记录每次学习的过程,总结学习的内容,希望能给到自己和别人帮助。
嵌入式学习-STC-ADC(模数转换器)
ADC
(Analog to Digital Converter 模数转换器)是一种将模拟信号转换为数字信号的电路。在电子系统中,模拟信号常常需要转换为数字信号进行处理和存储。模数转换的基本原理是将模拟信号进行采样,并将采样值量化为数字表示。
● 采样:是指在一定时间间隔内对模拟信号进行测量,并将测量值存储在数字形式的数据中
● 量化:是将这些连续的模拟信号值离散化为一系列数字值,通常使用二进制表示。
简单理解,ADC是把模拟信号转换为数字信号的工具,我们可以认为,一个信号有强弱之分,强弱的体现为电压的高低。在数字电路中,只有0和1之分,也就是高电平或低电平。那么体现不了这个强弱。ADC的作用就是体现强弱,精确化的拿到具体的值。

● 模拟信号:信号有强弱之分,强弱的体现为电压的高低
● 数字电路:只有0和1之分,也就是高电平或低电平
应用场景:
- 医疗设备:如心电图、血压计之类。
- 音频信号处理:在数字音频处理中,ADC将模拟音频信号转换为数字信号,然后可以进行数字信号处理和存储。
- 电力系统:测量电压。
总之,需要知道信号强弱的,需要将模拟信号转为数字信号的都会用到ADC。
主要功能:采集和量化
io设置模式:为了能准确采集,初始化为高阻输入
用4096表示基准电压
2.5 1.25
4096 2048
ADC为12位精度的,意思是最大值是2的12次方,值为4096.
ADC的这个最大值,表示的是最大测量范围:
- 数值最大为4096
- 测量的电压值不能超过基准电压
- 基准电压对应的值为4096
记住:我们用4096表示基准电压。
例如采集到4096的时候,证明是最大电压,这时候会是2.5伏。例如采集到2048的时候,证明当时的电压是1.25伏。
以上原理图中,基准电压由 VREF电压决定。这个电路中用到了一个芯片CJ431/CD431,这是一款电压基准芯片,会恒定的输出2.5V电压。
在我们的设计方案中,理论上可以不使用这个电压基准芯片的,直接连接3V3,但是LDO的输出稳定性不够,因此使用电压基准芯片会更为准确。
由以上我们可以得出:
- 基准电压为:2.5V
- 基准电压对应的数值是4096
- 测量的值为ADC引脚
- 电压值的计算:

反向得到电源输入电压
- 将ADC_Vref+引脚接到VCC管脚
- MCU_Vcc = 4096 * 1.19V / 12位ADC转换结果(CH15)
计算公式:

ADC功能引脚
STC8H芯片有15个通道的ADC功能引脚:

代码流程:
配置IO工作模式
配置ADC ADC_Config();
用 函数来读取采样值
IO初始化为高阻输入
void GPIO_config(void) {
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_5; //指定要初始化的IO,
GPIO_InitStructure.Mode = GPIO_HighZ; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P0, &GPIO_InitStructure);//初始化
}
ADC配置逻辑
一般内容不用修改
/******************* AD配置函数 *******************/
void ADC_config(void)
{
ADC_InitTypeDef ADC_InitStructure; //结构定义
ADC_InitStructure.ADC_SMPduty = 31; //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
ADC_InitStructure.ADC_CsSetup = 0; //ADC 通道选择时间控制 0(默认),1
ADC_InitStructure.ADC_CsHold = 1; //ADC 通道选择保持时间控制 0,1(默认),2,3
ADC_InitStructure.ADC_Speed = ADC_SPEED_2X1T; //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16T
ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; //ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
ADC_Inilize(&ADC_InitStructure); //初始化
ADC_PowerControl(ENABLE); //ADC电源开关, ENABLE或DISABLE
NVIC_ADC_Init(DISABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
数据读取与转换
result = Get_ADCResult(ADC_CH13);
v = result * 2.5 / 4096;
功能举例:
获取热敏电阻NTC数值
热敏电阻的特性:温度上升,电阻减少
NTC(Negative Temperature Coefficient)是指随温度上升电阻减小、具有负温度系数的热敏电阻现象和材料。
得到电阻,反推温度。
想得到电阻,要得到电压。

阻温特性表
表值过多,有兴趣的可以去浏览 相关所购买的热敏电阻的数据手册,我这里只截取部分作为例子


代码封装(转换成温度输出)
NTC.h
创建NTC.h,写入如下内容
#ifndef __NTC_H__
#define __NTC_H__
// 初始化NTC
void NTC_Initialize();
// 获取温度值
int NTC_get_temperature();
#endif
NTC.c
创建一个NTC.c文件,写入如下内容,请自行将temp_table拷贝进来(因为temp_table较长,我会放在最后面,有需要的话再复制进来这个.c文件中)
#include "NTC.h"
#include "GPIO

本文详细介绍了ADC(模数转换器)的工作原理,包括采样和量化过程,并展示了在医疗设备、音频信号处理和电力系统中的应用场景。特别关注了4096作为基准电压的含义以及如何通过ADC读取并转换模拟信号,以NTC热敏电阻为例,演示了整个数据获取和温度计算的过程。

9976

被折叠的 条评论
为什么被折叠?



