当前位置: 首页 > news >正文

ADC 模拟量转数字量

1.ADC概述

在STM32 MCU中,利用ADC端口完成【电压值转换为数字值】方式。大多数传感器会利用ADC方式已进行模拟量转化数字量方式进行传感器数据提供。例如:光敏电阻,压敏电阻,水位传感器,电池电路传感器。

ADC可以将数据转换后,交给后续MCU 进行阈值判断,完成需求后进行其他操作。

1.1ADC技术点分析

1.1.1ADC主要特征

1.1.2ADC框图分析

1.1.3ADC转换器工作原理

ADC转换器根据【参考电压】和【采样精度】,采用【逐次逼近法】进行电压转数值处理

  • 当前ADC采样精度是4096(0X00~0X0FFF);
  • 参考电压是Vref += 3.3V  Vref -=0V
  • ADC每一个数据对应的电压可以趋近于认为是3.3V/4096 ≈0.0008
  • 假设当前ADC输入通道对应的电压是2.2V

1.2ADC编程实现光敏模块

1.2.1ADC电路相关模块分析

  1. 对应MCU引脚为PF8,要求PF8 GPIO 工作模块为【模拟输入】模式
  2. 对应ADC模块为ADC3 , 同时数据端口为IN6,操作的目标ADC==》ADC3_IN6
  3. 需要开放的时钟有
    1. ADC时钟使能
    2. GPIOF始终使能
  4. ADC要求的时钟最大14MHz,同时提供了规定的降频倍数/预分频倍数。需要根据当前MCU设计的要求提供时钟,72MHz的MCU主频,最快周期情况下,有且只能选择预分配倍数/降频倍数 为8     提供给ADC时钟9MHz
    1. 需要对APB2预分频倍数进行处理。

1.2.2 ADC时钟配置

  • RCC APB2ENR 时钟使能
  • RCC CFGR 预分频倍数配置

1.2.3ADC配置相关寄存器

ADC_CR1 寄存器配置

ADC_CR2 寄存器配置

我们需要再CONT位置进行连续转换,置为1 ,图中标记错误,已经划掉。

ADC采样周期控制寄存器

  • 对应寄存器为 ADC_SMPR1 ADC_SMPR2 分别对应的 ADC 通道为

    • ADC_SMPR1 = 10 ~ 17 ADC 通道

    • ADC_SMPR2 = 0 ~ 9 ADC 通道

      • 其中 16 和 17 ADC 通道对应 MCU 的温度传感器和 MCU 电压传感器。

      • ADC_SMPR1 => ADCx_IN10 ~ ADCx_IN15

      • ADC_SMPR2 => ADCx_IN0 ~ ADCx_IN9

  • 当前光敏电阻对应的 ADC 通道是 ADC3_IN6 ,选择 ADC_SMPR2 进行配置。

  • ADC 采用周期越长,对应的 ADC 精度越高。通常情况下采用 111 ==> 239.5 周期进行采样,真实周期 239.5 周期 + 12.5 周期。

ADC 规则通道配置
  • ADC 规则通道支持 16 路 ADC 输入,每次转换一路 ADC 数据,需要配置当前 16 路 ADC 输入通道的对应关系。例如
    • ADC3 规则通道 0 ===> ADC3_IN5
    • ADC3 规则通道 1 ===> ADC3_IN10
    • ADC3 规则通道 2 ===> ADC3_IN6
  • 当前有且只有一路 ADC 数据输入,规则通道只需要开放通道 0 配置 ADC3_IN6 即可。

ADC规则通道数据转换结果寄存器
ADC 开启转换之后,DR 数据会根据用户要求,定时更新。

这些都是进行配置ADC所需要的。

以下是实现代码

adc.h

#ifndef _ADC_H
#define _ADC_H
#include "stm32f10x.h"
#include "delay.h"
#define GPIOF_RCC_APB2_CLOCK_ENABLE (0x01 << 7)
#define ADC3_RCC_APB2_CLOCK_ENABLE (0x01 << 15)
#define Analog_Input_Mode (0x00)
void LSEN_Init(void);
u16 LSEN_GetValue(void);
#endif

