STM32F030 ADC1的DMA采样问题
2014-11-29 01:21
1431 查看
搞了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。"
直接插入代码,正确的初始化代码:
另外补充,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
来自:http://blog.csdn.net/lan120576664
去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。"
直接插入代码,正确的初始化代码:
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的总数 }ADC_NUM; volatile u16 g_uADC_ConVal[ADC_NUM_CNT] = {0}; // ADC转换值 u32 const g_uADNum[]= { //KEYPORTA1, ADC_PORTA9, ADC_PORTA8, ADC_PORTA2, //KEYPORTA0, }; void Adc_Init(void) { ADC_DeInit(ADC1); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); //打开DMA1的时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //打开ADC1的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4); //初始化IO口 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); // 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_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR); //定义DMA外设基地址,即为存放转换结果的寄存器 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)g_uADC_ConVal; //定义内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //定义AD外设作为数据传输的来源 DMA_InitStructure.DMA_BufferSize = ADC_NUM_CNT; //指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设定寄存器地址固定 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到三个内存空间中 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //设定外设数据宽度 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //设定内存的的宽度 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //设定DMA工作再循环缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //设定DMA选定的通道软件优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1,&DMA_InitStructure); /* ADC DMA request in circular mode */ ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); //必须得添加,否则无法获取到采样值 ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //设定AD转化在连续模式 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++) { /* Convert the ADC1 with 55.5 Cycles as sampling time */ ADC_ChannelConfig(ADC1, g_uADNum[uCnt] , ADC_SampleTime_55_5Cycles); //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 } //ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_55_5Cycles); //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 //ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_55_5Cycles); //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 //ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_55_5Cycles); //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 //ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); /* ADC Calibration */ ADC_GetCalibrationFactor(ADC1); //校准ADC DMA_Cmd(DMA1_Channel1,ENABLE); /* Enable ADC_DMA */ ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1,ENABLE); //使能指定的ADC1 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); <span style="white-space:pre"> </span>//等待ADC准备好 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
来自:http://blog.csdn.net/lan120576664
相关文章推荐
- STM32F030 ADC1的DMA采样问题
- STM32F030 ADC1的DMA采样问题
- STM8L051之ADC+DMA两通道数据采样错位问题
- 记STM32F030多通道ADC DMA读取乱序问题
- STM32F0系列用timer控制ADC采样,然后DMA传输到Memory或者DAC
- STM32 多通道ADC采样,采用Timer1进行采样率控制,利用DMA进行传输
- STM32F407 ADC DMA 采样实验
- 关于STM32F0系列多路ADC单独采样数据相同问题的处理
- EFM32片内外设--ADC之多通道采样+Timer+PRS触发+DMA
- STM32 ADC结合DMA数据采样与软件滤波处理
- stm32 adc dma多通道采样 数据错位 的解决方法
- stm32 双adc 采集问题 dma数据有一个没有 adc2为0
- STM32F407 单通道ADC采样,DMA传输
- STM32F0 定时器触发ADC,多通道采样、DMA传输数据的配置
- STM32 ADC结合DMA数据采样与软件滤波处理
- STM32F4 ADC DMA 问题
- 使用28377S进行ADC采样时配置错误导致波形畸变问题
- STM32F1xx 多路ADC 使用DMA转换结果顺序错乱问题
- STM32 多通道ADC采样,采用Timer1进行采样率控制,利用DMA进行传输
- STM32F407IG多通道ADC-DMA采样