DYyanfa 2024-03-27 15:44 采纳率: 31.3%
浏览 48

stc8g1k08采集电池电压,计算百分比值异常

stc8g1k08单片机ADC电池电压采集,通过串口发送电池的百分比。目前遇见的问题是使用逻辑分析仪采集串口发送的百分比值不稳定,总是跳变,即采集电压稳定时,用逻辑分析仪采集1秒数据,会有多个数据出现。之前提问的回复尝试了采集也会出现跳变。adc_res的值是稳定正确的,应该是下面百分比计算出问题了。

#define  _ADC_C
#include "ADC.h"
#include "config.h"
#include "Uart.h"

#define ADC_RES_MAX 1024  // ADC采样最大值
#define V_REF (3.3)        // 参考电压为3.3V
#define V_BAT_MAX (2.8)     // 电池最大电压为2.8V
#define V_BAT_MIN (1.8)     // 电池最小电压为1.8V
#define V_BAT_WARN (2.1)    // 电池电量过低警告阈值为2.1V

unsigned int ADC_Value;  // 定义全局变量,用于存储采样结果
void ADC_Init() 
{
    P_SW2 |= 0x80;
    ADCTIM = 0x2A; //设置 ADC 内部时序
    P_SW2 &= 0x7f;
    ADCCFG = 0x20; //设置 ADC 时钟为系统时钟/2,右对齐
    ADC_CONTR = 0x80; //使能 ADC 模块
}

void ADC_ISR() interrupt 5 
{
    ADC_Value = (unsigned int)(ADC_RES << 8) + (unsigned int)ADC_RESL; 
    ADC_CONTR &= ~0x20; //中断标志位清0
}

void ADC_BATTERY() 
{
//    unsigned char battery_percent = 0;  // 定义电量百分比变量
    float adc_res,battery_percent;
    float v_bat;
    ADC_CONTR &= 0xf0;    //底四位清零
    ADC_CONTR |= 0x0C;    //置通道12
    ADC_CONTR |= 0x40;  // 启动ADC转换
    adc_res = (float)ADC_Value * V_REF / ADC_RES_MAX;// 计算ADC被转换通道的输入电压
    v_bat = adc_res * V_BAT_MAX / V_REF;// 计算电池电压值
    battery_percent = (v_bat - V_BAT_MIN)  / (V_BAT_MAX - V_BAT_MIN) * 100.0;// 计算电池电量百分比
    UartSend(adc_res);

  • 写回答

4条回答 默认 最新

  • 专家-皆知 2024-03-27 15:44
    关注

    引自免费微信小程序:皆我百晓生

    首先,我建议您检查以下几点来解决您的问题:

    1. 确保ADC采样速率足够快,以捕捉到电池电压的跳变。您可以尝试增加ADC转换的采样时间,例如将ADCTIM设置为更高的值。

    2. 检查ADC转换的通道选择是否正确。您在ADC_CONTR中设置了通道12,但您没有设置通道选择寄存器。通道选择的正确性对ADC转换的结果有很大影响。

    3. 检查串口通信是否正常。您的程序通过串口发送ADC值,因此需要确保串口通信正常。您可以尝试在串口发送ADC值时添加打印语句,以查看ADC值是否正确。

    4. 检查电池电压范围是否在允许的范围内。如果电池电压过低或过高,可能会影响ADC转换的结果。

    5. 检查代码中可能存在的错误。代码中有一些语法错误,例如ADC_RES应该是ADC_RESL。请检查并修复这些错误。

    以下是一个修改后的代码示例,以帮助您解决问题:

    #define _ADC_C
    #include "ADC.h"
    #include "config.h"
    #include "Uart.h"
    
    #define ADC_RES_MAX 1024  // ADC采样最大值
    #define V_REF (3.3)        // 参考电压为3.3V
    #define V_BAT_MAX (2.8)     // 电池最大电压为2.8V
    #define V_BAT_MIN (1.8)     // 电池最小电压为1.8V
    #define V_BAT_WARN (2.1)    // 电池电量过低警告阈值为2.1V
    
    unsigned int ADC_Value;  // 定义全局变量,用于存储采样结果
    unsigned char channel = 12; // 通道选择,1-11
    
    void ADC_Init() 
    {
        P_SW2 |= 0x80;
        ADCTIM = 0x2A; //设置 ADC 内部时序
        P_SW2 &= 0x7f;
        ADCCFG = 0x20; //设置 ADC 时钟为系统时钟/2,右对齐
        ADC_CONTR = 0x80; //使能 ADC 模块
    }
    
    void ADC_ISR() interrupt 5 
    {
        ADC_Value = (unsigned int)(ADC_RES << 8) + (unsigned int)ADC_RESL; 
        ADC_CONTR &= ~0x20; //中断标志位清0
    }
    
    void ADC_BATTERY() 
    {
        float adc_res,battery_percent;
        float v_bat;
        ADC_CONTR &= 0xf0;    //底四位清零
        ADC_CONTR |= 0x0C;    //置通道12
        ADC_CONTR |= 0x40;  // 启动ADC转换
        adc_res = (float)ADC_Value * V_REF / ADC_RES_MAX;// 计算ADC被转换通道的输入电压
        v_bat = adc_res * V_BAT_MAX / V_REF;// 计算电池电压值
        battery_percent = (v_bat - V_BAT_MIN)  / (V_BAT_MAX - V_BAT_MIN) * 100.0;// 计算电池电量百分比
        UartSend(adc_res);
        UartSend(battery_percent);
    }
    

    请注意,这个示例将ADC采样通道设置为通道12,并直接发送ADC值和电池电量百分比。您可能需要根据您的实际硬件和需求进行调整。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月27日

悬赏问题

  • ¥15 iE 浏览器不能访问 oracle secure global server, google 浏览器可以
  • ¥50 Namuru2007_Baseband_Verilog代码疑点
  • ¥15 复杂公式求最值问题,含有多个符号常量
  • ¥15 Qt移植后在开发板上无法运行
  • ¥15 关于STID337-32D15YB开发板LINUX调试
  • ¥15 有没有熟悉自动化点胶设备,有个加密狗,想复制一份软件到另个设备
  • ¥15 mysql 部分截取字符串
  • ¥20 只有一个C盘,磁盘管理分区
  • ¥15 PVE8.2版本ceph的监控项状态stopped不能销毁
  • ¥15 如何加快视频观看速度?