ADC 读不到电压 | 已解决
型号:STC8G1K08A-8Pin测试仪器:P33/P54/P55脚分别接可调电源(已共地),输入0~5V
代码:用例程改的
#include "reg51.h"
#include "intrins.h"
#include <stdio.h>//printf, sprintf
#include <intrins.h>//_nop_, _cror_, _crol_
typedef unsigned char u8;//0 to 255
typedef unsigned int u16;//0 to 65535
typedef unsigned long u32;//0 to 4294967295
//测试工作频率为11.0592MHz
sfr AUXR = 0x8e;
sfr ADC_CONTR = 0xbc;
sfr ADC_RES = 0xbd;
sfr ADC_RESL = 0xbe;
sfr ADCCFG = 0xde;
sfr P3M0 = 0xb2; //P3口配置寄存器0
sfr P3M1 = 0xb1; //P3口配置寄存器1
sfr P5M0 = 0xca; //P5口配置寄存器0
sfr P5M1 = 0xc9; //P5口配置寄存器1
bit Busy = 0;
void Uart1_Isr(void) interrupt 4
{
if (TI) //检测串口1发送中断
{
TI = 0; //清除串口1发送中断请求位
Busy = 0;
}
if (RI) //检测串口1接收中断
{
RI = 0; //清除串口1接收中断请求位
}
}
u8 putchar(u8 dat)
{
Busy = 1;
SBUF = dat;
while(Busy);
return dat;
}
void Uart1_Init(void) //115200bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xE8; //设置定时初始值
TH1 = 0xFF; //设置定时初始值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
ES = 1; //使能串口1中断
}
void Delay1000ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
i = 17;
j = 27;
k = 112;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay1ms(void) //@11.0592MHz
{
unsigned char data i, j;
i = 15;
j = 90;
do
{
while (--j);
} while (--i);
}
u16 Temp;
u16 Cnt = 0;
void main()
{
P3M0 = 0x00; P3M1 = 0x0c;
P5M0 = 0x00; P5M1 = 0x10;
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16/16
Uart1_Init();
EA=1;
ADC_CONTR = 0x82; //使能ADC模块
Delay1ms();
while (1)
{
Cnt++;
printf("ADC Test: %u\r\n",Cnt);
Delay1ms();
ADC_CONTR |= 0x42; //启动AD转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
Temp = ADC_RES; //读取ADC结果
Temp = Temp<<8 | ADC_RESL;
printf("P32 Raw: %u\r\n",Temp);
printf("P32 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
Delay1ms();
ADC_CONTR |= 0x43; //启动AD转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
Temp = ADC_RES; //读取ADC结果
Temp = Temp<<8 | ADC_RESL;
printf("P33 Raw: %u\r\n",Temp);
printf("P33 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
Delay1ms();
ADC_CONTR |= 0x44; //启动AD转换
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
Temp = ADC_RES; //读取ADC结果
Temp = Temp<<8 | ADC_RESL;
printf("P54 Raw: %u\r\n",Temp);
printf("P54 Volt: %lu x10mV\r\n",(u32)Temp*500/1024);
Delay1000ms();
}
}
现象
确定芯片型号后面有带“A”?
确保是 STC8G1K08A-36I-SOP8, 有ADC
====STC8G1K08-36I-SOP8, 无ADC
乘风飞扬 发表于 2024-5-23 19:08
确定芯片型号后面有带“A”?
确定 神农鼎 发表于 2024-5-23 19:14
确保是 STC8G1K08A-36I-SOP8, 有ADC
====STC8G1K08-36I-SOP8, 无ADC
确定 我猜想一下,第一次读取的时候 是不是只有前两路是正确的,,,从第二次开始就都不正确了? /************* 功能说明 **************
用户请先别修改程序, 直接下载"02-5路ADC转换-BandGap-串口1(P3.1)返回结果-C语言"里的"ADC.hex"测试. 下载时选择主频11.0592MHZ。
测试时, 电脑的串口助手设置115200,8,n,1.
本程序演示4路ADC(P3.0 P3.2 P3.3 P5.4 P5.5)和bandgap查询采样,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.
0~3通道对应P3.0~P3.3, 4通道-->P5.4, 5通道-->P5.5, 15通道为内部1.19V基准电压做输入的ADC值.
初始化时先把要ADC转换的引脚设置为高阻输入.
ADC模块是一个硬件模块, 由ADC时钟驱动, 一旦触发ADC转换, 硬件会在ADC时钟驱动下自动完成.
CLK为ADC时钟, 是系统时钟的SysClk/2/(n+1)分频, ADC转换由下列操作完成:
通道选择时间 1或2个CLK (默认1)
通道选择保持时间 1~4个CLK (默认2)
模拟信号采样时间 1~32个CLK (默认11)
ADC转换时间 10个CLK(固定).
******************************************/
第一次采集的是ADC2,第二次采集的是ADC3,第三次采集的是ADC7,往后每一次采集的都是ADC7 _奶咖君_ 发表于 2024-5-24 11:01
我猜想一下,第一次读取的时候 是不是只有前两路是正确的,,,从第二次开始就都不正确了? ...
对头!! 梁工 发表于 2024-5-24 11:12
/************* 功能说明 **************
用户请先别修改程序, 直接下载"02-5路ADC转换-Band ...
然后呢?