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

STM32_ADC_寄存器操作

文章目录

  • 一、ADC寄存器
    • 1、ADC状态寄存器(ADC_SR)
    • 2、ADC控制寄存器 1(ADC_CR1)
    • 3、ADC控制寄存器 2(ADC_CR2)
    • 4、ADC采样时间寄存器 1(ADC_SMPR1)
    • 5、ADC采样时间寄存器 2(ADC_SMPR2)
    • 6、ADC注入通道数据偏移寄存器x (ADC_JOFRx)(x=1..4)
    • 7、ADC看门狗高阀值寄存器(ADC_HTR)
    • 8、ADC看门狗低阀值寄存器(ADC_LRT)
    • 9、ADC规则序列寄存器 1(ADC_SQR1)
    • 10、ADC规则序列寄存器 2(ADC_SQR2)
    • 11、ADC规则序列寄存器 3(ADC_SQR3)
    • 12、ADC注入序列寄存器(ADC_JSQR)
    • 13、ADC 注入数据寄存器x (ADC_JDRx) (x= 1..4)
    • 14、ADC规则数据寄存器(ADC_DR)
    • 15、ADC寄存器地址映像
  • 二、代码实例
    • 1、ADC1 单次采样(PA0,查询模式)
    • 2、ADC1 连续采样(PA0,中断模式)
    • 3、ADC1 多通道扫描(PA0/CH0 + PA1/CH1,DMA 批量采集)
  • 三、总结
    • 1、核心寄存器
    • 2、注意事项
    • 3、ADC 寄存器编程核心流程:

一、ADC寄存器

1、ADC状态寄存器(ADC_SR)

地址偏移:0x00
复位值:0x0000 0000

2、ADC控制寄存器 1(ADC_CR1)

地址偏移:0x04
复位值:0x0000 0000

3、ADC控制寄存器 2(ADC_CR2)

地址偏移:0x08
复位值:0x0000 0000


4、ADC采样时间寄存器 1(ADC_SMPR1)

地址偏移:0x0C
复位值:0x0000 0000

5、ADC采样时间寄存器 2(ADC_SMPR2)

地址偏移:0x10
复位值:0x0000 0000

6、ADC注入通道数据偏移寄存器x (ADC_JOFRx)(x=1…4)

地址偏移:0x14-0x20
复位值:0x0000 0000

7、ADC看门狗高阀值寄存器(ADC_HTR)

地址偏移:0x24
复位值:0x0000 0000

8、ADC看门狗低阀值寄存器(ADC_LRT)

地址偏移:0x28
复位值:0x0000 0000

9、ADC规则序列寄存器 1(ADC_SQR1)

地址偏移:0x2C
复位值:0x0000 0000

10、ADC规则序列寄存器 2(ADC_SQR2)

地址偏移:0x30
复位值:0x0000 0000

11、ADC规则序列寄存器 3(ADC_SQR3)

地址偏移:0x34
复位值:0x0000 0000

12、ADC注入序列寄存器(ADC_JSQR)

地址偏移:0x38
复位值:0x0000 0000

13、ADC 注入数据寄存器x (ADC_JDRx) (x= 1…4)

地址偏移:0x3C – 0x48
复位值:0x0000 0000

14、ADC规则数据寄存器(ADC_DR)

地址偏移:0x4C
复位值:0x0000 0000

15、ADC寄存器地址映像


二、代码实例

1、ADC1 单次采样(PA0,查询模式)

最基础的 ADC 用法,单次触发转换、查询结果,适合低频采样场景。

