咱们的ADC0809电压表
第一次和同学合作的学校课题:ADC0809电压表,以实物失败,仿真成功告终。相信以后回头看,会发现许多地方非常的不专业,特发此博文,以后当笑话看。不过因为是第一次接触AD相关知识,也学到了挺多。
系统软件设计要求:
(1) 键盘管理程序(包括键扫描、键处理程序)。
(2) LED动态显示程序,包括:
(3) 各通道轮流显示,共显示2个通道,每通道显示1s;
(4) 单通道显示,仅显示指定通道电压,并保持到其他功能键按下。
先上原理图:
原理图连线比较乱,主要是为了满足尽量少外围元件的要求,有一个明显奇怪的地方就是38译码器输出口没用完,但是单片机口接得满满的,因为当时想用38译码器的其中三个输出口来控制ADC0809的ABC,结果发现38译码器输出口一次只能有一个低电,从而导致ADC的选址ABC两个以上低电的情况无法实现,测量电压输入口切换的功能也无法实现。这个原理图的错误直到编程时才发现,结果只能大胆参考网络言论,把ADC0809的STARTALE共接,OEEOC共接,虽然总感觉会带来潜在问题,还好,仿真成功了。
看到网上一些仿真图,有模有样,比如红绿交通灯,还真画出红绿灯外形,还有马路斑马线等等,而不是只用LED灯,真佩服,不过觉得把心思都用在表面的东西,还不如优化一下方案和程序。(注意:如参考此程序AD0809和C52的两个OUT网络标号高低位顺序是相反的)
说到程序,原本是本着dont share your code的原则(来自最近刚看了斯坦福的公开课,真是重视知识产权),不打算公开,不过想想,自己编得这么幼稚低级,就当做交流和以后借鉴吧:
///12MHZ/////
//////头文件及宏定义////////
#include
#define uint unsigned int
#define uchar unsigned char
///////相关变量定义///////
static uchar keynum;
bit shift;
float temp;
uchar val_int;
uchar val_decimal;
///////I/O口定义/////////
sbit STA_ALE = P3^0;
sbit OE_EOC = P3^1;
sbit CLK = P3^2;
sbit ADD_A = P3^3;
sbit ADD_B = P3^4;
sbit ADD_C = P3^5;
sbit ADC_B = P3^6;
sbit ADC_A = P3^7;
////////带小数点数码管显示编码///////////
uchar data numtable_DE[] =
{
0xbf,0x86,0xdb,0xcf,
0xe6,0xed,0xfd,0x87,
0xff,0xef
};
////////不带小数点数码管显示编码///////////
uchar data numtable[] =
{
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f
};
///////数码管动态显示函数声明///////
void disp();
///////延时函数///////
void delay(uint x)
{
uint a,b;
for ( a = x; a > 0; a--)
for ( b = 125; b > 0; b--);
}
///////矩阵键盘扫描及赋值函数///////(这个部分自己改造得比较喜欢,想记下来,作为自己的风格)
int keyscan()
{
uchar temp1,temp2,keycod;
P1 = 0xf0;
if ( (P1 & 0xf0) != 0xf0 )
{
temp1 = P1;
}
P1 = 0x0f;
temp2 = P1;
keycod = temp1 | temp2;
switch(keycod)
{
case 0x7e:
keynum = 1;
break;
case 0xbe:
keynum = 2;
break;
case 0xde:
keynum = 3;
break;
default :
keynum = keynum;
break;
}
}
///////数码管动态显示函数///////
void disp()
{
ADD_A = 1;
ADD_B = 0;
ADD_C = 0;
P0 = numtable_DE[val_int];
delay(1);
ADD_A = 0;
ADD_B = 1;
ADD_C = 0;
P0 = numtable[(val_decimal/10)];
delay(1);
ADD_A = 1;
ADD_B = 1;
ADD_C = 0;
P0 = numtable[(val_decimal)];
delay(1);
}
///////通道编号的数码管显示函数///////
void disp_in(uchar a)
{
ADD_A = 0;
ADD_B = 0;
ADD_C = 0;
P0 = numtable[a];
delay(3);
}
///////通道1的AD转换函数///////
void ADC_1()
{
STA_ALE = 0;
STA_ALE = 1;
ADD_A = 1;
ADD_B = 0;
ADD_C = 1;
ADC_B = 0;
ADC_A = 0;
STA_ALE = 0;
}
///////通道2的AD转换函数///////
void ADC_2()
{
STA_ALE = 0;
ADD_A = 1;
ADD_B = 0;
ADD_C = 1;
ADC_B = 0;
ADC_A = 1;
STA_ALE = 0;
}
///////判别是哪条通道AD转换函数///////
void ADC(uchar ad_dat)
{
if (1 == keynum)
{
ADC_1();
disp();
disp_in(1);
}
else if (2 == keynum)
{
ADC_2();
disp();
disp_in(2);
}
else if (3 == keynum)
{
TR1 = 1;
if (!shift)
{
ADC_1();
disp();
disp_in(1);
}
if (shift)
{
ADC_2();
disp();
disp_in(2);
}
}
else if (16 == keynum)
{
ADC_2();
disp();
disp_in(2);
}
while ( 0 == OE_EOC )
{
keyscan();
if (1 == keynum)
{
disp();
disp_in(1);
}
else if (2 == keynum)
{
disp();
disp_in(2);
}
else if (3 == keynum)
{
TR1 = 1;
if (!shift)
{
disp();
disp_in(1);
}
if (shift)
{
disp();
disp_in(2);
}
}
}
temp = ad_dat*0.0196078;
val_int = (uchar) temp;
val_decimal = (uchar) ((temp - val_i
ADC0809电压 相关文章:
- ADC0809电压表 数据采集与处理方法(11-28)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)