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

ADC模数转换器(相当于电压表)

1.ADC简介

1.简述(根据第二点):

原本只有高、低电平之分,现在通过ADC可以得到具体的电压值(数字电路只有高低电平)

2.转换频率:1MHz(根据第三点的1us转换时间)

3.模拟看门狗:

可以监测指定的某个通道(达到某个条件就会申请中断,在中断中执行某些操作)

4.另外:

DAC是数字-模拟转换器,PWM也是数字到模拟的桥梁,通过调整占空比来模拟信号

2.ADC内部结构

1.普通ADC内部结构

总结:通过比较器,DAC采用二分法输出已知编码的电压与输入电路中未知编码的电压比较,逐次逼近未知编码,最后输出正确的电压值(VREF是参考电压,结果取决于其电压值)

2.STM32的ADC内部结构

注意:注入通道由4个数据寄存器,可以同时存4个数据;而规则通道只有一个数据寄存器,同时传入16个数据时只能通过1个,其他的会被挤掉,所以最好配合DMA(数据转运帮手)使用。

触发ADC开始转换的信号:软件触发,程序中手写代码;硬件触发,利用定时器的更新事件触发,也可以选择外部中断引脚(即EXTI)来触发转换

VDDA和VSSA是内部模拟部分的电源

ADCCLK是用于驱动内部逐次比较的时钟,在RCC中通过ADC分频器后得到(最大14MHz),所以ADC分频器只能选择6分频(12MHz)和8分频(9MHz)

EOC:规则组的完成信号(标志位)

JEOC:注入组的完成信号(标志位)

3.ADC基本结构

部分解释:触发控制就是选择软件触发还是硬件触发,开关控制就是ADC_Cmd函数给ADC上电

4.细节

1.输入通道(对应的GPIO口)

注意:STM32只有ADC1和ADC2

2.规则组的4种转换模式

1.单次转换,非扫描模式

解释:在非扫描模式下,16个序列就只有序列1有效,在此选择通道后,ADC对这个通道进行模数转换,完成后在EOC置1即可。(每次都会结束)

2.连续转换,非扫描模式

解释:一直进行非扫描模式的转换。(像读AD值的时候直接读数据寄存器)

3.单次转换,扫描模式

解释:通道数目需要直接手动写入参数,在扫描模式下,16个序列可以自由使用,但是每次转换都会有多个结果放在数据寄存器里,这就意味着需要用DMA及时将数据挪走。

4.连续转换,扫描模式

上面已经解释过两个模式的具体区别,在此不再解释。

3.触发控制(规则组的触发源)

倒数第二个触发源的类型究竟是引脚还是定时器需要用AFIO重映射来确定

4.数据对齐

原因:ADC是12位的,转换结果是一个12位的数据,但是数据寄存器是16位的(一般用右对齐)

5.转换时间

这就是稳定情况下最快1us的来源

6.校准(了解)

5.实战代码

1.部分函数的功能

//ADCCLK的配置函数(配置ADCCLK分频器) void RCC_ADCCLKConfig(uint32_t RCC_PCLK2); //配置ADC转换器 void ADC_DeInit(ADC_TypeDef* ADCx); void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct); void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct); void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState); void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//开启DMA输出信号 void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//中断输出控制 void ADC_ResetCalibration(ADC_TypeDef* ADCx);//复位校准 FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);//获取复位校准状态 void ADC_StartCalibration(ADC_TypeDef* ADCx);//开始校准 FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取开始校准状态 void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//用于软件触发 FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx); //ADC获取软件开始转换状态(不能判断是否结束) FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//获取标志位状态(看EOC) //配置间断模式 void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);//每隔几个通道间断一次 void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//是否启动间断模式 void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); //ADC规则组通道配置(在序列中选择通道) void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); //ADC外部触发转换控制(是否允许外部触发转换) uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); //ADC获取转值(读取AD转换的数据寄存器,即读取转换结果) uint32_t ADC_GetDualModeConversionValue(void); //ADC获取双模式转换值 //注入组 void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState); void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv); void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx); void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length); void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset); uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel); //模拟看门狗 void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog); //是否启动看门狗 void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold); //配置高低阈值 void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel); //配置看门通道 //ADC温度传感器内部参考电压控制 void ADC_TempSensorVrefintCmd(FunctionalState NewState); FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//获取标志位状态 void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//清除标志位 ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);//获取中断状态 void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);//清除中断挂起位

