- 打卡等级:初来乍到
- 打卡总天数:9
- 最近打卡:2025-07-29 19:51:44
已绑定手机
注册会员
- 积分
- 87
|
发表于 2025-7-14 08:59:34
|
显示全部楼层
AI8H1K08-QFN20芯片ADC一但通过内部1.19V测量供电电压时原本正常的P1.0电压就不正常
AI8H1K08-QFN20芯片ADC一但通过内部1.19V测量供电电压时原本正常的P1.0电压就不正常,为什么呢?
在没有通过1.19V测量芯片供电电压时,P1.0-ADC0采集的电压正常(ADC0-P1.0参考电压为电源5.09V通过串口1发送电压数据显示OK)
硬件连接:
芯片采用AI8H1K08-QFN20
芯片供电采用USB供电,测量芯片供电电压为5.09V
芯片的6脚ADC_VRef+和供电VCC 5脚接在一起。
芯片的16脚也就是P1.0(ADC0通道)通过电位器中心脚连接到芯片供电
调节电位器P1.0脚电压会变化,通过串口1进行打印输出,在没有加测量
(Read_VCC()//读取芯片供电VCC) 函数时P1.0电压变化正,常用万用表测量
电压与串口打印数据基本一致(串口1接的数据是03DE=990 万用表测量为:0.99V BCCC=3020 3.02V)
说明P1.0的ADC转换电压正确
为什么在加入 (Read_VCC()//读取芯片供电VCC 函数是就不正常了?
在加入 (Read_VCC()//读取芯片供电VCC 函数时P1.0 ADC 电压就不正确了?
但是这个 (Read_VCC()//读取芯片供电VCC 函数读取的芯片供电电压又是正常的,为什么呢?
完整程序:
#include<AI8H.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
int *BGV;
int VCC,resMCU;
bit B_TX_Busy = 0; //发送忙标志
static char time_cous=0;
bit Time_flag=0;
bit Send_flag=0;
float res=0,Volate=0;
uint ADD=0;
sbit led1=P3^6;
sbit led2=P3^5;
//*********************************************
void Delay10ms(void) //@24.000MHz
{
unsigned char data i, j, k;
i = 2;
j = 56;
k = 172;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//*********************************************
void port_init()
{
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x0E;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
P6M0 = 0x00;
P6M1 = 0x00;
}
//*********************************************
void Timer0_Init(void) //10毫秒@24.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xE0; //设置定时初始值
TH0 = 0xB1; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
//*********************************************
void Uart1_Init(void) //9600bps@24.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x8F; //设置定时初始值
T2H = 0xFD; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
}
//*********************************************
void Uart1SendData(uchar ch)
{
while(B_TX_Busy); //不忙后发送数据
SBUF = ch; //写数据到UART数据寄存器
B_TX_Busy = 1;
}
//*********************************************
void Uart1_Isr(void) interrupt 4
{
if (TI) //检测串口1发送中断
{
TI = 0; //清除串口1发送中断请求位
B_TX_Busy = 0;
}
if (RI) //检测串口1接收中断
{
RI = 0; //清除串口1接收中断请求位
}
}
//*********************************************
void Timer0_Isr(void) interrupt 1
{//10ms
time_cous++;
if(time_cous>99)//100*10=1000ms=1s
{
time_cous=0;
Time_flag=!Time_flag;
Send_flag=1;
}
}
//*********************************************
void ADC_init()
{
P1M0 = 0x00; //设置P1.0为ADC口
P1M1 = 0x01;
P_SW2 |= 0x80;
ADCTIM = 0x3f; //设置ADC内部时序
P_SW2 &= 0x7f;
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16 OF
ADC_CONTR = 0x80; //使能ADC模块
}
//*********************************************
uint ADC_aul()
{
uint result;
ADC_CONTR |= 0x40; //启动AD转换
_nop_();
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
result=(ADC_RES << 8) | ADC_RESL; //读取ADC结果--ADCCFG = 0x2f;
// result = (ADC_RES << 2) | (ADC_RESL & 0x03); //组合10位结果 --ADCCFG = 0x0f;
return result;
}
//*********************************************
void adc_Volate()
{
char i=0;
res = 0;
for (i=0; i<8; i++)
{
res += ADC_aul(); //读取8次数据
}
res /=8; //取平均值
Volate=(res * 5.09) / 1023.0; // 计算实际电压值
ADD=Volate*1000;
}
//*********************************************
int ADCRead()//芯片VCC
{
int resX;
// ADC_CONTR|=0x40; //启动转换 芯片VCC-OK
ADC_CONTR|=0x4F; //启动转换 不管是40还是4F测量的芯片供电电压都正确
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&0x20)); //查询ADC完成标志
ADC_CONTR&=~0x20; //清完成标志
resX=(ADC_RES<<8)|ADC_RESL;
return resX;
}
//*********************************************
void Read_VCC() //读取芯片供电VCC
{
char i=0;
resMCU=0;
for(i=0;i<8;i++)
{
resMCU+=ADCRead();
}
resMCU>>=3; //8次
VCC=(int)(1024L* *BGV/resMCU); //获取电池电压--测量是4.24,万用表测量是4.21 OK
}
void main()
{
Delay10ms();
port_init();
Timer0_Init(); //10毫秒@24.000MHz
Uart1_Init(); //9600bps@24.000MHz
EA=1;
ADC_init();
BGV=(int idata*)0xef; //读取内部1.19V电压
while(1)
{
if(Send_flag==1)
{
Send_flag=0;
Uart1SendData(33); //串口1发送33 测试串口1用 OK
Uart1SendData(*BGV >> 8); //串口1发送内部1.19V参考信号源的高字节 OK
Uart1SendData(*BGV); //串口1发送内部1.19V参考信号源的低字节 OK
adc_Volate(); //读取P1.0-ADC0通道电压 OK
Uart1SendData( ADD >> 8); //03
Uart1SendData( ADD); //DE 串口1接的数据是03DE=990 万用表测量为:0.99V BCCC=3020 3.02V
Read_VCC(); //读取芯片供电VCC--加入这个函数ADC0-P1.0的数据就不正常
//但是读电池电压的值正常,也就是这个功能会影响到其他ADC通道测量
Uart1SendData(VCC >> 8); //串口1发送芯片供电VCC的高字节 ok
Uart1SendData(VCC); //串口1发送芯片供电VCC的低字节 ok
}
}
}
|
|