adc.c

#include "adc.h"
void LSEN_Init(void)
{
/*
1.RCC 时钟使能,需要使能有 GPIOF 和 ADC3
因为当前光敏电阻对应 GPIO PF8 ,ADC 通道是 ADC3_IN6
*/
RCC->APB2ENR |= GPIOF_RCC_APB2_CLOCK_ENABLE | ADC3_RCC_APB2_CLOCK_ENABLE;
/*
2. GPIOF 对应 PF8 配置为【模拟输入模式】
对应 GPIOF->CRH [CNF8:MODE8]
*/
GPIOF->CRH &= ~(0x0F);
/*
3. ADC 配置
*/
/*
3.1 ADCCLK 对应 APB2 预分频倍数配置,对应寄存器是
RCC->CFGR, 设置预分配倍数位 6. ADCCLK 对应 12MHz
*/
RCC->CFGR &= ~(0x03 << 14);
RCC->CFGR |= (0x02 << 14);
/*
3.2 ADC 采用周期时间控制
Tconv = 采样时间 + 12.5个周期 官方 ADC 规定周期。
一般情况下采样周期越长,对应的 ADC 数据精度越高。
239.5 + 12.5 周期。
*/
ADC3->SMPR2 |= (0x07 << 18);
/*
3.3 ADC 工作通道配置
选择规则通道进行 ADC 转换,同时开放一个转换通道。
对应 ADC3_IN6
*/
ADC3->SQR1 &= ~(0x0F << 20); // ADC 规则通道开始一个转换通道
ADC3->SQR3 &= ~(0x1F); // 擦除 ADC3 规则转换通道第一个转换通道原本数据
ADC3->SQR3 |= (0x06); // 赋值 ADC3 规则转换通道第一个转换通道对应 ADC3_IN6
/*
3.4 ADC CR 配置
CR1
DUALMOD[3:0] [位19:16] 配置 ADC 独立模式 ==> 0000
SCAN [位8] 关闭 ADC 扫描模式 ==> 0
CR2
SWSTART [位22] 开启规则转换通道 ==> 1
EXTTRIG [位20] 规则转换通道外部触发方式开始 ==> 1
EXTSEL[2:0] [位19:17] 选择启动规则通道组转换的外部事件 ==> 111
明确为软件触发当前 ADC 转换。
ALIGN [位11] 转换结果数据对齐方式 ==> 0 右对齐
CONT [位1] 连续转换 ==> 1 连续转换模式
*/
ADC3->CR1 &= ~(0x0F << 16); // DUALMOD[3:0] [位19:16]
ADC3->CR1 &= ~(0x01 << 8); // SCAN [位8]
ADC3->CR2 &= ~(0xFFFFFFFF);
ADC3->CR2 |= (0x01 << 22); // SWSTART [位22]
ADC3->CR2 |= (0x01 << 20); // EXTTRIG [位20]
ADC3->CR2 |= (0x07 << 17); // EXTSEL[2:0] [位19:17]
ADC3->CR2 |= (0x01 << 1);
/*
因为整个 ADC3->CR2 已经进行整体擦除操作,对应 ALIGN 无需再次赋值。
*/
/*
3.5 ADC 校准和开启
需要在 ADC 时钟,通道和其他相关配置完成之后,才可以开启校准。
ADC 自校准 + 重启过程
需要利用 ADC CR2 配置寄存器完成RSTCAL [位3] 复位校准
CAL [位2] AD 校准
ADON [位0] AD 转换模块开启
*/
// 3.5.1 ADC 关闭掉电,重启
ADC3->CR2 &= ~(0x01); // ADC 关闭断电
Delay_ms(10); // 延时 10 ms
ADC3->CR2 |= 0x01; // ADC 打开
/*
3.5.2 ADC 开启复位校准
需要对 CR2 寄存器 RSTCAL 位赋值为 1,如果 复位校准完毕
硬件会将对应 RSTCAL 位置为 0.
1 ==> 开启复位校准
0 ==> 硬件复位校准结束
*/
ADC3->CR2 |= (0x01 << 3); // 开启复位校准
while (ADC3->CR2 & (0x01 << 3)); // 等待硬件将对应寄存器位置为 0,校准结束
Delay_ms(10); // 延时 10 ms
/*
3.5.3 ADC A/D 校准
需要对 CR2 寄存器 CAL 位赋值为 1,如果 复位校准完毕
硬件会将对应 CAL 位置为 0.
1 ==> 开启 A/D 校准开启
0 ==> 硬件 A/D 校准结束
*/
ADC3->CR2 |= (0x01 << 2); // 开启 A/D 校准
while (ADC3->CR2 & (0x01 << 2)); // 等待硬件将对应寄存器位置为 0,校准结束
ADC3->CR2 |= 0x01; // ADC 打开
}
u16 LSEN_GetValue(void)
{
/*
ADC->SR 状态寄存器中,位[1] EOC 标志位,在规则通道或者注入通道转换数据
结束之后,被硬件置为 1,表示有 ADC 转换数据在对应的 DR 存在。
该位清除方式是读取 ADCx->DR 寄存器数据。
*/
while (0 == (ADC3->SR & (0x01 << 1)));
return ADC3->DR;
}

