找回密码
 立即注册
查看: 201|回复: 9

AI8G1K08A 通过ADC15通道读取VCC供电电压后,无法采集其他ADC通道的问题 | 已解决

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-3 16:30:04 | 显示全部楼层 |阅读模式
根据AI8G1K08A-8pin的数据手册,可以通过15通道先读取供电电压,然后使用计算公式计算外部电压值。
在实际使用时,获取供电电压5v,并进行串口输出。但在测取外部电压时,出现了问题。

代码如下:

#include "stc8.h"
#include "intrins.h"
#include "delay.h"
#include "stdio.h"
#include "string.h"

#define FOSC 11059200UL
#define BRT (65536 - FOSC / 115200 / 4)

//sbit KEY1 = P3^2;

bit         busy;   //等待上一个数据发送完
char         wptr;
char         rptr;  
char         buffer[16];
int         *BGV;

void UartIsr() interrupt 4
{
  if (TI) //发送完之后响应
  {
    TI = 0;
                busy = 0;
  }
  if (RI) //接受完之后响应
  {
    RI = 0;
                buffer[wptr++] = SBUF;
                wptr &= 0x0f;
  }
}
//stc8-8pin 只有串口1
//stc8-20pin 有2个串口
//stc8-48pin 有2~4个串口 芯片型号s2 s4

// from datasheet
// 14.7.2 串口 1 使用定时器 1(模式 0)做波特率发生器
void UartInit()
{  
         SCON = 0x50;
         TMOD = 0x00;
         TL1 = BRT;
         TH1 = BRT >> 8;
         TR1 = 1;
         AUXR = 0x40;//0x41为使用定时器2(使用哪个定时器都不影响正常工作)
         wptr = 0x00;
         rptr = 0x00;
         busy = 0;
}

void UartSend(char dat)
{
   while (busy); //等待上一个数据发送完
   busy = 1;
   SBUF = dat;
}
void UartSendStr(char *p)
{
   while (*p)
   {
     UartSend(*p++);
        }
}

void msg_send(char msg[])
{//发送字符串函数
                int i=0;
                while(msg)
                {
                        SBUF=msg;
                        while(!TI);
                        TI=0;
                        i++;
                }
}

void ADCInit()
{
                P_SW2 |= 0x80;//访问特殊功能寄存器
                 ADCTIM = 0x3f;//设置ADC内部时序
                P_SW2 &= 0x7f;//关闭
                ADCCFG = 0x2f;//数据右对齐,设置工作频率
                ADC_CONTR = 0x83; //P3^3
        //开启,设置P1^0为通道,0x01为P1^1,同理到P1^7//0x8f为内部参考电压
}
//测取内部电压1.19V,基准电压
void ADCInitInside()
{
                P_SW2 |= 0x80;//访问特殊功能寄存器
                ADCTIM = 0x3f;//设置ADC内部时序
                P_SW2 &= 0x7f;//关闭
                ADCCFG = 0x2f;//数据右对齐,设置工作频率
                ADC_CONTR = 0x8f;//开启,设置P1^0为通道0x01为P1^1,同理到P1^7//0x8f为内部参考电压
}

int ADCRead()
{
         int res;
         ADC_CONTR |= 0x40;//启动AD转换
         _nop_();
         _nop_();
         while (!(ADC_CONTR & 0x20)); //检测到转换结束
         ADC_CONTR &= ~0x20;//清标志位
         res = (ADC_RES << 8) | ADC_RESL; //送数据
         return res;
}

//Vx = BGV/resbg*resx;