2.配置思路

1.RCC开启时钟(把GPIO和ADC的时钟打开,包括ADCCLK的分频器也要配置)

2.配置GPIO(配置成模拟输入模式)

3.配置开关,将左边的通道接入右边的规则组里(就是选择通道)

4.配置ADC转换器(转换模式、通道数、触发源、数据对齐等)

5.开启ADC

3.基本配置格式(AD单通道、非扫描模式)

//ADC都是APB2上的设备 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启ADC1的时钟 //需要用到PA0口将可调的电压输出 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //配置ADCCLK RCC_ADCCLKConfig(RCC_PCLK2_Div6); //配置GPIO时钟 GPIO_InitTypeDef GPIO_InitStructure;//结构体定义 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //模拟输入(GPIO无效,即为ADC专属模式) GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//IO口 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //选择规则组的输入通道(在序列1写入通道0) ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5); //初始化ADC ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC模式(独立还是双模式) ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据对齐 ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //外部触发转换选择(触发源)(此处为软件触发) ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//连续转换还是单次转换模式 ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描还是非扫描模式 ADC_InitStructure.ADC_NbrOfChannel=1; //扫描模式下总工会用到的通道数 ADC_Init(ADC1,&ADC_InitStructure); ADC_Cmd(ADC1,ENABLE);//开启ADC //校准 ADC_ResetCalibration(ADC1);//复位校准 while(ADC_GetResetCalibrationStatus(ADC1)==SET);//获取复位校准状态 ADC_StartCalibration(ADC1);//开始校准 while(ADC_GetCalibrationStatus(ADC1)==SET);//获取开始校准状态

4.程序编写的细节

1.避免AD的输出抖动,采用迟滞比较,即设置高低阈值,高于上阈值或低于下阈值才进行操作。

2.AD值跳变程度太高,可以采用滤波的方法或裁剪分辨率(即将数据尾部去掉)

http://www.cnnetsun.cn/news/4004.html

相关文章:

  • 光学标准具的建模
  • 第13篇:多模态大模型论文MokA: Multimodal Low-Rank Adaptation for MLLMs一种兼顾多模态特性的高效微调策略
  • Wan2.2-T2V-A14B推动AIGC视频内容生态发展的关键作用
  • NAXSI WAF终极部署指南:让Nginx秒变安全卫士
  • 昇腾环境部署大模型全攻略
  • Wan2.2-T2V-A14B在汽车广告视频生成中的专项优化建议
  • 如何通过dpt-tools彻底改造索尼电子纸体验
  • arXiv LaTeX Cleaner:学术论文隐私保护与文件优化的终极指南
  • 微信自动答题小工具:3分钟搞定PC端自动答题神器
  • AxGlyph矢量图绘制软件完整使用指南
  • Windows 上解决 kaldifst DLL 加载失败问题
  • 元宇宙渲染卡顿怎么办?一文搞懂C++模块化架构的性能调优策略
  • 为什么顶尖团队都在关注C++26的依赖图编译模型?(内部架构首曝光)
  • 错过C# 14泛型增强特性将落后三年,现在掌握还来得及
  • Vibe Coding 的跨学科迁移:Agent 规划如何赋能叙事设计与学术研究?
  • 多模态交互:AI原生应用领域的未来趋势
  • 关于滤波器组多载波系统中多输入多输出技术与峰均功率比分析方案
  • 【企业级架构升级必看】:Symfony 8与API Gateway集成的4个关键步骤
  • Wan2.2-T2V-5B支持API调用,轻松集成至现有平台
  • vxe-table超实用入门指南:快速掌握Vue表格开发核心技能
  • Fashion-MNIST终极指南:重新定义图像分类基准测试
  • Java面试模拟:互联网大厂求职者的挑战
  • TensorRT-LLM如何实现5倍推理加速:核心技术解析与部署实践
  • 今年的网工到底为什么这么难找工作!!2026还会好吗?
  • jQuery人脸检测插件:从零开始的完整使用指南
  • 2026年AI就业市场深度解析:百万年薪岗位涌现,传统职位何去何从?
  • 8位RISC CPU完整实现指南:从架构设计到实战验证
  • OptiScaler终极指南:为什么AI超分辨率能让你帧率翻倍
  • Chinese-CLIP-ViT-Base-Patch16终极指南:快速构建中文多模态AI应用
  • 三步实现完全离线AI文档生成:本地部署终极隐私保护方案