• STM32 ADC详细篇(基于HAL库)


    一、基础认识

    ADC就是模数转换,即将模拟量转换为数字量

    l  分辨率,读出的数据的长度,如8位就是最大值为255的意思,即范围[0,255],12位就是最大值为4096,即范围[0,4096]

    l  通道,ADC输入引脚,通常一个ADC控制器控制多个通道,如果需要多通道的话,就得进行每个通道扫描了。

    l  ADC DMA功能,DMA是内存到内存或内存到存储的直接映射,数据不用经过单片机处理器而直接由硬件进行数据的传递。方便直接将读取的ADC值放到内存变量中。

    ADC芯片通常有正参考电压和负参考电压,通常正参考电压连接到VCC,负参考电压连接到GND

    在STM32中ADC还可以用于采集芯片的温度、RTC供电电压

    一般来说,采样时间越长,结果越准确,采样时间要更具ADC的时钟周期和ADC通道设置的采样周期计算,如STM32F103C8T6配置的ADC时钟周期为12MHZ,采样周期配置的是239.5 Cycles。

    ADC的转换方式:

    l  单次转换,一次只转换一个通道

    l  连续转换,转换完成一个通道后立即自动执行下一个通道的转换

    l  扫描模式,开启一次后,自动的连续读取多个通道

    ADC的三种工作方式:

    l  阻塞模式(查询模式)

    l  中断模式

    l  DMA模式

    二、cubemx基础配置

    使用外部晶振

    使用SWD调试

    时钟配置

    ADC时钟12MHZ,采样周期

    三、 单个通道,查询阻塞模式

    缺点:占用CPU的使用率

    流程:

    1. 启动ADC
    2. 等待EOC标志位
    3. 读取寄存器数据

    选择引脚,选择未ADC1的通道0和设置为模拟通道

    需要配置的功能,看门狗应该是可以设置上限下限的值,以产生中断报警。

     独立模式,不可选

    Data Alignment : 对齐模式,可选左对齐和右对齐

    Conversion Mode:扫描转换模式是否开启

    Continuous Conversion Mode:连续转换模式是否开启

    Discontinuous Conversion Mode:不连续转换模式 是否开启

    Enable Regular Conversions:是否使能转换

    Number Of Conversion:转换的通道数

    External Trigger Conversion Source:触发开始转换事件选择:

    可选由软件或定时器触发采集

    Rank 编号1,如果有多个通道的话就有多个Rank,每个Rank有如下参数配置:

    Channel:所选择的通道

    Sampling Time:采用周期,一个周期的时间要看ADC的时钟,如当前时钟图里设置的是12MHZ。这个时间设置越长采样越准确,但也相对要占用更长的采样时间。但不管再长,这采集都是微秒级别的。

    转换函数

    uint16_t ADC_Value=0;
    uint16_t dong_get_adc(){
        //开启ADC1
      HAL_ADC_Start(&hadc1);
        //等待ADC转换完成,超时为100ms
        HAL_ADC_PollForConversion(&hadc1,100);
        //判断ADC是否转换成功
        if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){
             //读取值
           return HAL_ADC_GetValue(&hadc1);
        }
        return 0;
    }

    调用

    ADC_Value=dong_get_adc();

    转换的值为0-4096,对应0-3.3V

    四、 三通道,查询阻塞模式

    选择引脚

    独立模式

    数据右读取,如果是多通道,则必须开启扫描模式(scan conversion mode)和不连续采集模式,最后一个1表示每个通道为一组

    设置为3个通道

    采用软件触发方式启动采集

    3个通道各自的参数设置

    转换函数

    uint16_t ADC_Value[3]={0};
    
    uint16_t dong_get_adc(){
        //开启ADC1
      HAL_ADC_Start(&hadc1);
        //等待ADC转换完成,超时为100ms
        HAL_ADC_PollForConversion(&hadc1,100);
        //判断ADC是否转换成功
        if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){
             //读取值
           return HAL_ADC_GetValue(&hadc1);
        }
        return 0;
    }

    使用

    for(uint8_t i=0;i<3;i++){
        //分别存放通道1、2、3的ADC值
        ADC_Value[i]=dong_get_adc();
    }

    五、 ADC中断方式多通道采集

    这个可以正确读出数据,但是顺序是乱的,所以谨慎使用

    第一步:启动ADC,使能中断

    第二步:等待中断触发

    第三步:在中断中读取寄存器数据

    引脚设置

    使能了连续转换

    开启中断

    把优先级设置低一点

    两个函数

    #define ADC_MAX_NUM 3*5 //3组ADC,每组最多存储5个值
    uint16_t ADC_Values[ADC_MAX_NUM]={0};
    uint16_t adc_value_flg=0;
    
    //启动函数,需要在main中调用一次
    void dong_start_adc(){
        //开启ADC1,使能中断
      HAL_ADC_Start_IT(&hadc1);
    }
    
    
    //ADC转换完成自动调用函数
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
        
         //获取值并存储
       ADC_Values[adc_value_flg++]=HAL_ADC_GetValue(hadc);
    
         if(adc_value_flg==ADC_MAX_NUM)
         {
             adc_value_flg=0;//清零下标
         }
         
    
    }

    六、ADC DMA方式多通道采集

    步骤:

    l  启动ADC

    l  配置DMA缓冲区

    l  读取缓冲区数据

    引脚选择

    基础配置

    开启连续转换模式

    关闭中断

    DMA配置

    mode:模式

    Normal:正常模式,当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次

    Circular: 循环模式,传输完成后又重新开始继续传输,不断循环永不停止

    data width:数据宽度

    byte:字节,通用8位,与u8相同

    word:字长,与硬件的位数相同,STM32是32位,所以对应是u32

    Half Word:半个字长,所以对应是u16

    Memory打钩表示存储ADC值的内存地址(数组)会自增

    代码也很简单,只要在main中调用一次启动函数即可

    #define ADC_MAX_NUM 3*5 //3组ADC,每组最多存储5个值
    
    uint16_t ADC_Values[ADC_MAX_NUM]={0};
    
    //启动函数,需要在main中调用一次
    void dong_start_adc(){
        
        //启动DMA
      HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Values,ADC_MAX_NUM);
        
    }

    测试发现,数据还是很稳的

    本人视频号:https://space.bilibili.com/162091292

  • 相关阅读:
    打击目标
    面试中的坑,你能爬出来几个?
    [linux] 小问题:管道符,换行问题等;[nginx]启动,重启,关闭命令;以及升级nginx切换命令
    xshell下使用vim的编辑一个文件Ctrl+S和Ctrl+Q
    [PHP] 调用微博API 发微博OAuth2.0
    [YII2] 视图层过滤客户恶意代码
    [YII2] 增删改查2
    [YII2] 增删改查
    [YII2] 自带分页调整
    [JS] 自己弄得个倒计时
  • 原文地址:https://www.cnblogs.com/dongxiaodong/p/14355843.html
Copyright © 2020-2023  润新知