GD32F330 | ADC實例 基於DMA方式


GD32F330 | ADC實例 基於DMA方式


 

  簡單記錄一下 ADC多通道轉換 DMA搬運 的使用,以 GD32F330G8U6 為例:

 

一、基礎知識

  12位  ADC 是一種采用逐次逼近方式的模擬數字轉換器。
  轉換模式:
    – 轉換單個通道,或者掃描一序列的通道;
    – 單次模式,每次觸發轉換一次選擇的輸入通道;
    – 連續模式,連續轉換所選擇的輸入通道;
    – 間斷模式;
    – 同步模式(適用於具有兩個或多個ADC的設備)。
  
   DMA(Direct Memory Access)— 直接存儲器存取,是單片機的一個外設,它的主要功能是用來搬數據,但是不需要占用 CPU,即在傳輸數據的時候,CPU 可以干其他的事情,好像是多線程一樣。數據傳輸支持從外設到存儲器或者存儲器到存儲器,這里的存儲器可以是 SRAM 或者是 FLASH。
 

二、軟件配置過程

  常規通道轉換 DMA 搬運:通過ADC轉換,在ADC 轉換完成后 觸發DMA 進行數據搬運。

1、開啟工作時鍾

// 1. 開啟時鍾
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_ADC);
rcu_periph_clock_enable(RCU_DMA);
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);

 

2、GPIO 初始化

  GPIO 用於 AD 轉換功能必須配置為模擬輸入模式

// 2. GPIO配置
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3 | GPIO_PIN_4);

   注:ADC 的通道與引腳的對應關系可查閱具體芯片的數據手冊 (Pin definitions 章節):

 

 

 

3、ADC 初始化

  配置 ADC 模式、對齊方式、轉換長度、采樣周期以及觸發方式等等
// 3. ADC配置
adc_deinit();
adc_special_function_config(ADC_SCAN_MODE, ENABLE);                     // 掃描模式
adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);               // 連續轉換

adc_resolution_config(ADC_RESOLUTION_12B);
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
adc_channel_length_config(ADC_REGULAR_CHANNEL, 2);
adc_regular_channel_config(0, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(1, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);

adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);  // 軟件觸發
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);                           // 觸發使能

adc_dma_mode_enable();  // 使能DMA接收

adc_enable();           // 使能ADC模塊
delay_1ms(0x03);        // ADC在使能之后需要進行短暫的延時,時間周期約為2毫秒左右,以保證ADC能正常啟動。
adc_calibration_enable();

 

 

4、DMA 初始化

  使用 DMA,最核心就是配置要傳輸的數據,包括數據從哪里來,要到哪里去,傳輸的數據的單位是什么,要傳多少數據,是一次傳輸還是循環傳輸等等。

  • 從哪里來到哪里去        --  DMA 傳輸數據的方向有三個:(1)從外設到存儲器  (2)從存儲器到外設 (3)從存儲器到存儲器
  • 要傳多少,單位是什么 --  要想數據傳輸正確,源和目標地址存儲的數據寬度一般會設置成一致
  • 什么時候傳輸完成        --  傳輸完成分兩種模式,是一次傳輸還是循環傳輸,一次傳輸很好理解,即是傳輸一次之后就停止,要想再傳輸的話,必須關斷 DMA 使能后再重新配置后才能繼續傳輸。循環傳輸則是一次傳輸完成之后又恢復第一次傳輸時的配置循環傳輸,不斷的重復。
// 4. DMA配置
dma_parameter_struct dma_data_parameter;

dma_deinit(DMA_CH0);
dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA);
dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_data_parameter.memory_addr = DstAddress;
dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_data_parameter.number = DataLength;
dma_data_parameter.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(DMA_CH0, &dma_data_parameter);
dma_circulation_enable(DMA_CH0);
dma_memory_to_memory_disable(DMA_CH0);
dma_channel_enable(DMA_CH0);

   注: DstAddress --  存儲器地址,一般設置為我們自定義存儲區的首地址。

 

 

5、觸發 ADC 轉換

  開啟 ADC 轉換,在ADC 轉換完成后 ADC 轉換結果 就會保存在 DMA配置的 DstAddress 地址里,在我們需要 最新的 ADC 轉換結果 時直接讀取即可。

adc_software_trigger_enable(ADC_REGULAR_CHANNEL);   // 開啟ADC轉換

 

 

三、ADC 使用注意事項

  1. ADC通道的采集引腳未配置為模擬輸入,GD32要求通道IO口必須配置為模擬輸入;
  2. ADC時鍾過高,ADC采樣時鍾高於ADC最高采樣時鍾獲取到的數據不具有參考意義,需要手動分頻到合適的ADC 要求的頻率;
  3. ADC采樣值偏小或不穩定,應該適當的降低ADC時鍾,加大采樣周期的值;
  4. ADC的查詢法在獲取ADC數值的時候,不允許重入,即不允許在同一時間調用ADC的數據讀取函數
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM