AI8G1K08A 通过ADC15通道读取VCC供电电压后,无法采集其他ADC通道的问题 | 已解决
根据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;
int *BGV;
void UartIsr() interrupt 4
{
if (TI) //发送完之后响应
{
TI = 0;
busy = 0;
}
if (RI) //接受完之后响应
{
RI = 0;
buffer = 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;
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);
}
}
在测取完供电电压后,把ADC_CONTR =0x82,切换了adc通道到p32
打错了芯片是stc8g1k08a 不同型号,通道选择 不一致:
不同型号,通道选择 不一致:
神农鼎 发表于 2025-7-3 16:57
不同型号,通道选择 不一致:
我就是根据数据手册选的通道control寄存器0x8f是通道15,内部电压,0x82就是p3^2,
今天可能发现问题了,这个芯片的引脚默认高阻抗输入,
可能是我没有对引脚进行配置,导致无法检测引脚的电压值。
神农鼎 发表于 2025-7-3 16:57
不同型号,通道选择 不一致:
上学的时候用的89和12系列,印象里不需要对引脚进行配置,这个芯片突然配置引脚,我就没注意。 问题总结: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;测取电压就没问题了。
wugoqoht 发表于 2025-7-4 10:00
我就是根据数据手册选的通道control寄存器0x8f是通道15,内部电压,0x82就是p3^2,今天可能发现问题了, ...
ADC的输入脚本来就要设置为高电平。 梁工 发表于 2025-7-4 11:05
ADC的输入脚本来就要设置为高电平。
技术手册上说需要通过寄存器PnM1.X与PnM0.X设置成输入模式 烧录软件就有端口配置,还不需要直接对位计算。
页:
[1]