单片机原理数码管动态显示实验-单片机原理-实验报告宁德师范学院计算机系实验报告(2014—2015学年第 2学期)课程名称单片机原理实验名称数码管动态显示实验专业计算机科学与技术(非师范)年级 2012级学号 B2012102147 姓名王秋指导教师杨烈君实验日期2015.4.17实验目的:1. 巩固Proteus软件和Keil软件的使用方法2. 学习端口输入输出的高级应用3. 掌握7段数码管的连接方式和动态显示法4. 掌握查表程序和延时等子程序的设计实验要求:1. 在Proteus软件中画好51单片机最小核心电路,包括复位电路和晶振电路2. 在电路中增加八位7段数码管(共阳/共阴自选),将P2口作数据输出口与7段数码管数据引脚相连,P3引脚输出位选控制信号3. 在Keil软件中编写程序,采用动态显示法,实现数码管分别显示数字1-84. 实现指定数值的显示 (可使用缓存数值)5. 实现类似时钟的效果,如“ 13-23-25” 13时23分25秒6. 实现时钟的自动计时7. 扩展要求: 结合LED显示,实现带数码显示的交通灯实验设备(环境):1(计算机2(Proteus ISIS 7 Professional应用程序3(Keil应用程序实验内容:数码管动态显示技术要求实现:1(动态显示法,实现数码管分别显示数字1-8;2(实现指定数值的显示 (可使用缓存数值) (33355223);3(实现类似时钟的效果,如“ 13-23-25” 13时23分25秒;4(实现时钟的自动计时;扩展要求: 结合LED显示,实现带数码显示的交通灯;实验步骤、实验结果及分析:1 实验步骤:1、使用Proteus ISIS 7 Professional应用程序,建立一个.DSN文件2、在“库”下拉菜单中,选中“拾取元件”(快捷键P),分别选择以下元件:AT89C51、CAP、CAP-ELEC、CRYSTAL、RESPACK-8。
3、构建仿真电路:连接图显示1-8显示33355223显示时间13.23.25时钟自动计时连接图红绿灯效果图1红绿灯效果图24、创建一个Keil应用程序:新建一个工程项目文件;为工程选择目标器件(AT89C52);为工程项目创建源程序文件并输入程序代码;保存创建的源程序项目文件;把源程序文件添加到项目中。
5、把用户程序经过编译后生成的HEX文件添加到仿真电路中的处理器中(编辑元件?文件路径) 2 实验程序 <流程图> 开始定义数组开始Ledcode[]开始定义数组定义数组定义数组 Dispbug[]Ledcode[]Ledcode[]存放指定数While定义Dispbug[]While(1)存放指定数(1)YYFor定义子函数ForN(i=0;i<8(i=0;i<8PutTime())),...,调用延YY时函数P3=1<<iP3=1<<iWhile(1)i++P2=~LedcoP2=~Ledcode[DispBude[i]f[i]]PutTim e()P2=~Ledcode[DispBuf[i]]i++i++For调用延时N调用延时(i=0;i<P3=1<<i函数函数8)Y开始P3=1<<iSbit r1=P2^0;...sbit g2=P2^5;P2=~Ledcode[DispBuf[i]]定义数组Ledcode[]i++调用延时定义Dispbug[]函数存放指定数If(ms>=60)定义子函数 YPutTime()comsec=(com,...,sec+1) %60;,ms=0While(1)If(comsec <20)YYSec1=20-comsec;PutTime()Sec2=30-comsec;R1=1;y1=0;g1=0;r2=0;y2=0;g2=1;YForIf(comsec>=20 (i=0;i<8)&& comsec<30)sec1=60-comsec;sec1=30-comsec;Sec2=60-comsec;Sec2=30-comsec;R1=0;y1=1;g1=0;R1=1;y1=0;g1=0;r2=1;y2=0;g2=0;r2=0;y2=1;g2=0;YIf(comsec>=30 If(Comsec>60)&& comsec<50)sec1=60-comsec;YSec2=50-comsec;R1=0;y1=0;g1=1;r2=1;y2=0;g2=0; 程序源代码:1(动态显示法,实现数码管分别显示数字1-8;#include<reg51.h>#define uchar unsigned char #define uint unsigned int uchar code Ledcode[]={ 0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //定义一个数组里面放入1-8void delay(uint x){while(x--);}void main(){uchar i;while(1){for(i=0;i<8;i++){P3=1<<i; //P3口表示从第一个位开始显示数值P2=~Ledcode[i]; //P2口用来显示所需要显示的数值delay(500);}}}2. 实现指定数值的显示 (可使用缓存数值) (33355223);#include<reg51.h>unsigned char code LedCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};unsigned char DispBuf[8]={3,3,3,5,5,2,2,3}; //指定要显示的数的位置void delay(unsigned int x){while(x--);}void main(){unsigned int i;for(i=0;i<8;i++){P3=1<<i;P2=~LedCode[DispBuf[i]]; //显示指定数的位置delay(500);}}3. 实现类似时钟的效果,如“ 13-23-25” 13时23分25秒;#include<reg51.h>unsigned char code LedCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned char Hour=13,Min=23,Sec=25; unsigned char DispBuf[8]; void delay(unsigned int x){while(x--);}void PutTime(){DispBuf[7]=Sec%10; //取对应秒数的个位放在最右边显示DispBuf[6]=Sec/10; //取对应秒数的十位放在右起第二位显示DispBuf[5]=10; //此处表示秒跟分之间用横杆隔开DispBuf[4]=Min%10;DispBuf[3]=Min/10;DispBuf[2]=10;DispBuf[1]=Hour%10;DispBuf[0]=Hour/10;}void main(){long n=0;while(1){unsigned char i;PutTime();for(i=0;i<8;i++){P3=1<<i;P2=~LedCode[DispBuf[i]];delay(500);}}}4. 实现时钟的自动计时; #include<reg51.h>unsigned char code LedCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; unsigned char Hour=13,Min=23,Sec=25;unsigned char DispBuf[8]; void delay(unsigned int x) { while(x--);}void PutTime(){DispBuf[7]=Sec%10;DispBuf[6]=Sec/10;DispBuf[5]=10;DispBuf[4]=Min%10;DispBuf[3]=Min/10;DispBuf[2]=10;DispBuf[1]=Hour%10;DispBuf[0]=Hour/10; }void main(){long n=0;while(1){unsigned char i,ms; //定义一个ms用于控制秒数加一的延时PutTime();for(i=0;i<8;i++){P3=1<<i;P2=~LedCode[DispBuf[i]];delay(500);}ms++; //控制加一的时延if(ms>=20){Sec++;ms=0;}if(Sec>=60) //表示进位,当秒满六十则向分钟进一,同时秒数清零{Min++;Sec=0;}if(Min>=60){Hour++;Min=0;}if(Hour>=24) //当小时数满24小时时,则小时数清零,完成计时{Hour=0;}}}5. 扩展要求: 结合LED显示,实现带数码显示的交通灯;#include "reg52.h"#define uint unsigned int#define uchar unsigned char #define Disp_Null 10uchar code LedCode[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f,0x40}; uchar DispBuf[8];sbit r1=P2^0;sbit y1=P2^1;sbit g1=P2^2;sbit r2=P2^3;sbit y2=P2^4;sbit g2=P2^5;uchar sec1;sec2;comsec; void delay(uint x){while(x--);}void PntTime( ){DispBuf[3]=sec2 % 10; DispBuf[2]=sec2 / 10; DispBuf[1]=sec1 % 10; DispBuf[0]=sec1 / 10; } void display(){uchar i;for (i = 0;i < 8;i ++) {P3=0;P1=~LedCode[ DispBuf[i] ]; P3=1<<i;delay(100) ;}}void main (){while(1){uchar ms;PntTime();display();ms++;if( ms >=60){ms=0;comsec=(comsec+1) % 60; //定义一个计数变量,使其一直保持在60内}if( comsec <20){ //comsec在20以内时g2、r1亮sec1=20-comsec; sec2=30-comsec;r1=1;y1=0;g1=0;r2=0;y2=0;g2=1;}if(comsec>=20 && comsec<30){ //comsec在20与30之间时y2、r1亮sec1=30-comsec; sec2=30-comsec;r1=1;y1=0;g1=0;r2=0;y2=1;g2=0;}if(comsec>=30 && comsec<50){ //g1、r2在comsec增加20内亮sec1=60-comsec; sec2=50-comsec;r1=0;y1=0;g1=1;r2=1;y2=0;g2=0;}if(comsec>=50){sec1=60-comsec; sec2=60-comsec;r1=0;y1=1;g1=0;r2=1;y2=0;g2=0;}}}过程总结:本实验是将单片机的P2口做为输出口,将四个数码管的七段引脚分别接到P2.0至P2.7.由于电路中采用共阳极的数码管,所以当P2端口相应的引脚为0时,对应的数码管段点亮。