咱们的ADC0809电压表

发布者:琴弦悠扬最新更新时间:2015-08-07 来源: dzsc关键字:ADC0809  电压表 手机看文章 扫描二维码
随时随地手机看文章
第一次和同学合作的学校课题:ADC0809电压表,以实物失败,仿真成功告终。相信以后回头看,会发现许多地方非常的不专业,特发此博文,以后当笑话看。不过因为是第一次接触AD相关知识,也学到了挺多。
系统软件设计要求:
(1) 键盘管理程序(包括键扫描、键处理程序)。
(2) LED动态显示程序,包括:
(3) 各通道轮流显示,共显示2个通道,每通道显示1s;
(4) 单通道显示,仅显示指定通道电压,并保持到其他功能键按下。
先上原理图:
咱们的ADC0809电压表
 
原理图连线比较乱,主要是为了满足尽量少外围元件的要求,有一个明显奇怪的地方就是38译码器输出口没用完,但是单片机口接得满满的,因为当时想用38译码器的其中三个输出口来控制ADC0809的ABC,结果发现38译码器输出口一次只能有一个低电,从而导致ADC的选址ABC两个以上低电的情况无法实现,测量电压输入口切换的功能也无法实现。这个原理图的错误直到编程时才发现,结果只能大胆参考网络言论,把ADC0809的STARTALE共接,OEEOC共接,虽然总感觉会带来潜在问题,还好,仿真成功了。
看到网上一些仿真图,有模有样,比如红绿交通灯,还真画出红绿灯外形,还有马路斑马线等等,而不是只用LED灯,真佩服,不过觉得把心思都用在表面的东西,还不如优化一下方案和程序。(注意:如参考此程序AD0809和C52的两个OUT网络标号高低位顺序是相反的)
 
说到程序,原本是本着don't 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);
}[page]
 
///////通道编号的数码管显示函数///////
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;
STA_ALE = 1;
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_int)*100);
}
 
///////定时器初始化函数//////
void timer_init()
{
IE = 0x8a;
TMOD = 0x12;
TH0 = 0x14;
TL0 = 0x00;
TR0 = 1;
TH1 = -50000/256;
TL1 = -50000%6;
}
 
///////主函数//////
int main ()
{
timer_init();//初始化定时器
while(1)
{
keyscan();//矩阵键盘扫描赋值
 
if (1 == keynum || 2 == keynum || 3== keynum) //当有键按下时,启动ADC转换
ADC(P2);
 
else //否则显示四个0
{
disp();
disp_in(0);
}
}
return 0;
}
 
///////1S显示切换的定时中断函数(T1)//////
void TIMER(void) interrupt 3
{
static uchar timer;
timer++;
if (20 == timer)
{
timer = 0;
shift = !shift;//用于两位的1S显示切换
}
}
 
///////提供给ADC芯片CLOCK的定时函数(T0)//////
void OTHER_CLOCK(void) interrupt 1
{
CLK = !CLK;
}
 
 
说说主要遇到的问题和学到的东西:一个是因为用了等待查询方式来读取ADC0809的AD转换结果,加上矩阵键盘和38译码器选址,导致两个问题:
1.各个功能的逻辑关系混乱。虽然只有几个功能模块,但是也思考了一番才有了新的程序架构。还有就是始终没能适应自顶向下的编程思维,比如会习惯先编出ADC的START信号或者选址函数,再去想用在哪里。而不是先直接构造一个ADC处理的框架,再去想细节的实现。
2.还有数码管动态显示不停闪烁。调试的时候,也老想着,应该就是这样了吧,改不了了吧,呵呵,可是解决之后再次觉得天无绝人之路啊,
 
ADD_A = 1;
ADD_B = 0; 这段语句起初P0 = numtable_DE[val_int];是放在首位的,结果想想是不是因为用38
ADD_C = 0; 译码器控制位选扰乱了下一位的段选,移一下位就搞定了……真是奇妙
P0 = numtable_DE[val_int];
delay(1);
 
团队合作的效率这次体现得很明显,特别是繁琐的画图,可是因为大家实践比较少,结果很不幸犯了很基础的错误,导致成品没有成功。不知道以后还有机会合作不
关键字:ADC0809  电压表 引用地址:咱们的ADC0809电压表

上一篇:基于单片机设计的音乐马桶
下一篇:基于C8051F单片机的镍氢电池组管理系统

推荐阅读最新更新时间:2024-03-16 14:27

