当前位置 : 主页 > 网络编程 > 其它编程 >

STM32F030ADC1的DMA采样问题

来源:互联网 收集:自由互联 发布时间:2023-07-02
搞了1天一直ADC没有出来,发现采处理的一直是固定..去21IC求助贴.[STM32F0]STM32F030ADC1采样问题请教等了好久都没有人回复,但有人提醒我说 搞了1天一直ADC没有出来,发现采处理的值一直是
搞了1天一直ADC没有出来,发现采处理的一直是固定..去21IC求助贴.[STM32F0]STM32F030ADC1采样问题请教等了好久都没有人回复,但有人提醒我说 搞了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 plain copy 在CODE上查看代码片派生到我的代码片
  • 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的总数
  • }ADC_NUM;
  • volatileu16g_uADC_ConVal[ADC_NUM_CNT]={0};//ADC转换值
  • 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);
  • //打开DMA1的时钟
  • RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  • //打开ADC1的时钟
  • RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  • RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
  • //初始化IO口
  • GPIO_InitTypeDefGPIO_InitStruct;
  • GPIO_StructInit(
  • GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AN;
  • GPIO_InitStruct.GPIO_Pin=AD_KEY1_PIN;
  • GPIO_Init(AD_KEY1_PORT,//KEY1
  • GPIO_InitStruct.GPIO_Pin=AD_KEY2_PIN;
  • GPIO_Init(AD_KEY2_PORT,//KEY2
  • GPIO_InitStruct.GPIO_Pin=BATTERY_AD_PIN;
  • GPIO_Init(BATTERY_AD_PORT,;//电池电源采样
  • //配置ADC1的DMA模式
  • ADC_InitTypeDefADC_InitStructure;
  • DMA_InitTypeDefDMA_InitStructure;
  • DMA_DeInit(DMA1_Channel1);
  • DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)//定义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,
  • /*ADCDMArequestincircularmode*/
  • ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular);//必须得添加,否则无法获取到采样值
  • ADC_StructInit(
  • 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,
  • for(u8uCnt=0;uCnt
  • {
  • /*ConverttheADC1with55.5Cyclesassamplingtime*/
  • 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);
  • /*ADCCalibration*/
  • ADC_GetCalibrationFactor(ADC1);//校准ADC
  • DMA_Cmd(DMA1_Channel1,ENABLE);
  • /*EnableADC_DMA*/
  • ADC_DMACmd(ADC1,ENABLE);
  • ADC_Cmd(ADC1,ENABLE);//使能指定的ADC1
  • while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_ADEN));"white-space:pre">//等待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]--->AIN8g_uADC_ConVal[2]-->AIN2

    【文章转自日本多IP服务器 http://www.558idc.com/japzq.html提供,感恩】
    上一篇:以正确姿势理解区块链技术
    下一篇:没有了
    网友评论