STM32快速入门(ADC数模转换)

打印 上一主题 下一主题

主题 656|帖子 656|积分 1968

STM32快速入门(ADC数模转换)

前言

ADC数模转换存在的意义就是将一些温度传感器、各自数据传感器产生的模仿信号转换成方便识别和盘算的数字信号。
导航

图24 通用定时器框图:

图片截取自STM32 F1XX中文参考手册。照旧以框图为中心,来叙述我对ADC的理解。
ACD实现细节

核心原理

所谓ADC转换目的是为了将连续变革的模仿量转酿成数字,方便程序的盘算。这里的模仿量不单单指代那些以正弦规律变革的波形,只要是连续变革的波形,我们都称它为模仿量。简朴来说,数模转化器就是按一定分辨率对连续变革的模仿信号进行切分,每一段都会给他进行数字编码,固然分辨越大,模仿信号被切分的越细,精度也会越准确。图片引用自知乎,如有侵权,可联系我将其删除,如图:

ADC转换器的实现是:起首对输入的模仿信号进行采样,由于数模转换的精度是确定的,以是会以精度来进行一个二分,每次取掷中的精度范围的中心数值,然后将数值通过DA转换,转换成模仿量,然后和采样的模仿量比较,判定巨细,再进行一次二分,终极确定采样的模仿量对应的数字编码是多少。这里帖一张简朴8位的ADC内部构造的原理图,图片引用自江协科技,如有侵权,联系我将其删除,如图2。

图24的中心部门

回到图24,框图左侧ADCx_INx就是各个GPIO端口也称为通道,模仿信号可以从这里输入,旁边的GPIO端口矩形框,内部就是一个硬件开关,STTM32中的ACD一次可以处理多个ADC通道的转换,通道的转换就靠硬件开关来选择。我们这里重要讲规则通道的转换。注入通道原理其实是一样的。规则通道有16路通道,而输出寄存器只有一个,以是在完成一次通道的转换,我们就应该快速讲输出寄存器的值读取走,不然就会覆盖,一般会配合DMA利用。中心的模仿至数字转换器的内部原理就是图2所示。ADCCLK就是给ADC转换器的驱动时钟,和图2的CLOCK引脚对应。
图24的上半部门

图2上部门有毗连到输出寄存器(包罗1个规则通道寄存器、4个注入通道寄存器)的各种标志位,这些标志位都有相应的寄存器,并且也能触发停止。模仿看门狗的作用在图中也描述的非常明了,就是给定一个检测范围,在范围中就会触发标志位或停止。
图24的下半部门

下半部门就是描绘数模转换触发的一些方式,这里是支持硬件触发的软件触发。硬件触发包罗主模式下定时器的TRGO输出、以及定时器的输出通道、外部停止的触发等。各种触发方式和图2的START引脚对应。
实现ADC转换的细节记载

1. 起首要区分:间断模式和扫描模式、单次转换和连续转换。
所谓间断模式,就是一次触发只转换部门通道。所谓扫描,就是一次触发将规则组(注入组)的全部待转换的通道都转换完。
所谓单次转换,就是将规则组转换完了,就停止转换。所谓连续转换,就是规则组(注入组)转换完了,就自动从头开始新一轮的转换。
间断模式和扫描模式通过配置ADC_CR1.SCAN[8]可以开启或者关闭扫描模式,规则组和注入组共用这一位。通过配置ADC_CR1.JDISCEN[12]、ADC_CR1.DISCEN[11]分别可以配置注入组或者规则组去启用或禁用间断模式。通过配置ADC_CR1.DISCNUM[15:13]可以配置间断模式下规则组一次触发事件转换的通道数目,这里只强调规则组!中文手册并没提到注入组,现在不确认规则组是否也受该位的影响!扫描模式下,只有末了一个条目转换完毕才会置位EOC。
具体利用连续转换照旧单次转换,由ADC_CR2.CONT[1]控制。
2. 关于看门狗的细节
规则组和注入组可以独立的开启模仿看门狗,分别利用ADC_CR1.AWDEN[23]、ADC_CR1.JAWDEN[22],通过ADC_CR1.AWDSGL[9]位可以实现扫描模式下让看门狗只监控一个特定通道,监督的通道号由ADC_CR1.AWDCH[4:0]位给出。
3. 模式选择和触发方式
本文只讲解独立模式的配置,由ADC_CR1.DUALMOD[19:16]可以配置是独立模式照旧双模式。规则组和注入组都可以独立配置触发方式。规则组通过ADC_CR2.EXTSEL[19:17]选择触发源。典型值是[111:软件触发SWSTART],还须要利用ADC_CR2.EXTTRIG[20]使能外部触发源。ADC_CR2.SWSTART[22]置位可激活软件触发,使规则组开始转换。
4. 规则组和通道的关系
STM32F103系列规则组可以有16个条目(entry)(标号从1开始,范围[1, 16]),通道一共有18个(标号从0开始,范围[0, 17])。
ADC1的模仿输入通道16和通道17在芯片内部门别连到了温度传感器和VREFINT。
ADC2的模仿输入通道16和通道17在芯片内部连到了VSS。
ADC3模仿输入通道9、14、15、16、17与Vss相连。
每个通道可以单独配置其采样时间。ADC_SMPRx(x=1、2)。通过配置ADC_SQRx(x=1、2、3)可以配置规则组每个条目指向哪个通道。此中ADC_SQR1.L[23:20]可设置规则组中有用条目的长度(也即通道数目)。
盗取江协科技的图片如下:

