首页 > 其他分享 >【STC8H】使用ADC第15通道测量外部电压及电池电压详解

【STC8H】使用ADC第15通道测量外部电压及电池电压详解

时间:2024-10-25 20:45:47浏览次数:1  
标签:设置 15 ms void 1.19 STC8H ADC 电压

 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

相关文章

  • 大数据-154 Apache Druid 架构与原理详解 基础架构、架构演进
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(已更完)Kudu(已更完)Druid(正在更新…)章节内容上节我们完成了如下的内容:Apa......
  • 【vue】15.组件通信的方式(一)props、emits、v-model
    Vue组件通信指的是在Vue.js应用程序中,不同组件之间传递数据和信息的过程。在一个项目中,通常有很多个组件,其中每个组件都是独立的实例,都拥有自己的状态和方法。因此,为了构建复杂的应用,组件之间需要能够互相传递数据和信息,也就是进行组件通信,接下来的几篇内容将对vue组件通信......
  • 负电压存在的意义与作用是什么
    负电压存在的意义与作用:1.提供电路中电子流动的方向;2.实现半导体器件的正常工作;3.用于直流电源的极性标识;4.在特定电路中实现信号的放大和处理;5.在直流电机中产生反向磁场;6.在直流电源中提供双极性电压。负电压在电路中起到了定义电流方向的关键作用。1.提供电路中电子......
  • 题解:SP25334 NPC2015A - Eefun Guessing Words
    涉及知识点:字符串处理。解题思路记录每个字符出现的第$1$个位置和最后$1$个位置,询问时比较大小即可。代码#include<bits/stdc++.h>//#defineintlonglong#definell__int128#definedbdouble#defineldblongdouble#definevovoid#defineendl'\n'#defin......
  • adg通过增量恢复后,tempfile报错ORA-01157
    源端是oracle11.2.0.4rac+asm,目标端单机+fs由于断电故障,adg长时间无人维护,GAP归档缺失,采用增量恢复的方式恢复完成。备库open后报如下错误:处理办法:由于备库只有一个临时文件,所以需在备库添加一个新的临时文件,然后删掉报错的临时文件即可。SQL>!mkdir-p/oradata/orcl/t......
  • 【leetcode-面试经典 150 题】-4.删除有序数组中的重复项 II
    题目:给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用O(1)额外空间的条件下完成。示例1:输入:nums=[1,1,1,2,2,3]输出:5,nums=......
  • 【leetcode-面试经典 150 题】-1.合并两个有序数组
    题目:给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 ......
  • 150份Java计算机毕业设计项目推荐(源码+论文+PPT)
    2024最新Java项目选题推荐哈喽,大家好,大四的同学马上要开始做毕业设计了,大家做好准备了吗?博主给大家详细整理了150个Java项目选题推荐,有什么疑问可在评论区留言哦!需要链接请私信我哦!或者在评论区打出来!02:基于Java+springboot的报名系统03:基于Java+springboot的培训管理系统......
  • JavaWeb合集15-线程局部变量ThreadLocal
    十五、ThreadLocalThreadLocal并不是一个Thread,,而是Thread的局部变量。ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。场景:通过过滤器/过滤器获取到JWT,可将JWT值存储到ThreadLocal中,当执行到需要JWT的......
  • 代码随想录算法训练营第九天|leetcode151.翻转字符串里的单词、卡码网55.右旋字符串
    1leetcode151.翻转字符串里的单词题目链接:151.反转字符串中的单词-力扣(LeetCode)文章链接:代码随想录视频链接:字符串复杂操作拿捏了!|LeetCode:151.翻转字符串里的单词_哔哩哔哩_bilibili自己的思路:直接将空格去掉,然后分割字符串为列表,在列表中进行翻转,不在字符串内部操作,......