历史上的今天
返回首页

历史上的今天

今天是:2025年04月15日(星期二)

正在发生

2018年04月15日 | STM32F030 ADC1的DMA采样问题

2018-04-15 来源:eefocus

搞了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。"


直接插入代码,正确的初始化代码:

  1. typedef enum  

  2. {  

  3.     ADC_PORTA0 = ADC_Channel_0,      

  4.     ADC_PORTA1 = ADC_Channel_1,  

  5.     ADC_PORTA2 = ADC_Channel_2,  

  6.     ADC_PORTA3 = ADC_Channel_3,  

  7.     ADC_PORTA4 = ADC_Channel_4,  

  8.     ADC_PORTA5 = ADC_Channel_5,  

  9.     ADC_PORTA6 = ADC_Channel_6,  

  10.     ADC_PORTA7 = ADC_Channel_7,  

  11.     ADC_PORTA8 = ADC_Channel_8,  

  12.     ADC_PORTA9 = ADC_Channel_9,  

  13.     ADC_PORTA10 = ADC_Channel_10,  

  14.     ADC_PORTA11 = ADC_Channel_11,  

  15.     ADC_PORTA12 = ADC_Channel_12,  

  16.     ADC_PORTA13 = ADC_Channel_13,  

  17.     ADC_PORTA14 = ADC_Channel_14,  

  18.     ADC_PORTA15 = ADC_Channel_15,  

  19. }AD_PORT;  

  20.   

  21. typedef enum   

  22. {  

  23.     KEY_LINE_1,  

  24.     KEY_LINE_2,  

  25.     ADC_KEY_LINE_MAX = KEY_LINE_2,  

  26.     BATTERY_AD,  

  27.     ADC_NUM_CNT,    //ADC的总数  

  28. }ADC_NUM;  

  29.   

  30.   

  31. volatile u16 g_uADC_ConVal[ADC_NUM_CNT] = {0};      // ADC转换值  

  32.   

  33.   

  34. u32 const  g_uADNum[]=  

  35. {     

  36.     //KEYPORTA1,   

  37.     ADC_PORTA9,    

  38.     ADC_PORTA8,    

  39.     ADC_PORTA2,  

  40.     //KEYPORTA0,  

  41. };  

  42.   

  43.   

  44. void Adc_Init(void)  

  45. {  

  46.     ADC_DeInit(ADC1);     

  47.       

  48.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  

  49.   

  50.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  

  51.   

  52.     //打开DMA1的时钟  

  53.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  

  54.     //打开ADC1的时钟  

  55.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);  

  56.   

  57.     RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);  

  58.   

  59.     //初始化IO口  

  60.     GPIO_InitTypeDef    GPIO_InitStruct;  

  61.     GPIO_StructInit(&GPIO_InitStruct);  

  62.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;  

  63.     GPIO_InitStruct.GPIO_Pin =  AD_KEY1_PIN;  

  64.     GPIO_Init(AD_KEY1_PORT,&GPIO_InitStruct);               // KEY1  

  65.     GPIO_InitStruct.GPIO_Pin =  AD_KEY2_PIN;  

  66.     GPIO_Init(AD_KEY2_PORT,&GPIO_InitStruct);               // KEY2  

  67.     GPIO_InitStruct.GPIO_Pin =  BATTERY_AD_PIN;  

  68.     GPIO_Init(BATTERY_AD_PORT,&GPIO_InitStruct);;           // 电池电源采样  

  69.   

  70.     //配置ADC1的DMA模式  

  71.     ADC_InitTypeDef ADC_InitStructure;  

  72.     DMA_InitTypeDef DMA_InitStructure;  

  73.     DMA_DeInit(DMA1_Channel1);  

  74.     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR);             //定义DMA外设基地址,即为存放转换结果的寄存器  

  75.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)g_uADC_ConVal;      //定义内存基地址  

  76.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;          //定义AD外设作为数据传输的来源  

  77.     DMA_InitStructure.DMA_BufferSize = ADC_NUM_CNT;     //指定DMA通道的DMA缓存的大小,即需要开辟几个内存空间,本实验有两个转换通道,所以开辟两个  

  78.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //设定寄存器地址固定  

  79.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         //设定内存地址递加,即每次DMA都是将该外设寄存器中的值传到三个内存空间中  

  80.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;     //设定外设数据宽度  

  81.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         //设定内存的的宽度  

  82.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                     //设定DMA工作再循环缓存模式  

  83.     DMA_InitStructure.DMA_Priority = DMA_Priority_High;                 //设定DMA选定的通道软件优先级  

  84.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  

  85.     DMA_Init(DMA1_Channel1,&DMA_InitStructure);  

  86.   

  87.     /* ADC DMA request in circular mode */  

  88.     ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);                   //必须得添加,否则无法获取到采样值  

  89.   

  90.     ADC_StructInit(&ADC_InitStructure);  

  91.     ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;  

  92.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                  //设定AD转化在连续模式  

  93.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;         //不使用外部促发转换  

  94.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;                   //采集的数据在寄存器中以左对齐的方式存放  

  95.     ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;  

  96.     ADC_Init(ADC1, &ADC_InitStructure);   

  97.   

  98.     for(u8 uCnt = 0;uCnt < ADC_NUM_CNT;uCnt++)  

  99.     {  

  100.         /* Convert the ADC1  with 55.5 Cycles as sampling time */   

  101.         ADC_ChannelConfig(ADC1, g_uADNum[uCnt] , ADC_SampleTime_55_5Cycles);    //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间  

  102.     }  

  103.       

  104.     //ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_55_5Cycles);   //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间  

  105.     //ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_55_5Cycles);   //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间  

  106.     //ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_55_5Cycles);   //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间  

  107.     //ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);   

  108.   

  109.       

  110.     /* ADC Calibration */  

  111.     ADC_GetCalibrationFactor(ADC1);                     //校准ADC  

  112.   

  113.       

  114.     DMA_Cmd(DMA1_Channel1,ENABLE);  

  115.       

  116.     /* Enable ADC_DMA */  

  117.     ADC_DMACmd(ADC1, ENABLE);    

  118.   

  119.     ADC_Cmd(ADC1,ENABLE);                                                                   //使能指定的ADC1  

  120.     while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));             //等待ADC准备好  

  121.   

  122.   

  123.     ADC_StartOfConversion(ADC1);                        //启动转换  

  124. }  



