学习目标

  1. 理解模数转换器(ADC)的基本原理和应用场景;
  2. 掌握STC8H中ADC模块的结构和工作原理;
  3. 学会使用STC8H的ADC的电路设计;
  4. 掌握通过编程获取ADC数据
  5. 学会基本的调试策略

    学习内容

    案例介绍

    通过控制滑动变阻器,来观察电压变化。
    image.png

  6. 通过万用表测量 P0.5位置的电压

  7. 通过代码读取出 P0.5位置的电压

    万用表测量

  8. 调整万用表到电压测量位

  9. 正极接P0.5
  10. 负极接GND
  11. 读取值

    ADC概念

    ADC(Analog to Digital Converter 模数转换器)是一种将模拟信号转换为数字信号的电路。在电子系统中,模拟信号常常需要转换为数字信号进行处理和存储。模数转换的基本原理是将模拟信号进行采样,并将采样值量化为数字表示。
  • 采样:是指在一定时间间隔内对模拟信号进行测量,并将测量值存储在数字形式的数据中
  • 量化:是将这些连续的模拟信号值离散化为一系列数字值,通常使用二进制表示。

简单理解,ADC是把模拟信号转换为数字信号的工具,我们可以认为,一个信号有强弱之分,强弱的体现为电压的高低。在数字电路中,只有0和1之分,也就是高电平或低电平。那么体现不了这个强弱。ADC的作用就是体现强弱,精确化的拿到具体的值。
应用场景:

  1. 医疗设备:如心电图、血压计之类。
  2. 音频信号处理:在数字音频处理中,ADC将模拟音频信号转换为数字信号,然后可以进行数字信号处理和存储。
  3. 电力系统:测量电压。

总之,需要知道信号强弱的,需要将模拟信号转为数字信号的都会用到ADC。

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

ADC功能 引脚
ADC0 P1.0
ADC1 P1.1
ADC2 P5.4
ADC3 P1.3
ADC4 P1.4
ADC5 P1.5
ADC6 P1.6
ADC7 P1.7
ADC8 P0.0
ADC9 P0.1
ADC10 P0.2
ADC11 P0.3
ADC12 P0.4
ADC13 P0.5
ADC14 P0.6

代码实现

IO初始化为高阻输入

  1. void GPIO_config(void) {
  2. GPIO_InitTypeDef GPIO_InitStructure; //结构定义
  3. GPIO_InitStructure.Pin = GPIO_Pin_5; //指定要初始化的IO,
  4. GPIO_InitStructure.Mode = GPIO_HighZ; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  5. GPIO_Inilize(GPIO_P0, &GPIO_InitStructure);//初始化
  6. }

ADC配置逻辑

  1. /******************* AD配置函数 *******************/
  2. void ADC_config(void)
  3. {
  4. ADC_InitTypeDef ADC_InitStructure; //结构定义
  5. ADC_InitStructure.ADC_SMPduty = 31; //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
  6. ADC_InitStructure.ADC_CsSetup = 0; //ADC 通道选择时间控制 0(默认),1
  7. ADC_InitStructure.ADC_CsHold = 1; //ADC 通道选择保持时间控制 0,1(默认),2,3
  8. ADC_InitStructure.ADC_Speed = ADC_SPEED_2X1T; //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16T
  9. ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; //ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
  10. ADC_Inilize(&ADC_InitStructure); //初始化
  11. ADC_PowerControl(ENABLE); //ADC电源开关, ENABLE或DISABLE
  12. NVIC_ADC_Init(DISABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  13. }

数据读取与转换

  1. result = Get_ADCResult(ADC_CH13);
  2. v = result * 2.5 / 4096;

芯片基准电压,参考ADC_VRef+引脚,此引脚设计如下:
image.png
ADC为12位精度的,意思是最大值是2的12次方,值为4096.
ADC的这个最大值,表示的是最大测量范围:

  1. 数值最大为4096
  2. 测量的电压值不能超过基准电压
  3. 基准电压对应的值为4096

记住:我们用4096表示基准电压。

以上原理图中,基准电压由 VREF电压决定。这个电路中用到了一个芯片CJ431/CD431,这是一款电压基准芯片,会恒定的输出2.5V电压。
在我们的设计方案中,理论上可以不使用这个电压基准芯片的,直接连接3V3,但是LDO的输出稳定性不够,因此使用电压基准芯片会更为准确。

由以上我们可以得出:

  1. 基准电压为:2.5V
  2. 基准电压对应的数值是4096
  3. 测量的值为ADC引脚
  4. 电压值的计算:

电位器案例(ADC)⭐⭐ - 图3

反向得到电源输入电压

  1. 将ADC_Vref+引脚接到VCC管脚
  2. MCU_Vcc = 4096 * 1.19V / 12位ADC转换结果(CH15)

    练习题

  3. 实现ADC测量电压

  4. 思考ADC电路设计中是否存在问题