环境:
Proteus 8.7
使用proteus读取ADC0809数据时,数据会跳变,大小变化也不一致。
查了程序,时序没有问题。
最终发现是数据口接反了,数据口在手册中的定义为:
21号脚为MSB,需要接到GPIO的高位引脚上。
调整引脚后,读取数据就变为正常了。贴上原理图和源代码。
程序代码(PROTEUS 6.7调试通过)
#include <reg51.h> //头文件
#define uchar unsigned char //宏定义无符号字符型
#define uint unsigned int //宏定义无符号整型
code uchar seg7code[10]= { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //显示段码
sbit ST=P3^0; //A/D启动转换信号
sbit OE=P3^1; //数据输出允许信号
sbit EOC=P3^2; //A/D转换结束信号
sbit ALE=P3^3; //时钟脉冲
void delay(uchar t)
{
while(t--);
}
//在第N位显示num数据,是否带点显示
void seg_disp(uchar n,uchar num,uchar dot)
{
P0=0XFF;
P2=0xff&(~(0x01<<(n+4)));//选择位
P0=seg7code[num]&(0xff&(~(dot<<7)));
delay(100);
}
void disp(uint num)
{
seg_disp(0,num/1000,1);//显示千位,带点
seg_disp(1,num%1000/100,0);//显示百位
seg_disp(2,num%100/10,0);//显示十位
seg_disp(3,num%100,0);//显示各位
}
uint read_ADC0809(void)
{
uint ADC_Value;
OE=0; //开始采集,按照ADC0809手册时序
ST=0;
ALE=0;
ALE=1;
ST=1;//开始数据转换
ALE=0;
ST=0; //停止数据转换
delay(10);
while(!EOC); //等待数据转换完毕
OE=1; //允许数据输出信号
ADC_Value=P1; //读取数据
OE=0; //关闭数据输出允许信号
return ADC_Value;
}
void main()
{
while(1)
{
disp(read_ADC0809()*20); //数码管显示函数,数字量转换为电压需要乘以20.实际应该乘以19.6
}
}