ADC转换的库函数实现

硬件接线图如下:


GPIO对应的ADC如下:

由表可知,我们须要配置的是ADC3
GPIO配置如下:

核心代码如下:
  1. void LunarADCInit(void) {
  2.         GPIO_InitTypeDef GPIOF8_Cfg;
  3.         ADC_InitTypeDef ADC3_Cfg;
  4.         // 先配置ADCCLK预分频器                12M HZ
  5.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  6.         // 打开ADC1时钟
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
  9.         GPIOF8_Cfg.GPIO_Mode = GPIO_Mode_AIN;
  10.         GPIOF8_Cfg.GPIO_Pin = GPIO_Pin_8;
  11.         GPIOF8_Cfg.GPIO_Speed = GPIO_Speed_50MHz;
  12.         GPIO_Init(GPIOF, &GPIOF8_Cfg);
  13.         ADC3_Cfg.ADC_ContinuousConvMode = ENABLE;                                        // 连续转换使能
  14.         ADC3_Cfg.ADC_DataAlign = ADC_DataAlign_Left;
  15.         ADC3_Cfg.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        // 软件触发
  16.         ADC3_Cfg.ADC_Mode = ADC_Mode_Independent;                                        // 独立模式
  17.         ADC3_Cfg.ADC_NbrOfChannel = 1;                                                                // 只转换一个序列
  18.         ADC3_Cfg.ADC_ScanConvMode = ENABLE;                                                        // 使用扫描模式
  19.         ADC_Init(ADC3, &ADC3_Cfg);
  20.         ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 1, ADC_SampleTime_7Cycles5);        // 配置规则序列寄存器以及通道采样时间
  21.         ADC_Cmd(ADC3, ENABLE);
  22.         ADC_ResetCalibration(ADC3);
  23.         while (ADC_GetResetCalibrationStatus(ADC3) == SET);        // 硬件置0
  24.         ADC_StartCalibration(ADC3);
  25.         while (ADC_GetCalibrationStatus(ADC3) == SET);        // 硬件置0
  26.         ADC_SoftwareStartConvCmd(ADC3, ENABLE);
  27.         while (ADC_GetFlagStatus(ADC3, ADC_FLAG_STRT) == RESET);
  28. }
  29. int main() {
  30.         // 初始化usart
  31.         LunarInitUSART1();
  32.         LunarADCInit();
  33.         SYSTick_Init();
  34.         LunarNVICInit();
  35.         printf("stm32 启动\n");
  36.         int t = 3;
  37.         while(1) {
  38.                 printf("light:%d\r\n", ADC_GetConversionValue(ADC3));
  39.                 while (t > 0){
  40.                         t--;
  41.                         Delay_Ms(1000);
  42.                 }
  43.                 t= 3;
  44.         }
  45.         return 0;
  46. }
复制代码
  实验征象就是手机背光照射光敏电阻时,ADC转换数值变小。
  
本章完结

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表