liming 发表于 2023-6-13 20:42:36

单独运行ADC电压采集代码无电压时输出0,和获取内部1.19V的代码一起运行就会输出161

   STC8H4K64TLCD单独运行ADC12电压采集数值这部分代码,串口助手显示正常为0。当先获取内部1.19V电压代码和运行ADC电压采集代码一起时运行,ADC通道无电压也会输出161的数值。
#include <STC8H.h>
#include <intrins.h>
#include <stdio.h>

void Delay1000ms()                //@11.0592MHz
{
        unsigned char data i, j, k;
        i = 57;
        j = 27;
        k = 112;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void UartInit(void)//9600bps@11.0592MHz
{
               SCON = 0x50;//8位数据,可变波特率
        AUXR |= 0x40;//定时器1时钟为FOSC,就是1T
          AUXR &= 0xFE;//串口1选择定时器1为波特率发生器
                TMOD &= 0x0F;//设定定时器1为16位重装载方式
                  TL1 = 0xE0;//设定定时器低位值
                TH1 = 0xFE ;//设定定时器高位值
           ET1 = 0;//禁止定时器1中断
                  TR1 = 1;//启动定时器1
}

void Uart1_SendChar(unsigned char Udat)
{
    SBUF = Udat;//串口1数据寄存器
    while(!TI);//串口1中断发送请求标志
    TI = 0;   
}

char putchar(char c)
{
    Uart1_SendChar(c);
                return c;
}       

                      unsigned        int xinpianneibiaoya,ADC_celiangdianya;
void main()
{
                  P0M0 = 0x00; P0M1 = 0x10; //设置P0.4(47引脚)ADC测量的引脚为高阻输入模式
                                                while(1)
                                               {
                                                                               /************************内部电压采集*************************/                                                                                                                                       
                                                                                                        UartInit();
                                                                                                                        EA = 1;
                                                                                                P_SW2 = 0x80;//当需要访问XFR寄存器时,必须先将寄存器的B7位置EAXFR置1,才能对XFR 进行正常的读写操作。                                                       
                                                                                                                        xinpianneibiaoya = ((int)CHIPID7<<8) + CHIPID8;
                                                                                                                       printf("芯片内部标压%02u\r\n", xinpianneibiaoya);        //测量结果显示至串口助手显示出来,显示输出的单位为(mV)毫伏。
                                                                                                                       Delay1000ms();                                                       
                                                                                        /***********************外部电压采集基数**************************/
                                                                                        P_SW2 |= 0x80; //使能访问XFR特殊寄存器                                               
                                                                                        ADCTIM = 0x3f; //设置ADC 内部时序
                                                                                        ADCCFG = 0x2f; //设置ADC 时钟为系统时钟/2/16
                                                                                        ADC_CONTR = 0x8c; //开启ADC测量功能,设置第12通道为ADC测量作用
                                                                                        UartInit();                                                                                               
                                                                                                        ADC_CONTR = 0xcc; //启动AD 转换
                                                                                                        _nop_();//延时1微秒
                                                                                                        _nop_();//延时1微秒
                                                                                                        while (!(ADC_CONTR & 0x20)); //查询ADC 完成标志                                                       
                                                                                                        ADC_CONTR &= ~0x20; //清完成标志
                                                                                                        printf("采集外部的ADC信息为%02u\r\n",ADC_RES); //读取ADC 测量结果显示至串口助手显示出来,打印输出的单位为(mV)毫伏。
                                                                                                Delay1000ms();       
                                        //            /******************电压测量计算**********************/
                                        //      ADC_celiangdianya = xinpianneibiaoya / ADC_RES * 4096;//根据MCU手册查询公式得知,外部的ADC电压=4096*内部标压/外部电压采集基数
                                        //                       UartInit();
                                        //      printf("测得外部的ADC电压为%02u\r\n",ADC_celiangdianya);
                }
}

神农鼎 发表于 2023-6-13 21:29:25

将原理图的PDF贴上来

liming 发表于 2023-6-13 22:07:07

原理图

liming 发表于 2023-6-13 22:09:42

串口助手显示内容

liming 发表于 2023-6-13 22:12:51

测量1节5号电池的电压串口助手显示结果

liming 发表于 2023-6-13 22:17:40

把获取芯片内部1.19V的电压代码注释掉,接入1节5号电池,串口助手输出以下结果:

乘风飞扬 发表于 2023-6-14 18:16:22

本帖最后由 乘风飞扬 于 2023-6-14 18:18 编辑

liming 发表于 2023-6-13 22:17
把获取芯片内部1.19V的电压代码注释掉,接入1节5号电池,串口助手输出以下结果: ...代码我稍微整理测试了一下,采集结果基本正常,主要修改以下部分,其它内容不变:
unsigned int xinpianneibiaoya,ADC_Result;
float ADC_celiangdianya;
void main()
{
    P_SW2 = 0x80;//当需要访问XFR寄存器时,必须先将寄存器的B7位置EAXFR置1,才能对XFR 进行正常的读写操作。                                                      
    P0M0 = 0x00; P0M1 = 0x10; //设置P0.4(47引脚)ADC测量的引脚为高阻输入模式

    ADCTIM = 0x3f; //设置ADC 内部时序
    ADCCFG = 0x2f; //设置ADC 时钟为系统时钟/2/16
    ADC_CONTR = 0x8c; //开启ADC测量功能,设置第12通道为ADC测量作用
    UartInit();
    EA = 1;
    while(1)
    {
      Delay1000ms();      
      /************************内部电压采集*************************/                                                                                                                                       
      xinpianneibiaoya = ((int)CHIPID7<<8) + CHIPID8;
      printf("芯片内部标压%02umV\r\n", xinpianneibiaoya);      //测量结果显示至串口助手显示出来,显示输出的单位为(mV)毫伏。
      /***********************外部电压采集基数**************************/
      ADC_CONTR = 0xcf; //启动AD 转换
      _nop_();//延时1微秒
      _nop_();//延时1微秒
      while (!(ADC_CONTR & 0x20)); //查询ADC 完成标志                                                      
      ADC_CONTR &= ~0x20; //清完成标志
      ADC_Result = ((unsigned int)ADC_RES << 8) + ADC_RESL;
      printf("采集内部通道的ADC值为%02u\r\n",ADC_Result); //读取ADC 测量结果显示至串口助手显示出来。
//      printf("采集外部的ADC信息为%02bu\r\n",ADC_RES); //读取ADC 测量结果显示至串口助手显示出来,打印输出的单位为(mV)毫伏。
      /******************电压测量计算**********************/
      ADC_celiangdianya = (float)xinpianneibiaoya / ADC_Result * 4096;//根据MCU手册查询公式得知,外部的ADC电压=4096*内部标压/外部电压采集基数
      printf("测得外部的ADC电压为%fmV\r\n",ADC_celiangdianya);
    }
}实测结果如下:


另外,keil C51使用printf打印不同类型的数据需要指定数据宽度
(1)b 八位(2)h 十六位(默认)(3)l 三十二位
例如:
%bd输出8位 十进制有符号整数
%hx 或者 %x输出16位 十六进制整数
%lx输出32位 十六进制整数
页: [1]
查看完整版本: 单独运行ADC电压采集代码无电压时输出0,和获取内部1.19V的代码一起运行就会输出161