数码管流水灯设计.docx
《数码管流水灯设计.docx》由会员分享,可在线阅读,更多相关《数码管流水灯设计.docx(19页珍藏版)》请在冰豆网上搜索。
数码管流水灯设计
单片机课程设计报告
第一章基础设计报告
1.1设计题目数码管流水灯设计
1.2设计任务
结合单片机原理知识,运用AT89C51单片机来设计一款简单的数码流水灯,并结合Uvision4和ISIS7Professional两款软件来设计和模拟。
利用AT89C51单片机来控制发光二极管的点亮和熄灭,实现延时和循环移位。
用单片机AT89C51的一个端口接8位用逻辑显示的发光二极管,设计程序,使发光二极管从右向左依次轮流点亮。
1.3程序流程:
图1.1实验程序流程图
1.4Proteus模拟实验电路
图1.2Proteus实验电路模拟
(1)启动proteues软件,获取所需的器件。
图1.1
图1.3Proteus拾取元件
(1)
(2)打开库后,输入AT89C51,查找到AT89C51芯片,双击添加到实验图示中。
图1.4Proteus拾取元件
(2)
同理,还添加所需的电容(CAP、CAP-POL)、电阻(RESISTOR)、晶振(CRYSTAL)、发光二极管(LED-BLUE)、74LS373等。
(3)按照图1.2所示连接电路图。
1.5编写实验程序
(1)打开Keil程序,选择工程菜单。
1.5Keil程序
(2)选择新建uVision工程,保存为工程名称。
图1.6新建uVision工程
(3)选择Atmel公司的AT89C51设备。
(4)新建一个程序,并保存其后缀名为.asm(若是用C语言编写,其后缀名保存为.c)
图1.8新建程序文本
图1.9保存程序并更改后缀名为.asm
(5)增加程序文本到源组。
图1.10添加程序文本
(6)编译程序之前,在闪存菜单设置选项中选择输出选项,在产生HEX文件前打钩即可。
图1.54产生HEX文件
图1.11产生HEX文件
1.6实验程序
(1)编写汇编程序
ORG00H
LOOP:
MOVA,#0FEH//赋初始值
MOVR2,#8//设计数值
OUTPUT:
MOVP1,A//送P1口输出
RLA//数据移位
ACALLDELAY
DJNZR2,OUTPUT
LJMPLOOP
DELAY:
MOVR6,#0//延时程序
MOVR7,#0
DELAYLOOP:
DJNZR6,DELAYLOOP
DJNZR7,DELAYLOOP
RET
END
(2)调试与运行:
通过右击单片机,选择编辑属性,导入程序
图1.12向单片机导入程序
(3)点击运行,仿真实验
图1.13实验仿真结果
第二章提高设计报告
2.1设计题目基于单片机的数字电压表设计
2.2设计任务
设计单片机主电路、数据采集接口电路、数码管显示电路,能够实现对电压的测量及显示,电压精确到小数点后一位。
2.3程序流程图
图2.1主程序流程图
2.4设计步骤:
1)根据设计要求来确定设计思路。
2)根据设计要求查找相应芯片参数,确定所需要的器件。
3)设计硬件电路。
4)根据电路图编写程序。
2.5设计硬件电路
(1)复位电路
图2.2复位电路
复位端与计算机的复位键的功能类似。
当系统正在运行或者计算机死机时,只要按下复位键,计算机就会重新启动。
当打开单片机系统的电源开关时,VCC的电压瞬间变为+5V,电解电压的电容突变相当于短路,于是VCC(高电平)相当于直接加到了RST端。
正是这个加在RST上的瞬间高电平使得单片机复位。
很快,电容充满电,在电路中相当于断路,于是RST由高变成低,单片机开始执行程序。
按键相当于手动复位,当按键闭合时,单片机的RST端接高电平VCC,从而单片机复位。
(2)时钟信号
图2.3外部时钟信号电路
这个电路构成了单片机的一个时钟信号源,作为单片机的工作时序。
这种使用晶振配合产生时钟信号的方法称为内部时钟方式。
晶振的频率决定了该系统的时钟频率。
根据系统对速度的要求,一般可选择1.2M~12MHz的晶振,电容C1和C2容量可选取20~40pF。
除了内部时钟外,还可以利用外部信号源直接向单片机提供时钟信号,这时应当把外部时钟信号输入到XTAL2脚上,XTAL1接地,而这时外部振荡信号一般选择低于12MHz的方波信号。
(3)AD0808芯片接法
图2.4ADC0808芯片接法
ADC0808引脚功能
●IN0~IN7:
模拟量输入通道。
●ADDA、ADDB、ADDC:
地址线,它决定转换通道。
●ALE:
地址锁存信号。
●START:
转换启动信号。
START为上升沿,所有内部寄存器清零,START为下降沿,启动A/D转换。
●OUT1~OUT8:
数据输出端,为三态缓冲输出。
●OE:
输出允许端。
OE=0,输出禁止。
OE=1,输出允许。
●CLK:
时钟信号,频率小于750kHz的时钟信号。
●EOC:
转换结束信号。
系统启动前EOC=1,系统启动后EOC=0,当EOC=1时,表示转换结束。
●VREF:
参考电压,典型值为+5V。
ADC0808主要参数
●分辨率:
8
●转换时间:
100us
●转换路数:
8
●标准电压:
5V
●时钟频率:
≤750kHz
●输入为0~5V
●输出具有锁存
●功耗:
≤15mV
●非调整误差位:
+LSB或-LSB
(4)数码管显示(采用的是共阳极数码管)
图2.5数码显示电路
(5)
完整电路图
图2.6基于单片机设计的数字电压表电路
2.6程序代码:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definePORTP0
sbitSTART=P2^5;
sbitEOC=P2^6;
sbitOE=P2^7;
sbitCLOCK=P2^4;
sbitp21=P2^1;
sbitp22=P2^2;
/*数码管显示字符组*/
ucharcodenum[]={0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/
};//共阳极数码管
/*定义中断程序*/
voidint1(void)interrupt1using1
{
CLOCK=~CLOCK;
}
/*定义延时程序*/
voiddelay(void)
{
uchari,j;
for(i=25;i>0;i--);
for(j=100;j>0;j--);
}
/*声明数码显示函数*/
voiddisplay(uintsw,uintgw);
voidmain()
{
uchardate;
uintsw,gw;
IE=0x82;//开中断,EA=1,允许T0中断
TMOD=0x02;//设置工作方式,工作方式2,自动重装初值
TH0=245;//设置初值
TL0=0;//计数溢出,置位溢出中断标志位
TR0=1;//启动T0
for(;;)
{
START=0;//ADC转换器启动信号,上升沿将逐次毕竟寄存器清零,下降沿启动ADC转换
START=1;
START=0;
delay();
while(EOC==0);//EOC为高时,表示转换结束,为低时表示正在转换。
将EOC作为中断请求信号
OE=1;//输出转换得到的数据
date=P1;
sw=date/51;
gw=(date%51)%10;
display(sw,gw);
}
}
/*数码管显示程序*/
voiddisplay(uintsw,uintgw)
{
/*显示数码管一*/
p21=1;
PORT=num[sw]&0x7f;
delay();
p21=0;
/*显示数码管二*/
p22=1;
PORT=num[gw]|0x80;
delay();
p22=0;
}
2.7仿真结果
图2.7实验电路仿真结果
通过外接一个一个滑动变阻器来模拟数字电压表的两个测电压端。
2.8误差分析
(1)ADC0808芯片的精度限制会带来一定的误差,这部分误差会影响到模数转换输出的结果。
(2)ADC0808转换后输出的二进制,而得到的二进制转换成十进制时往往不是模拟的电压值,这时需要我们在主程序做相应的处理,将其转换出的结果和模拟电压值相对应。
在此实验中,电压的量程为5V,ADC0808的转换位数为8.模拟电压值与转换后二进制存在一个比例为5:
256(2^8).而在这主程序中我们所做的转换处理会带来本次实验的误差。
(3)在此次实验中,我们只精确到小数一位,在程序中的四舍五入也会带来一定的误差。
2.9实验所遇到的问题以及相应的处理
(1)在最开始时,我们采用的是ADC0831串行的方式输入数据,而在最后输出显示部分,完全不能正确的显示。
我的判断是在ADC0831到单片机AT89C51中没有串并转换的器件,努力尝试的更改电路后,比预想的还要困难,所以最终选择的是用并行的ADC0808芯片来做模数转换。
(2)数码显示部分是问题最多的地方,其一就是因为人眼的视觉特性,导致延时设定不合适而出现视觉闪烁现象。
最后我在查阅了相关资料后,将延时设置为25ms.其二,显示数码管相应位数时,问题也特别多,也是不能正确显示出。
尤其是在数码管的位数相应比较多的情况。
显示程序部分就很有很大的问题。
在主程序中我采用的是无符号整型和无符号字符型,而其中将其进行强制转换成浮点型来处理,但是在后的数码管显示部分仍然是不正确的读数,而其中检查模数转换部分是正确的,我判断的是主程序中处理数据部分和数码管显示子程序的问题。
最后采用一种比较折中的办法,将数码管的显示位数减少为两位,小数精确到一位。
(3)ADC0808的时钟信号供给。
从始至终我没有想用外部电路来控制时钟信号。
基于单片机的可控制性,我还是采用了通过单片机的I/O口来控制。
而这部分也是一个比较大的难题。
外接电路究竟要怎么接?
是直接连到单片机上?
还是需要一些器件来共同连接?
最后参考到一些单片机控制的相关程序而选择用中断的方式来供给ADC芯片时钟信号。
第三章提高设计报告任务说明书
3.1小组成员及学号
姓名
学号
赵林
0807040118
唐棋
0807040125
3.2本人工作任务详细说明
本次实验,我主要负责软件部分,通过已建立的电路来编写单片机的控制程序,并协同同伴修改出错的电路。
在此程序采用的通过中断给ADC0808一个时钟信号。
在此之间我们需要将中断打开,即在IE、TMOD设置数值。
而中断程序是给CLOCK取反。
通过这种方式而产生一个脉冲。
在主程序中,先给START置低,再置高,从而形成一个上升沿,ADC0808内部寄存器清零。
再置低,形成一个下降沿,启动A/D转换。
然后使能OE=1,输出转换的数据到P1口。
处理数据后,调用显示数码管子程序,即将模数转换的结果输出到数码管显示。
第四章 设计心得
这次设计尤其是在编写程序部分是一个比较大的挑战。
其中遇到了许多困难。
刚开始时,我对整个软件的操作都显得不那么的熟悉。
而后,在如何选择芯片上遇到了困难。
我不知道应该是基于什么样的标准去选择芯片。
所以最后我选择了我们常用的的芯片。
在设计电路时,有时需要给一个上拉电阻,有时又不需要,这也只有在一步一步的仿真后,通过观察相应端口的高低电平来判断的。
对于很少编程的我是努力的不断的看程序,不断的模仿,不断的设计,不断的改进,才最终设计完此次实验。
在面对问题时,我们应该选择积极的态度去面对,是积极的去解决问题,查资料,一步步弄明白,而不是选择消极的方式去处理。
最后,通过这次实验,我逐步掌握了PROTEUS的用法。
这对今后的设计工作带来一些方便。
参考文献:
[1]李建忠.《单片机原理及应用》.西安:
西安电子科技大学出版社,2008
[2]侯玉宝、陈忠平、李成群等.《基于Proteus51系列单片机设计与仿真》北京:
电子工业出版社,2008
[3]江世明.《基于Proteus的单片机应用技术》北京:
电子工业出版社,2009
[4]杨欣、王玉凤、刘湘黔.《51单片机应用从零开始》北京:
清华大学出版社,2009