#include"stm32f10x.h"/** * @brief 系统时钟初始化(72MHz,HSE=8MHz) */voidSystemClock_Init(void){RCC->CR|=RCC_CR_HSEON;while(!(RCC->CR&RCC_CR_HSERDY));FLASH->ACR|=FLASH_ACR_LATENCY_2;RCC->CFGR&=~RCC_CFGR_HPRE;RCC->CFGR|=RCC_CFGR_PPRE1_DIV2;RCC->CFGR&=~RCC_CFGR_PPRE2;RCC->CFGR&=~(RCC_CFGR_PLLSRC|RCC_CFGR_PLLXTPRE|RCC_CFGR_PLLMULL);RCC->CFGR|=RCC_CFGR_PLLMULL9;RCC->CR|=RCC_CR_PLLON;while(!(RCC->CR&RCC_CR_PLLRDY));RCC->CFGR&=~RCC_CFGR_SW;RCC->CFGR|=RCC_CFGR_SW_PLL;while((RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_PLL);}/** * @brief ADC1初始化(单次转换,CH0/PA0,查询模式) */voidADC1_Single_Init(void){// 1. 开启时钟:GPIOA、ADC1RCC->APB2ENR|=RCC_APB2ENR_IOPAEN|RCC_APB2ENR_ADC1EN;// ADC时钟分频:6分频(72/6=12MHz ≤14MHz)RCC->CFGR&=~RCC_CFGR_ADCPRE;RCC->CFGR|=RCC_CFGR_ADCPRE_DIV6;// 2. 配置GPIO:PA0模拟输入(无上下拉)GPIOA->CRL&=~(GPIO_CRL_MODE0|GPIO_CRL_CNF0);// 模拟输入模式// 3. 配置ADC1核心参数ADC1->CR1&=~ADC_CR1_SCAN;// 关闭扫描模式(单次通道)ADC1->CR2&=~ADC_CR2_CONT;// 关闭连续转换(单次转换)ADC1->CR2&=~ADC_CR2_ALIGN;// 数据右对齐(低12位有效)ADC1->SQR1&=~ADC_SQR1_L;// 转换序列长度:1(L[3:0]=0000)ADC1->SQR3&=~ADC_SQR3_SQ1;// 转换序列第1位:CH0(0)ADC1->SQR3|=0;// 4. 配置采样时间:CH0采样时间239.5周期(提高精度)ADC1->SMPR2&=~ADC_SMPR2_SMP0;ADC1->SMPR2|=ADC_SMPR2_SMP0_2;// SMP0[2:0]=110 → 239.5周期// 5. 开启ADC1并校准ADC1->CR2|=ADC_CR2_ADON;// 开启ADCADC1->CR2|=ADC_CR2_CAL;// 启动校准while(ADC1->CR2&ADC_CR2_CAL);// 等待校准完成}/** * @brief ADC1单次采样(查询模式) * @return 采样值(0~4095) */uint16_tADC1_Single_Read(void){// 1. 启动ADC转换ADC1->CR2|=ADC_CR2_SWSTART;// 2. 等待转换完成(EOC=1)while(!(ADC1->SR&ADC_SR_EOC));// 3. 读取采样值(DR寄存器,右对齐)returnADC1->DR;}/** * @brief 采样值转电压(mV) * @param adc_val:ADC采样值(0~4095) * @return 电压值(mV,如1650=1.65V) */uint16_tADC_To_Voltage(uint16_tadc_val){// 公式:电压 = (adc_val / 4095) * 3300mVreturn(uint32_t)adc_val*3300/4095;}// 主函数intmain(void){uint16_tadc_val,voltage;SystemClock_Init();ADC1_Single_Init();while(1){// 单次采样adc_val=ADC1_Single_Read();voltage=ADC_To_Voltage(adc_val);// 可通过串口输出adc_val和voltage,或做其他处理// 简单延时for(uint32_ti=0;i<1000000;i++);}}

2、ADC1 连续采样(PA0,中断模式)

连续转换 + 中断通知,CPU 无需轮询,适合高频采样场景。

#include"stm32f10x.h"// 全局变量:存储最新采样值uint16_tADC1_Cont_Value=0;/** * @brief ADC1初始化(连续转换,CH0/PA0,中断模式) */voidADC1_Cont_IRQ_Init(void){// 1. 时钟/GPIO配置(同场景1)RCC->APB2ENR|=RCC_APB2ENR_IOPAEN|RCC_APB2ENR_ADC1EN;RCC->CFGR|=RCC_CFGR_ADCPRE_DIV6;GPIOA->CRL&=~(GPIO_CRL_MODE0|GPIO_CRL_CNF0);// 2. 配置ADC1:连续转换+中断ADC1->CR1&=~ADC_CR1_SCAN;ADC1->CR2|=ADC_CR2_CONT;// 开启连续转换ADC1->CR2&=~ADC_CR2_ALIGN;ADC1->SQR1&=~ADC_SQR1_L;ADC1->SQR3|=0;ADC1->SMPR2|=ADC_SMPR2_SMP0_2;// 3. 开启ADC转换完成中断ADC1->CR1|=ADC_CR1_EOCIE;// 开启EOC中断// 4. 配置NVIC(ADC1_IRQn=18号中断)SCB->AIRCR=0x05FA0800;// 优先级分组2NVIC->IP[18]&=~0xFF;NVIC->IP[18]|=0x10;// 抢占优先级1NVIC->ISER[0]|=(1<<18);// 使能ADC1中断// 5. 开启ADC并校准,启动转换ADC1->CR2|=ADC_CR2_ADON;ADC1->CR2|=ADC_CR2_CAL;while(ADC1->CR2&ADC_CR2_CAL);ADC1->CR2|=ADC_CR2_SWSTART;// 启动连续转换}/** * @brief ADC1中断服务函数 */voidADC1_IRQHandler(void){// 检查转换完成标志if(ADC1->SR&ADC_SR_EOC){ADC1_Cont_Value=ADC1->DR;// 读取采样值ADC1->SR&=~ADC_SR_EOC;// 清除EOC标志}}// 主函数intmain(void){uint16_tvoltage;SystemClock_Init();ADC1_Cont_IRQ_Init();while(1){// 实时读取连续采样值并转电压voltage=ADC_To_Voltage(ADC1_Cont_Value);// 业务处理逻辑}}

3、ADC1 多通道扫描(PA0/CH0 + PA1/CH1,DMA 批量采集)

扫描多个通道 + DMA 批量传输,适合多模拟量同步采集(如温度、电压、电流)。

#include"stm32f10x.h"// DMA采集缓冲区:存储CH0和CH1的采样值uint16_tADC1_Scan_Buf[2]={0};#defineADC_SCAN_CH_NUM2/** * @brief ADC1+DMA初始化(多通道扫描,CH0+CH1,DMA1_Channel1) */voidADC1_Scan_DMA_Init(void){// 1. 开启时钟:GPIOA、ADC1、DMA1RCC->APB2ENR|=RCC_APB2ENR_IOPAEN|RCC_APB2ENR_ADC1EN;RCC->AHBENR|=RCC_AHBENR_DMA1EN;RCC->CFGR|=RCC_CFGR_ADCPRE_DIV6;// 2. 配置GPIO:PA0/PA1模拟输入GPIOA->CRL&=~(GPIO_CRL_MODE0|GPIO_CRL_CNF0|GPIO_CRL_MODE1|GPIO_CRL_CNF1);// 3. 配置ADC1:扫描模式+连续转换ADC1->CR1|=ADC_CR1_SCAN;// 开启扫描模式ADC1->CR2|=ADC_CR2_CONT;// 连续转换ADC1->CR2|=ADC_CR2_DMA;// 开启ADC DMA模式ADC1->CR2&=~ADC_CR2_ALIGN;// 转换序列长度:2(L[3:0]=0001 → 2个通道)ADC1->SQR1&=~ADC_SQR1_L;ADC1->SQR1|=(ADC_SCAN_CH_NUM-1)<<20;// 转换序列:第1位=CH0,第2位=CH1ADC1->SQR3&=~(ADC_SQR3_SQ1|ADC_SQR3_SQ2);ADC1->SQR3|=0<<0;// SQ1=CH0ADC1->SQR3|=1<<5;// SQ2=CH1// 采样时间:CH0/CH1均为239.5周期ADC1->SMPR2|=ADC_SMPR2_SMP0_2|ADC_SMPR2_SMP1_2;// 4. 配置DMA1_Channel1(ADC1映射通道)DMA1_Channel1->CCR&=~DMA_CCR_EN;// 关闭DMA通道DMA1_Channel1->CCR=0;DMA1_Channel1->CCR&=~DMA_CCR_DIR;// 方向:外设→内存DMA1_Channel1->CCR|=DMA_CCR_MINC;// 内存地址自增DMA1_Channel1->CCR&=~DMA_CCR_PINC;// 外设地址不自增DMA1_Channel1->CCR|=DMA_CCR_PSIZE_0;// 外设数据宽度:16位DMA1_Channel1->CCR|=DMA_CCR_MSIZE_0;// 内存数据宽度:16位DMA1_Channel1->CCR|=DMA_CCR_CIRC;// 循环模式(连续采集)DMA1_Channel1->CCR|=DMA_CCR_PL_1;// 优先级:高// 5. 配置DMA地址和长度DMA1_Channel1->CPAR=(uint32_t)&ADC1->DR;// 外设地址(ADC_DR)DMA1_Channel1->CMAR=(uint32_t)ADC1_Scan_Buf;// 内存缓冲区DMA1_Channel1->CNDTR=ADC_SCAN_CH_NUM;// 传输长度// 6. 启动DMA和ADCDMA1_Channel1->CCR|=DMA_CCR_EN;// 开启DMAADC1->CR2|=ADC_CR2_ADON;// 开启ADCADC1->CR2|=ADC_CR2_CAL;// 校准while(ADC1->CR2&ADC_CR2_CAL);ADC1->CR2|=ADC_CR2_SWSTART;// 启动连续转换}// 主函数intmain(void){uint16_tvoltage0,voltage1;SystemClock_Init();ADC1_Scan_DMA_Init();while(1){// ADC1_Scan_Buf[0] = CH0采样值,ADC1_Scan_Buf[1] = CH1采样值voltage0=ADC_To_Voltage(ADC1_Scan_Buf[0]);voltage1=ADC_To_Voltage(ADC1_Scan_Buf[1]);// 多通道数据处理逻辑}}

