STC8H 系列 ADC 的第 15 通道用于测量内部参考信号源,由于内部参考信号源很稳定,约为 1.19V, 且不会随芯片的工作电压的改变而变化,所以可以通过测量内部 1.19V 参考信号源,然后通过 ADC 的 值便可反推出外部电压或外部电池电压。以下是如何设置和读取 ADC 第 15 通道的详细步骤:
1. 硬件连接
确保你要测量的电压信号(如外部电压或电池电压)通过适当的电路连接到 ADC 输入引脚。对于 STC8H 单片机,ADC 第 15 通道通常连接到外部电压输入引脚。
2. 配置 ADC
2.1 启用 ADC 功能
首先,你需要在单片机的初始化代码中启用 ADC 功能。通常在 STC8H 系列单片机中,这涉及到设置相关的寄存器
// 假设使用 STC8H 的标准库函数或自定义函数
void ADC_Init(void) {
// 使能 ADC 模块
ADCCFG |= 0x01; // 开启 ADC 功能,具体寄存器设置请查阅数据手册
}
2.2 配置 ADC 输入通道
选择 ADC 第 15 通道作为输入源。通常可以通过设置 ADC 通道选择寄存器来完成这一操作。
void ADC_SetChannel(uint8_t channel) {
// 选择 ADC 通道
ADCCON |= (channel & 0x0F); // 设置通道编号,具体寄存器设置请查阅数据手册
}
2.3 配置 ADC 转换参数
设置 ADC 的采样精度、参考电压等参数,以确保测量精度和范围。
void ADC_Config(void) {
ADCCON |= 0x40; // 设置为 12 位分辨率,具体设置请查阅数据手册
}
3. 启动 ADC 转换
启动 ADC 转换并等待转换完成。ADC 转换可以通过软件触发,也可以通过硬件触发。以下是软件触发的例子:
uint16_t ADC_Read(void) {
// 启动 ADC 转换
ADCCON |= 0x80; // 开始转换,具体寄存器设置请查阅数据手册
// 等待转换完成
while (!(ADCCON & 0x08)); // 等待完成标志位,具体设置请查阅数据手册
// 读取结果
uint16_t result = (ADCH << 8) | ADCL; // 读取结果寄存器,具体寄存器设置请查阅数据手册
return result;
}
4. 计算实际电压
ADC 输出值需要转换成实际电压值。计算电压值的公式通常是:
5. 完整示例代码
main.c
#include "STC8.h"
#include "Headers.h"
#define MAIN_Fosc 24000000L //定义主时钟
/========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-3
// 备注:
//========================================================================
void delay_ms(int ms)
{
u16 i;
do{
i = MAIN_Fosc / 10000;
while(--i); //10T per loop
}while(--ms);
}
void ADCInit()
{
ADCTIM = 0x3f; //设置 ADC 内部时序,ADC采样时间建议设最大值
ADCCFG = 0x2f; //设置 ADC 时钟为系统时钟/2/16
ADC_CONTR = 0x80; //使能 ADC 模块
}
u16 ADCRead(int channel)
{
ADC_RES = 0;
ADC_RESL = 0;
ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel; //启动 AD 转换
_nop_();
_nop_();
_nop_();
_nop_();
while((ADC_CONTR & 0x20) == 0) ; //wait for ADC finish
ADC_CONTR &= ~0x20; //清除ADC结束标志
return (((u16)ADC_RES << 8) | ADC_RESL);
}
void main(void)
{
float vcc=0.00;
u16 res;
u8 i;
Uart1_Init(9600); //[email protected]
ADCInit();
while(1)
{
ADCRead(15);
ADCRead(15); //前两个数据建议丢弃
res = 0;
for (i=0; i<8; i++)
{
res += ADCRead(15); //读取 8 次数据
}
res >>= 3; //取平均值
vcc = (4096L * 1.19 / res); //(12 位 ADC 算法)计算 VREF 管脚电压,即电池电压
printf("ADC_convert:%g mV \r\n", vcc);
delay_ms(500);
}
}
6、测试结果
由于没有读取内部基准电压结果会有一点小误差。实际值2.76V,ADC测量的外部电压为2.79V。需要更高精度的可以把代码 vcc = (4096L * 1.19 / res);
里的 1.19换成 ,读取内部 1.19V 参考信号源-BGV 值。具体可以研究一下手册(注:我使用BGV失败了,*BGV的数值一直是0,原因不明)
下载的时候可以看到参考电压的数值,如果不是偏离太大,那么直接用1.19代替BGV就可以。
标签:设置,15,ms,void,1.19,STC8H,ADC,电压 From: https://www.cnblogs.com/FBsharl/p/18503217