生活随笔
收集整理的這篇文章主要介紹了
STM32F030 ADC1的DMA采样问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
搞了1天一直ADC沒有出來,發現采處理的值一直是固定值..
去21IC求助貼.[STM32F0] STM32F030 ADC1采樣問題請教
等了好久都沒有人回復,但有人提醒我說需要等待DMA的數據完成.
后面對比了別人的代碼,
/* ADC DMA request in circular mode */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
別人有這句代碼,于是我加上這個話,則能夠正常采樣到數據了,
所以,必須得添加,否則無法獲取到采樣值.
接著又發現DMA傳輸到指定的數組數據順序錯亂了.....
類似別人的求助貼:[STM32F0] STM32F030 多通道ADC DMA讀取問題
后面解決方式,按照最后帖子的方式解決的
? ? ? ? " F0的ADC在使用之前需要校準。這個7位的校準值也是放在ADC_DR中的,它也會觸發DMA請求。可以參照F0的ADC-DMA例程,先做ADC校準、然后再設置DMA,再使能ADC的DMA。"
直接插入代碼,正確的初始化代碼:
[cpp] view plaincopy
typedef?enum??{??????ADC_PORTA0?=?ADC_Channel_0,??????????ADC_PORTA1?=?ADC_Channel_1,??????ADC_PORTA2?=?ADC_Channel_2,??????ADC_PORTA3?=?ADC_Channel_3,??????ADC_PORTA4?=?ADC_Channel_4,??????ADC_PORTA5?=?ADC_Channel_5,??????ADC_PORTA6?=?ADC_Channel_6,??????ADC_PORTA7?=?ADC_Channel_7,??????ADC_PORTA8?=?ADC_Channel_8,??????ADC_PORTA9?=?ADC_Channel_9,??????ADC_PORTA10?=?ADC_Channel_10,??????ADC_PORTA11?=?ADC_Channel_11,??????ADC_PORTA12?=?ADC_Channel_12,??????ADC_PORTA13?=?ADC_Channel_13,??????ADC_PORTA14?=?ADC_Channel_14,??????ADC_PORTA15?=?ADC_Channel_15,??}AD_PORT;????typedef?enum???{??????KEY_LINE_1,??????KEY_LINE_2,??????ADC_KEY_LINE_MAX?=?KEY_LINE_2,??????BATTERY_AD,??????ADC_NUM_CNT,??????}ADC_NUM;??????volatile?u16?g_uADC_ConVal[ADC_NUM_CNT]?=?{0};????????????u32?const??g_uADNum[]=??{???????????????ADC_PORTA9,????????ADC_PORTA8,????????ADC_PORTA2,????????};??????void?Adc_Init(void)??{??????ADC_DeInit(ADC1);???????????????RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,?ENABLE);????????RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,?ENABLE);??????????????RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,?ENABLE);????????????RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);????????RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);??????????????GPIO_InitTypeDef????GPIO_InitStruct;??????GPIO_StructInit(&GPIO_InitStruct);??????GPIO_InitStruct.GPIO_Mode?=?GPIO_Mode_AN;??????GPIO_InitStruct.GPIO_Pin?=??AD_KEY1_PIN;??????GPIO_Init(AD_KEY1_PORT,&GPIO_InitStruct);?????????????????????GPIO_InitStruct.GPIO_Pin?=??AD_KEY2_PIN;??????GPIO_Init(AD_KEY2_PORT,&GPIO_InitStruct);?????????????????????GPIO_InitStruct.GPIO_Pin?=??BATTERY_AD_PIN;??????GPIO_Init(BATTERY_AD_PORT,&GPIO_InitStruct);;?????????????????????????ADC_InitTypeDef?ADC_InitStructure;??????DMA_InitTypeDef?DMA_InitStructure;??????DMA_DeInit(DMA1_Channel1);??????DMA_InitStructure.DMA_PeripheralBaseAddr?=?(u32)&(ADC1->DR);???????????????????DMA_InitStructure.DMA_MemoryBaseAddr?=?(u32)g_uADC_ConVal;????????????DMA_InitStructure.DMA_DIR?=?DMA_DIR_PeripheralSRC;????????????????DMA_InitStructure.DMA_BufferSize?=?ADC_NUM_CNT;???????????DMA_InitStructure.DMA_PeripheralInc?=?DMA_PeripheralInc_Disable;??????????DMA_InitStructure.DMA_MemoryInc?=?DMA_MemoryInc_Enable;???????????????DMA_InitStructure.DMA_PeripheralDataSize?=?DMA_PeripheralDataSize_HalfWord;???????????DMA_InitStructure.DMA_MemoryDataSize?=?DMA_MemoryDataSize_HalfWord;???????????????DMA_InitStructure.DMA_Mode?=?DMA_Mode_Circular;???????????????????????????DMA_InitStructure.DMA_Priority?=?DMA_Priority_High;???????????????????????DMA_InitStructure.DMA_M2M?=?DMA_M2M_Disable;??????DMA_Init(DMA1_Channel1,&DMA_InitStructure);??????????????ADC_DMARequestModeConfig(ADC1,?ADC_DMAMode_Circular);???????????????????????????ADC_StructInit(&ADC_InitStructure);??????ADC_InitStructure.ADC_Resolution?=?ADC_Resolution_12b;??????ADC_InitStructure.ADC_ContinuousConvMode?=?ENABLE;????????????????????????ADC_InitStructure.ADC_ExternalTrigConv?=?ADC_ExternalTrigConvEdge_None;???????????????ADC_InitStructure.ADC_DataAlign?=?ADC_DataAlign_Left;?????????????????????????ADC_InitStructure.ADC_ScanDirection?=?ADC_ScanDirection_Backward;??????ADC_Init(ADC1,?&ADC_InitStructure);?????????for(u8?uCnt?=?0;uCnt?<?ADC_NUM_CNT;uCnt++)??????{?????????????????????ADC_ChannelConfig(ADC1,?g_uADNum[uCnt]?,?ADC_SampleTime_55_5Cycles);??????????}??????????????????????????????????????????????????ADC_GetCalibrationFactor(ADC1);???????????????????????????????????DMA_Cmd(DMA1_Channel1,ENABLE);??????????????????ADC_DMACmd(ADC1,?ENABLE);??????????ADC_Cmd(ADC1,ENABLE);?????????????????????????????????????????????????????????????????????????while(!ADC_GetFlagStatus(ADC1,?ADC_FLAG_ADEN));?????????<span?style="white-space:pre">????</span>??????????ADC_StartOfConversion(ADC1);??????????????????????????}??
另外補充,ADC_ScanDirection_Upward及ADC_ScanDirection_Backward的簡要說明。假設ADC1有18個通道,1,2....18
ADC_ScanDirection_Upward表示從1~18開始掃描
ADC_ScanDirection_Backward表示從18~1方向掃描
這樣就決定了,用戶指定的內存數組里面存值的順序.
像上面的代碼,則對應關系為g_uADC_ConVal[0]--->AIN9 ?g_uADC_ConVal[1]--->AIN8?g_uADC_ConVal[2]-->AIN2
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的STM32F030 ADC1的DMA采样问题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。