浅谈STM32 模数转换器 (ADC)(下)

模拟技术

2295人已加入

描述

温度传感器和VRENFINT通道框图

模数转换器

要使用传感器,请执行以下操作:

  1. 选择 ADC1_IN16 或 ADC1_IN18 输入通道。
  2. 选择一个采样时间,该采样时间要大于数据手册中所指定的最低采样时间。
  3. 在 ADC_CCR 寄存器中将 TSVREFE 位置 1,以便将温度传感器从掉电模式中唤醒。
  4. 通过将 SWSTART 位置 1(或通过外部触发)开始 ADC 转换
  5. 读取 ADC 数据寄存器中生成的 V SENSE 数据
  6. 使用以下公式计算温度:

温度(单位为 °C)= {(V SENSE — V 25 ) / Avg_Slope} + 25

其中:

— V 25 = 25 °C 时的 V SENSE 值

— Avg_Slope = 温度与 V SENSE 曲线的平均斜率(以 mV/°C 或 μV/°C 表示)

由于ADC寄存器的相关配置相对比较简单,这里直接附上测量温度相关的ADC初始化和中断程序:

void ADC_Init()
{
  u32 prigroup = 0;                          
  u32 priority = 0;        

  RCC->APB2ENR  |=  1<<8;    //开ADC1时钟        

  ADC->CCR  =  0;
  ADC->CCR  |=  1<<23;    //使能温度传感器和 V REFINT 通道
  ADC->CCR  |=  1<<16;    //ADCCLK=21mHZ

  ADC1->CR1  =  0;//分辨率12位

  ADC1->CR2  =  0;          //数据右对齐
  ADC1->CR2  |=  1<<10;    //通道只要转换结束,则将EOC置1,使能溢出检测

  ADC1->SMPR1  =0;          //通道16采样时间3T

  ADC1->SQR3  |=  16<<0;

  ADC1->CR1  |=  1<<5;          //使能EOC中断
  ADC1->SR  &=~  (1<<1);        //清中断标记33
  prigroup = NVIC_GetPriorityGrouping();        //得到优先级分组
  priority = NVIC_EncodePriority(prigroup,1,2);  //优先级编码
  NVIC_SetPriority(ADC_IRQn,priority);        //设置中断优先级
  NVIC_EnableIRQ(ADC_IRQn);                  //使能ADC中断

  ADC1->CR2  |=  1<<0;      //使能ADC
  Delay_us(3);
  ADC1->CR2  |=  1<<30;  //启动AD转换
}


u16 ADC1_Value={0};      //定义二维数组,按行存入三个通道的转换结束
u8 ADC1_OK = 0;


//中断处理函数
void ADC_IRQHandler()
{
  if(ADC1->SR  &  (1<<1))
  {      
    ADC1->SR  &=~  (1<<1);        //写0,请标记
    ADC1_Value = ADC1->DR;    //按行依次存入各通道的转换结果
    ADC1_OK  =  1;                //采集完成结束标记置1
  }
}

接着编写主函数测试

#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "stdio.h"
#include "ADC.h"


extern u8 ADC1_OK;
extern u16 ADC1_Value;


int main()
{
  float wendu = 0; 

  NVIC_SetPriorityGrouping(7-2);
  Usart1_Init(115200);
  ADC_Init();


  while(1)
  {
    if(ADC1_OK == 1)
    {
      ADC1->SR  &=~ (1<<1);      //清中断标记
      ADC1_OK = 0;
      wendu = 3.3*ADC1_Value/4095;        //求温度数字值对应的模拟电压值
      wendu = (wendu -0.76)*1000/2.5+25;    //计算温度值

      printf("温度AD值:%d\\r\\nwendu = %.lf°C\\r\\n",ADC1_Value,wendu);
      ADC1->CR2  |=  1<<0;        //再次开启ADC1
      Delay_us(3);
      ADC1->CR2  |=  1<<30;      //触发一次转换
    }
    Delay_ms(1000);
  }
}

从串口可以看到ADC读取的温度值,ADC温度测量成功。

模数转换器

对于电池电压或者其他外部模拟量的测量,配置方法与温度测量类似,这里不再赘述。如果想要让CPU更多地用于算法或者其他功能的处理,同样可以配置DMA进行数据传输。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分