中国平安金融集团面试:关于用51单片机和ADC0809做电压表的问题

来源:百度文库 编辑:查人人中国名人网 时间:2024/04/27 21:33:37
/****************************/
/*Head files*/
/************************/
#include"reg51.h"
#include"absacc.h"
/***********************/
#define c8279 XBYTE[0x0fff] /*8279控制字寄存器地址*/
#define d8279 XBYTE[0x0ffe] /*8279数据地址*/
#define ch0 XBYTE[0x2ff8] /*ADC地址*/
#define uchar unsigned char
#define uint unsigned int
sbit E=P3^2;
/*******************************/
uint disdat[8]; /*定义一个数组作为显示单元*/
uchar nokey;
uint LedCode[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f, /*0,1,2,3,4,5,6,7,8,9*/
0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d,0x76,0x40,0x00}; /*A,B,C,D,E,F,G,H,-,hide*//*段码表*/
uchar keyval[]={0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38, /*0,1,2,3,4,5,6,7*/
0x01,0x09,0x11,0x19,0x21,0x29,0x31,0x39}; /*7,8,9,A,B,C,D,E,F*//*键值表*/
/*****************************/
/*函数声明*/
/********************/
void Init8279(void); /*8279 Init*/
void Display(void); /*display*/
uchar ReadKey(void); /*ReadKey*/
void Delay(uint); /*delay*/
/*****************************************/
/*主函数*/
/**************************************/
void main(void)
{
int v;
float v0=0.0;
Init8279();
while(1)
{
ch0=0;
Delay(128);
while(E==0);
v=ch0;
v0=(float)5*v/255;
v0=1000*v0;
disdat[0]=0x13; /*显示单元赋值*/
disdat[1]=0x13;
disdat[2]=0x13;
disdat[3]=0x13;
disdat[4]=(int)v0/1000;
disdat[5]=(int)v0%1000/100;
disdat[6]=(int)v0%1000%100/10;
disdat[7]=(int)v0%1000%100%10;
Display();
Delay(60000);
}
}
/**************************************/
void Init8279(void)
{
c8279=0x00; /* set 8279 工作方式8x8字符显示;左边输入;双键互锁 */
c8279=0x2a; /* set 8279 分频系数 */
c8279=0xd1; /* clear 8279 */
while(c8279 & 0x80);
}
/******************* 读键值函数 ************/
uchar ReadKey(void)
{
uchar i,j,m;
m=c8279&0x0f; /*读取按键ram看是否有键按下*/
if(m==0)
return(nokey); /*no key is pressed*/
else
{
c8279=0x40; /* read 8279 FIFO */
i=d8279; /* i=keyval */
i&=0x3f;
for(j=0;j<16;j++)
{
if(i!=keyval[j]); /*程序查表算法*/
else return(j);
}
}
}
/*********************************************/
void Display(void)
{
uint i;
for(i=0;i<8;i++)
{
c8279=0x80+i;
d8279=LedCode[disdat[i]];
}
}
/*******************************************/
void Delay(uint t)
{
while(--t);
}
/***

请各位帮看一下有什么问题啊
地址和显示部分没问题
转换有问题
不能正确转换
比如给0V它会转换成1~3
给5V它转换成3~5
中间基本也是这样
而且每次转换跳动很大
但出现的数值不多
这是第4天了
这四天没干别的
上网查资料
检查电路
要疯了

硬件有问题
P0口数据应该不对
或者看一下你用的573或373

哈哈,我不知道!

不太明白"不能正确转换"是什么意思.
检查硬件电路,尤其是ADC0809的接口.
使用稳定的输入信号检查转换结果是否稳定.如果能跟随输入信号变化,说明逻辑电路没问题,故障在模拟电路.如果不跟随输入而变化说明逻辑电路或者程序有问题.

我觉得是读回数据时出错,问题在这段:::
ch0=0;
Delay(128);
while(E==0);
v=ch0;

问题:
1:Delay(128);试试加长延时。12M晶振下(128)相当于128uS,0809转换时间为100uS,要是你用24M晶振就会出问题,为了保险加大到1000左右
2:不要用等待中断,(while(E==0); 用法不太对),加大延时后直接读回数据就行了