• STM32基于hal库的adc以DMA的多通道采样以及所遇问题解决


    目录

    准备

    配置

    步骤

     总结


     

    准备

    正点原子的STM32F103ZET6开发板(精英版)

    CUBEMX配置软件

    KEIL5

    配置

     右对齐就是正常的数据格式。左对齐除以16后得正常数据。(当输出非常大时考虑是否改了对齐方式,默认都是右对齐)

     扫描模式,连续转换模式使能。(多通道下扫描模式自动使能)

    采样周期 SamplingTime 越大越精确,越小则则会频繁触发DMA中断(在开启dma中断时,我试了在14M的adc时钟程序进不来while(因为频繁触发DMA中断)

    看数据手册,知道三个adc中(adc1,adc2,adc3只有adc1和adc3能用DMA通道。

     ADC的时钟不能超过14Mhz,

    配置外设到内存(cubeMX自动配置好了),外设adc地址是不变的,而DMA把数据存到存储器的地址是增长的。

    Circular循环模式连续搬运adc数据。

    在配置DMA时,因为ad的精度是12位,最大也就是4096,而DMA转储adc是一个通道接着一个通道去存储的,所以转储的时候dma搬运半字(stm32 32位为一个字,半字16位 最大位4096*16)就可以了,节省dma资源提升速度。然后在程序里用一个缓存为uint16_t去接受就不会有问题。

     __IO uint16_t adcbuf[100]={0};

     开启DMA

    HAL_ADC_Start_DMA(&hadc1,  (uint32_t*)&adcbuf,100);//

    不推荐的的一种配置,也不是不可以,接受数据缓存定义位32位

     

    正常情况下我们还是配置成半字长的

     

     

     而我走的一个坑点就adcbuf这个DMA转移数据的缓存数组定义成立uint32_t,(在dma半字转移下)结果就翻船。。。

    想着不应该啊,大类型接受小类型数据C是不会出问题的。

    1. int temp=0;
    2. for (int i=0 ;i < 100; ){
    3. temp=i;
    4. //adcreal[0]+= adcbuf[i++]*3.3/4096;
    5. //adcreal[1]+= adcbuf[i++]*3.3/4096;
    6. printf(" %d-Channel1:%d\r\n", temp,adcbuf[i++]);
    7. printf(" %d-Channel2:%d\r\n",temp ,adcbuf[i++]);
    8. }

    依次取两个通道的数据(i为偶数是通道1,i为奇数则是通道二),看串口打印结果(两个通道,一个接3.3v一个接5v电压)

     

     前50是3.3v电压采集,后50是接地采集结果,完全乱了。这种情况下把接受类型改成uint16_t就解决了。

    步骤

    定义接受缓存(定义成单字转移)

    1. __IO uint16_t adcbuf[100]={0};
    2. float adcreal[2]={0};

    开启接受 

       HAL_ADC_Start_DMA(&hadc1,  (uint32_t*)&adcbuf,100);//

    打印数据 (平均滤波)

    1. HAL_Delay(1000);
    2. adcreal[0]=0.0;
    3. adcreal[1]=0.0;
    4. for (int i=0 ;i < 100; ){
    5. adcreal[0]+= adcbuf[i++]*3.3/4096;
    6. adcreal[1]+= adcbuf[i++]*3.3/4096;
    7. }
    8. printf(" -Channel1:%1.3f\r\n",adcreal[0]/50);
    9. printf(" -Channel5:%1.3f\r\n",adcreal[1]/50);
    10. printf("\r\n");

     结果

     

     总结

    配置时单字dma转移,uint32_t类型定义缓存。

    配置时半字dma转移,uint16_t类型定义接受缓存。

     

  • 相关阅读:
    买条新内存给台式机扩容,没想到出现玄学花屏
    判断经纬度是否在某个城市内
    js input手机号正则限制11位数字
    11. 查询人数及其所占的百分比
    Docker-harbor私有仓库部署与管理
    计算属性,侦听属性,方法区别及例子
    crontab定时任务
    操作系统 面试题(二)
    微擎模块 柚子抽奖平台1.2.6 后台模块+前端小程序源码 增加发布抽奖图片自定义
    LeetCode 384. 打乱数组
  • 原文地址:https://blog.csdn.net/PHILICS7/article/details/125952060