三、总结

1、核心寄存器

2、注意事项

DC 时钟限制
STM32F103 ADC 时钟最大 14MHz,72MHz 系统时钟下必须 6 分频(72/6=12MHz),否则 ADC 采样精度下降。
采样时间选择:
采样时间越长,抗干扰能力越强,常用 239.5 周期(高精度)、13.5 周期(高速);
公式:采样时间 = (SMPx + 1) × ADC 时钟周期(如 239.5 周期 @12MHz = ~20μs)。
校准操作:
每次开启 ADC 后必须执行校准(ADC_CR2_CAL),校准完成后才能启动转换,否则采样值偏差大。
DMA 循环模式:
多通道连续采集时,DMA 需开启CIRC循环模式,否则采集完一次后停止。
电压转换精度:
公式(adc_val * 3300) / 4095中,需用uint32_t强制转换,避免 16 位整数溢出。

3、ADC 寄存器编程核心流程:

开时钟→配 GPIO→配 ADC 参数(扫描 / 连续 / 采样时间)→校准→启动转换→读数据;

http://www.jsqmd.com/news/512064/

相关文章:

  • 基于RABC的权限控制设计
  • 数据库设计原则
  • Qwen2.5-VL-7B-Instruct保姆级教程:对话历史管理、一键清空操作
  • 总结上海移民中介服务费用情况,多少钱才合理 - mypinpai
  • WangEditor — 轻量级富文本编辑器的核心功能与实战应用
  • 【技术干货】MiniMax M2.7 自主进化多智能体模型:从原理到实战落地指南
  • Pixel Dimension Fissioner部署教程:GPU算力优化适配+免配置镜像实操
  • RADIUS协议实战解析:从RFC2865/2866到典型配置与报文深度剖析
  • Pixel Dimension Fissioner快速上手:像素UI交互+实时HUD状态监控详解
  • 如何用AI读脸术做实时分析?CPU推理优化实战案例详解
  • SEO_如何通过内容优化有效提升SEO效果?(143 )
  • 2026年怀化透析中心排名,附近透析中心收费标准与服务质量对比 - myqiye
  • Qwen-Image镜像一键部署:预装CUDA12.4+PyTorch+Qwen-VL依赖的极简方案
  • AudioLDM-S生成效果实测对比:10步和50步有什么区别?听音频就知道
  • 2026年市场上有实力的磁性材料成型液压机源头厂家推荐榜单,稀土永磁压制/铁氧体成型/磁性材料湿法成型/自动化生产线,磁性材料成型液压机制造企业哪家好 - 品牌推广师
  • Kubernetes存储与GPU管理:从开源到主流云厂商的最佳实践
  • Jimeng AI Studio(Z-Image Edition)入门教程:环境部署与快速调用指南
  • 测貂图片AI工具时,模板多不等于后面好改
  • 2026年浙江地区好用的弯管机厂家推荐,专业厂商盘点 - 工业推荐榜
  • 【工业级C语言OTA健壮性设计】:基于CRC32+SHA256+版本指纹三重校验的失败分级响应策略
  • Python实战:利用莱斯利模型预测种群动态变化
  • # 发散创新:用Python打造自动化渗透测试工具链——从扫描到漏洞利用全流程实战在现代信息安全
  • LVGL 7.10.1在STM32F103上的嵌入式GUI移植实战
  • Qwen3-32B-Chat开源模型部署新范式:单卡24G实现32B参数高效推理
  • 总结哈尔滨自动变速箱维修推荐,怎么选择合适的公司? - 工业设备
  • FFmpeg编解码实战
  • SEO_10个提升网站排名的实用SEO技巧分享(470 )
  • STM32 进阶封神之路(十九):ADC 深度解析 —— 从模拟信号到数字转换(底层原理 + 寄存器配置)
  • 告别竞态条件:call_once 原理与应用,如何优雅地解决并发初始化难题
  • 召回率优化进入倒计时:Dify即将弃用legacy-rag插件接口,立即下载迁移工具包+自动适配脚本(含召回A/B测试看板)