另外补充,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


推荐阅读

史海拾趣

GE Solid State公司的发展小趣事
选择一个合适的光敏元件(如光敏电阻或光敏二极管)作为感光元件,以及必要的信号处理元件(如运算放大器、比较器等)和声音输出元件(如扬声器)。
方舟(ARKLED)公司的发展小趣事

方舟公司高度重视产品品质管理,从原材料采购到生产加工,再到成品检验,每一个环节都严格把关。公司引进了先进的生产设备和检测仪器,建立了完善的质量管理体系。通过ISO9001质量管理体系认证,方舟公司的产品质量得到了有效保障,赢得了客户的信赖和支持。

BOCA公司的发展小趣事

随着技术的不断进步,BOCA公司意识到单一产品线的局限性。为了拓宽市场,公司决定进军消费电子领域。BOCA通过与知名品牌合作,推出了一系列搭载其先进技术的电子产品,如智能手机、平板电脑等。这些产品凭借其卓越的性能和独特的设计,迅速在市场上获得了良好的口碑,为BOCA带来了丰厚的利润。

B.B. Battery公司的发展小趣事

面对日益严峻的环境问题,B.B. Battery公司积极响应国家绿色发展的号召,致力于推动绿色生产。他们引进环保型生产设备和技术,减少生产过程中的污染物排放。同时,公司还研发出多款环保型电池产品,为客户提供更加绿色、高效的能源解决方案。这些举措不仅提升了公司的社会责任感,也为公司的可持续发展奠定了坚实基础。

