STM32F030 ADC1的DMA采樣問(wèn)題
搞了1天一直ADC沒(méi)有出來(lái),發(fā)現(xiàn)采處理的值一直是固定值..
去21IC求助貼.[STM32F0] STM32F030 ADC1采樣問(wèn)題請(qǐng)教
等了好久都沒(méi)有人回復(fù),但有人提醒我說(shuō)需要等待DMA的數(shù)據(jù)完成.
后面對(duì)比了別人的代碼,
/* ADC DMA request in circular mode */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
別人有這句代碼,于是我加上這個(gè)話,則能夠正常采樣到數(shù)據(jù)了,
所以,必須得添加,否則無(wú)法獲取到采樣值.
接著又發(fā)現(xiàn)DMA傳輸?shù)街付ǖ臄?shù)組數(shù)據(jù)順序錯(cuò)亂了.....
類似別人的求助貼:[STM32F0] STM32F030 多通道ADC DMA讀取問(wèn)題
后面解決方式,按照最后帖子的方式解決的
" F0的ADC在使用之前需要校準(zhǔn)。這個(gè)7位的校準(zhǔn)值也是放在ADC_DR中的,它也會(huì)觸發(fā)DMA請(qǐng)求??梢詤⒄誇0的ADC-DMA例程,先做ADC校準(zhǔn)、然后再設(shè)置DMA,再使能ADC的DMA。"
直接插入代碼,正確的初始化代碼:
typedefenum
{
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;
typedefenum
{
KEY_LINE_1,
KEY_LINE_2,
ADC_KEY_LINE_MAX=KEY_LINE_2,
BATTERY_AD,
ADC_NUM_CNT,//ADC的總數(shù)
}ADC_NUM;
volatileu16g_uADC_ConVal[ADC_NUM_CNT]={0};//ADC轉(zhuǎn)換值
u32constg_uADNum[]=
{
//KEYPORTA1,
ADC_PORTA9,
ADC_PORTA8,
ADC_PORTA2,
//KEYPORTA0,
};
voidAdc_Init(void)
{
ADC_DeInit(ADC1);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
//打開(kāi)DMA1的時(shí)鐘
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
//打開(kāi)ADC1的時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
//初始化IO口
GPIO_InitTypeDefGPIO_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);//KEY1
GPIO_InitStruct.GPIO_Pin=AD_KEY2_PIN;
GPIO_Init(AD_KEY2_PORT,&GPIO_InitStruct);//KEY2
GPIO_InitStruct.GPIO_Pin=BATTERY_AD_PIN;
GPIO_Init(BATTERY_AD_PORT,&GPIO_InitStruct);;//電池電源采樣
//配置ADC1的DMA模式
ADC_InitTypeDefADC_InitStructure;
DMA_InitTypeDefDMA_InitStructure;
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&(ADC1->DR);//定義DMA外設(shè)基地址,即為存放轉(zhuǎn)換結(jié)果的寄存器
DMA_InitStructure.DMA_MemoryBaseAddr=(u32)g_uADC_ConVal;//定義內(nèi)存基地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//定義AD外設(shè)作為數(shù)據(jù)傳輸?shù)膩?lái)源
DMA_InitStructure.DMA_BufferSize=ADC_NUM_CNT;//指定DMA通道的DMA緩存的大小,即需要開(kāi)辟幾個(gè)內(nèi)存空間,本實(shí)驗(yàn)有兩個(gè)轉(zhuǎn)換通道,所以開(kāi)辟兩個(gè)
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//設(shè)定寄存器地址固定
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//設(shè)定內(nèi)存地址遞加,即每次DMA都是將該外設(shè)寄存器中的值傳到三個(gè)內(nèi)存空間中
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//設(shè)定外設(shè)數(shù)據(jù)寬度
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//設(shè)定內(nèi)存的的寬度
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//設(shè)定DMA工作再循環(huán)緩存模式
DMA_InitStructure.DMA_Priority=DMA_Priority_High;//設(shè)定DMA選定的通道軟件優(yōu)先級(jí)
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
/*ADCDMArequestincircularmode*/
ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular);//必須得添加,否則無(wú)法獲取到采樣值
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//設(shè)定AD轉(zhuǎn)化在連續(xù)模式
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConvEdge_None;//不使用外部促發(fā)轉(zhuǎn)換
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Left;//采集的數(shù)據(jù)在寄存器中以左對(duì)齊的方式存放
ADC_InitStructure.ADC_ScanDirection=ADC_ScanDirection_Backward;
ADC_Init(ADC1,&ADC_InitStructure);
for(u8uCnt=0;uCnt
{
/*ConverttheADC1with55.5Cyclesassamplingtime*/
ADC_ChannelConfig(ADC1,g_uADNum[uCnt],ADC_SampleTime_55_5Cycles);//設(shè)置指定ADC的規(guī)則組通道,設(shè)置它們的轉(zhuǎn)化順序和采樣時(shí)間
}
//ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_55_5Cycles); //設(shè)置指定ADC的規(guī)則組通道,設(shè)置它們的轉(zhuǎn)化順序和采樣時(shí)間