main.c

#include "stm32f10x.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "led.h"
#include "beep.h"
#include "delay.h"
#include "key.h"
#include "usart1.h"
#include "adc.h"
int main(void)
{
USART1_Init(9600);
LSEN_Init();
char buffer[32];
while (1)
{
u16 lsen_adc_value = LSEN_GetValue();
sprintf(buffer, "ADC Value : %d\r\n", lsen_adc_value);
USART1_SendString(buffer);
memset(buffer, 0, 32);
Delay_ms(2000);
}
}

http://www.dtcms.com/a/507265.html

相关文章:

  • 网络广告是什么网站优化外包费用
  • 【IEEE/EI/Scopus检索】2026年第六届信息技术与云计算国际会议(ITCC 2026)
  • 赋能天然产物科学研究:多模态大模型与知识图谱的革新之旅
  • 用C语言实现原型模式时,如何确定需要深拷贝还是浅拷贝?
  • Spring Boot 3零基础教程,WEB 开发 Thymeleaf 属性优先级 行内写法 变量选择 笔记42
  • Go语言:对其语法的一些见解
  • Go Web 编程快速入门 · 04 - 请求对象 Request:头、体与查询参数
  • 伦教九江网站建设辽宁工程建筑信息网
  • Deep End-to-End Alignment and Refinement for Time-of-Flight RGB-D Module,2019
  • Ubuntu 安装 Gitea
  • 通达信灵活屏
  • 亚马逊云代理商:AWS怎么通过加密实现数据保护目标?
  • C标准库--C99--控制浮点环境<fenv.h>
  • 【Linux】“ 权限 “ 与相关指令
  • webrtc弱网-ReceiveSideCongestionController类源码分析及算法原理
  • 通达信--主题投资分析
  • 揭阳专业做网站天台县建设规划局网站
  • 福海网站制作关键词堆砌的作弊网站
  • sql特训
  • LeetCode 刷题【126. 单词接龙 II】
  • 防火墙规则设置
  • 江协科技STM32课程笔记(五)— ADC模数转换器
  • 什么是慢查询,慢请求,以及如何避免
  • 网站设计模板简约福州网站设计
  • 各大网站做推广广告什么是企业形象设计
  • 大模型金融量化比赛
  • Kubernetes深入学习之容器入门(一)
  • Docker安装部署MrDoc觅思文档-免费的国产知识库管理系统
  • 批量更新操作全攻略:从JDBC原理到多框架实现(MyBatis/MyBatis-Plus/Nutz)
  • 简述:普瑞时空数据建库软件(国土变更建库)之一(2025年部分新规则)