HI Microwave Technology Limited公司的发展小趣事

随着技术的不断积累和市场需求的日益增长,HI Microwave不断加大研发投入,成功开发出了一系列高性能的微波组件产品,包括隔离器、循环器、开关、滤波器、功率分配器/合成器、定向耦合器、天线、混频器、压控振荡器(VCOs)和射频放大器等。这些产品广泛应用于无线电信和光纤通信行业,满足了客户多样化的需求。同时,公司还积极与国内外知名企业和科研机构合作,共同推动微波通信技术的发展。

ATC [American Technical Ceramics]公司的发展小趣事

在电子行业的发展历程中,技术突破一直是推动公司成长和市场扩张的关键因素。假设ATC在某一时期成功研发出了一种新型的陶瓷材料,这种材料在耐高温、抗腐蚀等方面具有显著优势,因此被广泛应用于半导体制造和电子设备领域。这一技术突破使得ATC的产品在市场上获得了极高的认可,公司也因此实现了快速的收入增长和市场占有率的提升。

问答坊 | AI 解惑

USB分析工具 急

我现在时在CE上开发USB驱动。。但是我掉用USBd函数后没有什么反映读不到数。。也不知道数是否发出去了。。有没有什么USB在CE的的小工具能帮我看看。。我的数据是否发出去了。。。。请大侠们帮忙介绍下。。谢谢。。。…

查看全部问答>

WriteFile一直失败

我用串口发AT命令给GSM模块,端口可以打开,但是就是WriteFile失败,ReadFile没有失败 void CCeSerial::Senddata(BYTE *psendbuf, DWORD length) {         DWORD dwactlen;         if (m_hComm == ...…

查看全部问答>

WDT的问题急!!!

我用看门狗中断来采集A/D,芯片是F1232…

查看全部问答>

(刚接触AVR)关于自制USBASP下载线的问题,麻烦各位大大!

我用已有的ATMEGA8,弄出了下载线,能对atmega128烧写程序, 我想弄多几条这种下载线, 在网上已经找好下载的程序,但不知如何对ATMEGA8烧写程序, 能用这个下载线烧写吗?如何连接ATMEGA8?麻烦各位大大帮忙! 感谢各位!…

查看全部问答>

LPC IAP应用开发与仿真

随着技术的不断发展,IAP不在陌生,很多产品上都实现了IAP的应用。特别是ARM芯片上,由于其足够的Flash和内存空间,以及简单方便的IAP开发,使得用其开发的产品上使用IAP成为必然。       IAP的方式有很多,比较流行的有UART ...…

查看全部问答>

本人初学STM32遇到一些问题,希望有人给予帮助

本人初学STM32,先用keil4编写程序,把库和代码都加入工程里了,主函数也有了,可一运行出现下列错误,我看不懂怎么改啊!!求哪位大侠给看下吧。     compiling main.c...D:\\Keil\\ARM\\INC\\ST\\STM32F10x\\stm32f10x_type.h(25): ...…

查看全部问答>

怎么选好驱动电路

谁能告诉我,5-10个mos管并联使用时使用什麽样的驱动电路比较合适?为什么?…

查看全部问答>

【程序设计】聊聊C语言 之 数据类型引发的程序异常

       我们在使用C语言进行程序设计时常常定义很多变量。对于每一个变量来说都有其特定的变量类型,比如“整型”就是我们使用较为频繁的一种变量类型。        对于像“整型”这种数据类型它更多表达的 ...…

查看全部问答>

ise14.6 license 支持全系列xilinx 7系列

vivado2013.2 license 支持全系列xilinx 7系列 ise14.6 license 支持全系列xilinx 7系列 推荐一个知名公司资深fpga工程师share的网站 www.rocetech.com KINTEX7,FPGA采集卡,pcieX8采集卡,pcie采集卡,万兆光网卡,rocetech 技术工程师电话1( ...…

查看全部问答>