void main()
{
                int         Vref_res=0;        //供电电压ad值
                int                res=0;                  //外部电压ad值
                int                i=0;                        
                int                vcc=0;                        //参考电压值
                char         disp[15];
                int   V;                                  //外部电压值
                P3M0 = 0x00;
                P3M1 = 0x00;
                P5M0 = 0x00;
                P5M1 = 0x00;
  
                BGV = (int idata *)0xef ;  
        
                UartInit();
                ADCInitInside();
                ES = 1;
                EA = 1;

                while (1)
                {                                                
//                        ADCInitInside();  //供电电压 测取
                        ADC_CONTR = 0x8f;
                        Vref_res = 0;
                        for (i = 0; i < 8; i++) // 平均
                        {
                                Vref_res += ADCRead();
                        }
                        Vref_res >>= 3; // 除以8
                        
                        vcc = (int)(1024L * *BGV / Vref_res);                        
                        sprintf(disp,"vcc:%d mv\r\n",vcc);//以10进制转化为字符串
                        msg_send(disp);
                        delay_ms(500);
                        ADC_CONTR = 0x82;   //p55
//                        ADCInit();                                //测取外部电压
                        res = 0;
                        for (i = 0; i < 8; i++) // 平均
                        {
                                res += ADCRead();
                        }
                        res >>= 3; // 除以8
                        
                        V = vcc/Vref_res*res;
                        sprintf(disp,"外部电压:%d mv\r\n",V);//以10进制转化为字符串
                        msg_send(disp);
                        delay_ms(500);
                        
                }
}


串口打印图

串口打印图
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-3 16:36:25 | 显示全部楼层
在测取完供电电压后,把ADC_CONTR =0x82,切换了adc通道到p32
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-3 16:40:38 | 显示全部楼层
打错了芯片是stc8g1k08a
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:144
  • 最近打卡:2025-07-31 10:37:58

760

主题

1万

回帖

1万

积分

管理员

积分
18139
发表于 2025-7-3 16:57:06 | 显示全部楼层
不同型号,通道选择 不一致
截图202507031657429973.jpg
截图202507031658364374.jpg

截图202507031700054147.jpg

截图202507031657013416.jpg


截图202507031702335762.jpg

截图202507031703217129.jpg

不同型号,通道选择 不一致

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-4 10:00:17 | 显示全部楼层
神*** 发表于 2025-7-3 16:57
不同型号,通道选择 不一致:

我就是根据数据手册选的通道control寄存器0x8f是通道15,内部电压,0x82就是p3^2,
今天可能发现问题了,这个芯片的引脚默认高阻抗输入,
可能是我没有对引脚进行配置,导致无法检测引脚的电压值。

点评

ADC的输入脚本来就要设置为高电平。  详情 回复 发表于 2025-7-4 11:05
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-4 10:03:01 | 显示全部楼层
神*** 发表于 2025-7-3 16:57
不同型号,通道选择 不一致:

上学的时候用的89和12系列,印象里不需要对引脚进行配置,这个芯片突然配置引脚,我就没注意。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-4 10:12:06 | 显示全部楼层
问题总结:STC8G1K08A单片机除P3.0和P3.1外,所有I/O上电均为高阻输入状态。
所以大家必须要先配置I/O模式再去用引脚。
不像之前的所使用用的stc12与stc89系列,印象中这两款是不需要进行这种配置的(距离上一次使用已经过去快5年了)。

以P5^5为例,把引脚配置如下

P5M0&=0xDF;        //P5M0.5=0
P5M1|=0x20;        //P5M1.5=1
寄存器改成ADC_CONTR = 0x85;测取电压就没问题了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-07-31 12:11:20

76

主题

6281

回帖

1万

积分

超级版主

积分
13347
发表于 2025-7-4 11:05:15 | 显示全部楼层
wugo*** 发表于 2025-7-4 10:00
我就是根据数据手册选的通道control寄存器0x8f是通道15,内部电压,0x82就是p3^2,今天可能发现问题了, ...

ADC的输入脚本来就要设置为高电平。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-4 14:43:40 | 显示全部楼层
梁*** 发表于 2025-7-4 11:05
ADC的输入脚本来就要设置为高电平。

技术手册上说需要通过寄存器PnM1.X与PnM0.X设置成输入模式
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2025-07-17 07:52:50
已绑定手机

1

主题

7

回帖

29

积分

新手上路

积分
29
发表于 2025-7-17 07:52:50 | 显示全部楼层
烧录软件就有端口配置,还不需要直接对位计算。
截图202507170752085736.jpg
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-7-31 23:03 , Processed in 0.154840 second(s), 99 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表