使用电压表测量电压注意事项
使用电压表测量电压时,应注意下列事项: 1.测量电压时,应根据被测电压的大小,选择合适的量程,使电压表的量程略大于被测电压值。 2.电压表应并联接入电路。由于电压表内阻很大,如果错接成串联,则测量电路呈断路状态,仪表将不能显示。 3.在测量直流电压时,如果电压很高,应串联外附式附加电阻。 4.在交流电路中,测量高压时,需要配备一定变比倍数的电压,仪表应与所配用的互感器二次电压相符。
[测试测量]
ADC0832数字电压表数码管显示(示例程序)
;******************************************************************************** 描述: ADC0832数字电压表数码管显示 调节ADC0832旁边的电位器,数码管显示 ADC0832 转换值的大小 ;******************************************************************************* *************************************
[单片机]
数码管显示的ADC0831电压表程序
/* 程序效果:数码管显示0.00-5.00U电压,调节电位器,得到      ADC0831的2脚电压值。 注:测量时先把电位器调节到中间,也就是2.5U,但切记   所测的引脚的电压值不能超过5U,否则会烧坏ADC0831    芯片和单片机,小心哦。 程序版权所有: http://www.51hei.com ,如无法编译,请去掉所有前导空白。 */ #include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned int uchar code table ={ 0x3f,0x06,0x5b,0x4f,0x66,0x6
[单片机]
基于51单片机和ADC0809的数字电压表设计
本课题是利用单片机设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,使用的元器件数目较少。外界电压模拟量输入到A/D转换部分的输入端,通过A/D转换变为数字信号,输送给单片机。然后由单片机给数码管数字信号,控制其发光,从而显示数字。 注:因为ADC0809的通道选择端口是使用插针,做出电路板后再用导线连起来的,在程序里也少了通道选择的语句,请注意一下。 一.原理图 二.仿真图 三.存储空间定义 (1)70H用于存放A/D转换结果,71H、72H、73H、74H分别存储显示用的三位数据如表所示。 (2)地址30H~39H存放显示在数码管上0~9的数。如表所示。 四.程序 程序可分为数据采
[单片机]
基于51单片机和<font color='red'>ADC0809</font>的数字<font color='red'>电压表</font>设计
基于单片机的简易数字R-V-I测试仪的设计
0 引言 当前大量使用的一种基本的测量工具,广泛应用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大的生命力。针对电阻、电压及电流三个基本电量的测量,本文设计了一个简易的数字多用表。 1 总体设计方案 1.1 功能要求 本系统采用8位8路A/D转换器ADC0809和AT89S52单片机,设计了一台数字多用表,能进行电阻、电压和电流的测量,测量结果通过LED数码管显示,通过按键进行测量功能转换。电压测量范围为0~20 V,测量误差约为±0.02 V;电流测量范围为1~100 mA,测量误差约为±0.5 mA;电阻测量范围为0~100kΩ,1k以内测量误差约为±2Ω。 1.2 系统总体设计框图
[单片机]
基于单片机的简易数字R-V-I测试仪的设计
89C51单片机与1片ADC0809组成的数据采集系统编程实例
在1个由89C51单片机与1片ADC0809组成的数据采集系统中,ADC0809的8个输入通道的地址为7FF8H~7FFFH,试画出有关接口电路图,并编写出每隔1分钟轮流采集1次8个通道数据的程序,共采样50次,其采样值存入内RAM20H单元开始的存储区中。 图片1 参考程序如下: 0~7通道地址:fef8h~feffh ORG 000H LJMP MAIN ORG 0003H LJMP I_INT0 ORG 000BH LJMP I_T0 ORG 050H MAIN: MOV
[单片机]
89C51单片机与1片<font color='red'>ADC0809</font>组成的数据采集系统编程实例
基于ADC0809的数字电压表
1.引言 本设计待测的输入电压为8路,电压范围为0~5V,使用目前广泛使用的AT89S52来做控制系统,用ADC0809来进行模拟电压的采集及模数转换,实现采集8路数据,并将结果在四位一体数码管上进行滚动显示或单独显示的功能,测量的最小分辨率为0.019V. 2 硬件设计 2 . 1 系统构成 该系统主要包括几大模块:数据采集模块、A/D转换模块、控制模块、显示模块、按键模块等。采用AT89S52作为控制模块,A/DC0 8 0 9作为A/D转换模块的核心,ADC0809本身具有8路模拟量输入端口,通过C、B、A,3位地址输入端,能从8路中选择一路进行转换。如每隔一段时间依次轮流改变3位地址输入端的地址,就能依次对8路输入电压进行
[电源管理]
基于<font color='red'>ADC0809</font>的数字<font color='red'>电压表</font>
一种基于FPGA的新型数字电压表研究与设计
  数字电压表是大学物理教学和实验中的重要仪表,其数字化是指将连续的模拟电压量转换成不连续、离散的数字量并加以显示。传统的实验用模拟电压表功能单一、精度低、体积大,且存在读数时的视差,长时间连续使用易引起视觉疲劳,使用中存在诸多不便。而目前数字万用表的内部核心多是模/数转换器,其精度很大程度上限制了整个表的准确度,可靠性较差。本文采用National Semiconductor。公司性能优越的8位A/D转换器ADC0809对模拟电压采样,以一片高性能FPGA芯片为控制核心,以软件实现了诸多硬件功能,对电压信号的转换结果进行准确实时的运算处理并送出显示。系统的主要功能都集成在一块芯片上,大大减少了系统的分立元件数量,降低了功耗,增加
[嵌入式]
一种基于FPGA的新型数字<font color='red'>电压表</font>研究与设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved