前提:我用的芯片是STM32L系列,可能對其它STM32系列不完全適用,僅供參考!
一、問題描述
我在使用DMA方式讀取單ADC單通道采集的數據時,發現只能正確的采集一次數據,后來的就一直與第一次的相同。
配置DMA時,用於保存轉換數據的16位變量的地址和ADC_DR寄存器的地址都沒問題,DMA模式是DMA_Mode_Circular(循環模式),存儲器地址自增也關閉了,一切我能查到的都配置好了,但是還是不行。
二、發現問題
按理說配置出問題應該先去查手冊,但是無奈手冊只有英文,我在網上找不到解決方案就只能硬着頭皮看手冊了,最后把STM32L151xx的參考手冊ADC章節關於DMA的部分給翻譯了一遍,才找到了問題的解決方案。
手冊原文(P286):
翻譯過來大體意思:
所以問題就出來,因為我只需要將每一個AD轉換的值保存在一個16位的變量中,所以將DMA_BufferSize=1,這就導致我傳輸一次就結束了,而ADC_CR2的DDS位也沒配置,默認是0,即傳輸完一次后就不會在接受新的DMA請求了。
三、解決問題
了解了原因所在后,解決方法就很簡單了,你可以直接在ADC初始化的直接給ADC_CR2的DDS位置1,當然我也在標准庫中找到了一個函數:
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
其實內部也是對DDS位操作的,效果是相同的。
void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState) { /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE) { /* Enable the selected ADC DMA request after last transfer */ ADCx->CR2 |= ADC_CR2_DDS; } else { /* Disable the selected ADC DMA request after last transfer */ ADCx->CR2 &= (uint32_t)~ADC_CR2_DDS; } }