8位数码管显示时钟
- 格式:doc
- 大小:383.50 KB
- 文档页数:16
八段数码管显示1.实验目的 :(1)了解数码管动态显示的原理。
(2)了解 74LS164 扩展端口的方法。
2. 实验内容 :利用实验仪提供的显示电路 , 动态显示一行数据。
3.实验线路 :PB0数据输入PB1时钟输入说明:这里只是显示草图,详细原理参见"8155 接口实验 "4.实验器材:(1)QTH2008下载式综合实验仪1 台(2)QTH2008仿真器 1 台(3)计算机 1 台5.实验说明 :(1)本实验仪提供了 8 段码 LED 显示电路,学生只要按地址输出相应数据,就可以实现对显示器的控制。
显示共有 6 位,用动态方式显示。
8 段码是由 8155的 PB0、PB1 经74LS164“串转并”后输出得到。
6 位位码由 8155( 或8255) 的PA0-5 口输出,经 uA2003 反向驱动后,选择相应显示位。
74LS164 是串行输入并行输出转换电路,串行输入的数据位由 8155 的PB0 控制,时钟位由 8155 的PB1 控制输出。
写程序时,只要向数据位地址输出数据,然后向时钟位地址输出一高一低两个电平就可以将数据位置到74LS164 中,并且实现移位。
向显示位选通地址输出高电平就可以点亮相应的显示位。
本实验仪中数据位输出地址为 0e102H,时钟位输出地址为 0e102H,位选通输出地址为 0e101H。
本实验涉及到了 8155 I0/RAM 扩展芯片的工作原理以及74LS164 器件的工作原理。
(2)七段数码管的字型代码表如下表:显示字g f e d c b a 段码形0 0 1 1 1 1 1 1 3fh1 0 0 0 0 1 1 0 06h2 1 0 1 1 0 1 1 5bh3 1 0 0 1 1 1 1 4fh4 1 1 0 0 1 1 0 66h5 1 1 0 1 1 0 1 6dh6 1 1 1 1 1 0 1 7dh7 0 0 0 0 1 1 1 07h8 1 1 1 1 1 1 1 7fh9 1 1 0 1 1 1 1 6fhA 1 1 1 0 1 1 1 77h b 1 1 1 1 1 0 0 7ch C 0 1 1 1 0 0 1 39h d 1 0 1 1 1 1 0 5ehE 1 1 1 1 0 0 1 79hF 1 1 1 0 0 0 1 71h6.程序框图:7.参考程序 (SY10.ASM):OUTBIT equ 0e101h ; 位控制口CLK164 equ 0e102h ; 段控制口 ( 接164 时钟位 )DAT164 equ 0e102h ; 段控制口 ( 接164 数据位 )IN equ 0e103h ;键盘读入口LEDBuf equ 60h ;显示缓冲Num equ 70h ;显示的数据DelayT equ 75horg 0000hljmp StartLEDMAP: ; 八段管显示码db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07hdb 7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71hDelay: ;延时子程序mov r7, #0DelayLoop:djnz r7, DelayLoopdjnz r6, DelayLoopretDisplayLED:mov r0, #LEDBufmov r1, #6 ;共个八段管6mov r2, #00100000b ;从左边开始显示Loop:mov dptr, #OUTBITmov a, #00hmovx @dptr, a ;关所有八段管mov a, @r0mov B, #8 ;送164DLP:rlc amov r3, amov acc.0, cANL A, #0FDHmov dptr, #DAT164movx @dptr, amov dptr, #CLK164orl a,#02hmovx @dptr, aanl a,#0fDhmovx @dptr, amov a, r3djnz B, DLPmov dptr, #OUTBITmov a, r2movx @dptr, a ;显示一位八段管mov r6, #1call Delaymov a, r2 ;显示下一位rr amov r2, ainc r0djnz r1, Loopmov dptr, #OUTBITmov a, #0movx @dptr, a ;关所有八段管retStart: mov dptr,#0e100hmov a,#03hmovx @dptr,amov sp, #40hmov Num, #0MLoop:inc Nummov a, Nummov b, amov r0, #LEDBufFillBuf:mov a, banl a, #0fhmov dptr, #LEDMapmovc a, @a+dptr ;数字转换成显示码mov @r0,a ;显示在码填入显示缓冲inc r0inc bcjne r0, #LEDBuf+6, FillBufmov DelayT,#30DispAgain:call DisplayLED ;显示djnz DelayT,DispAgainljmp MLoopEND八位数码管显示: 8155 控制参考程序2:对 8155 初始化,使I/O 口控制 LED 的显示情况。
用STC12C2052AD及八位数码管(595)模块扩展模块组成的三键时钟8位LED数码管驱动模块是通过HC595级联,只需要三个普通IO口就可以驱动八位LED数码管。
以下是程序:#include<STC12C2052AD.H>#include<INTRINS.h>#define uchar unsigned char#define uint unsigned intuchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0 xbf,0xff};//0-f -//uchar weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码,这里可以选择显示方向uchar weima[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//分别对应相应的数码管点亮,即位码uchar time_buf[]={12,0,0};uchardisp_buf[]={0x00,0x01,0x02,0x00,0x01,0x02,0x00,0x01,0x02,0x00,0x01,0x02,0x00,0x01,0x02}; uchar Time_temp = 0, LED_temp = 0;uchar uTH0=0;uchar zz,ix,k1,k2,k3,k4,isk;// 调时led_NO= 0-7 key1 向右(led_NO+1) key2 向左(led_NO-1) 移动调整位置, key3 调数字(0-9循环)// 调快慢led_NO =8-12 key1 向右(led_NO+1) key2 向左(led_NO-1) 移动调整位置, key3 调数字(0-9循环)uchar led_NO = 8; // 一级菜单调时闪烁位uchar led_NO2 = 4; // 一级菜单调快慢闪烁位 C 粗调d 细调uchar t_buf=189 ; // 调快慢粗调1秒=时基* t_bufuchar t_buf2=0 ; // 调快慢细调每隔五分钟增减几秒,由t_buf3决定加减uchar t_buf3=1 ; // =1 增>1 减uchar ist;// 键sbit key1=P3^3; // 向右sbit key2=P3^5; // 向左-sbit key3=P3^4; // +sbit key4=P3^7; // - 暂没用// 数码模块占用IO 口sbit P00=P1^0;//SER 串行数据输入sbit P26=P3^0;//RCL 移位寄存器时钟输入sbit P25=P3^1;//CLK 存储寄存器时钟输入sbit P24=P3^2; //OE使能端//74hc595函数void hc595(uchar date){uint i;P25=0;//给rclk一个下降沿for(i=0;i<8;i++){P26=0;//sclk拉低if((date&0x80)!=0){P00=1;}//判断m的值如果为高ser1就拉高else{P00=0;}P26=1;//给一个上升沿_nop_;date=date<<1;//8位依次进行判断}P25=1;//给rclk一个上升沿_nop_;P25=0;}void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=108;y>0;y--);}void ndisplay2(uint xa,uint da,uint ca){uint ya;if (ca==1) ya=led_NO;if (ca==2) ya=led_NO2;hc595(weima[xa]);if((xa != ya) || ( zz == 3 ) ) hc595(table[da]);else hc595(0xff);delay(4);hc595(0xff);hc595(0xff);}/********************************************************************* 名称: Time0_Init()* 功能: 定时器的初始化,11.0592MZ晶振,50ms* 输入: 无* 输出: 无***********************************************************************/ void Time0_Init(){/************************************TMOD = 0x01;IE = 0x82;TH0 = 0x4c;TL0 = 0x00;TR0 = 1;*************************************/TMOD = 0x11; // 定时/计数器0,1工作于方式1TH0 = 0xf6; // 预置产生45ms时基信号TL0 = 0x3c;EA = 1; // 开总中断ET0 = 1; // 定时/计数器0允许中断TR0 = 1; // 开闭定时/计数器0}/********************************************************************* 名称: Time0_Int()* 功能: 定时器中断,中断中实现Count 加一* 输入: 无* 输出: 无***********************************************************************/ void Time0_Int() interrupt 1{TH0 = 0xf6-uTH0; // 预置产生时基信号TL0 = 0x3c;Time_temp++;if(Time_temp == t_buf ) // 1秒,{time_buf[2]=time_buf[2]+1; //秒if ( time_buf[2]>59 ){ time_buf[1]=time_buf[1]+1;time_buf[2]=0;ist=ist+1;} //分if ( time_buf[1]>59 ){ time_buf[0]=time_buf[0]+1;time_buf[1]=0;} //时if ( time_buf[0]>23){ time_buf[0]=0;} //天Time_temp = 0;}}void display0(){uint ii;ii= time_buf[0]/10%10 ;ndisplay2(0,ii,1);ii= time_buf[0]%10 ;ndisplay2(1,ii,1);// ndisplay2(0,time_buf[0]/10%10);// ndisplay2(1,time_buf[0]/10);ndisplay2(2,16,1);ii= time_buf[1]/10%10 ;ndisplay2(3,ii,1);ii= time_buf[1]%10 ;ndisplay2(4,ii,1);// ndisplay2(3,time_buf[1]/10%10);// ndisplay2(4,time_buf[1]/10);ndisplay2(5,16,1);ii= time_buf[2]/10%10 ;ndisplay2(6,ii,1);ii= time_buf[2]%10 ;ndisplay2(7,ii,1);delay(4);// ndisplay2(6,time_buf[2]/10%10); // ndisplay2(7,time_buf[2]/10);}void display() //调快慢{uint s,ii;unsigned char hms1,hms2;s=1;switch (led_NO){case 9:led_NO2=4 ;break;case 10:led_NO2=5 ;break;case 11:led_NO2=6 ;break;case 12:led_NO2=7 ;break;}if (led_NO==9) // 粗调{if ( k2>40 ) {k2=0;t_buf=t_buf-1;}if ( k3>40 ) {k3=0;t_buf=t_buf+1;}}if (led_NO==10) // 加减{if ( k2>40 ) {k2=0;t_buf3=t_buf3-1;}if ( k3>40 ) {k3=0;t_buf3=t_buf3+1;}if ( t_buf3>2) t_buf3=1; // 加if (t_buf3==0) t_buf3=2; // 减}if (led_NO==11) //细调十位{if ( k2>40 ) {k2=0;hms1=t_buf2/10%10 ;hms2=t_buf2%10 ;if (hms1==0) hms1=5;else hms1=hms1-1;t_buf2=hms1*10+hms2;}if ( k3>40 ) {k3=0;hms1=t_buf2/10%10 ;hms2=t_buf2%10 ;hms1=hms1+1;if (hms1>5) hms1=0;t_buf2=hms1*10+hms2;}}if (led_NO==12) //细调个位{if ( k2>40 ) {k2=0;hms1=t_buf2/10%10 ;hms2=t_buf2%10 ;if (hms2==0) hms2=9;else hms2=hms2-1;t_buf2=hms1*10+hms2;}if ( k3>40 ) {k3=0;hms1=t_buf2/10%10 ;hms2=t_buf2%10 ;hms2=hms2+1;if (hms1>9) hms2=0;t_buf2=hms1*10+hms2;}}ndisplay2(0,12,2);ndisplay2(1,16,2);ii=t_buf/100%10;ndisplay2(2,ii,2);ii= t_buf/10%10 ;ndisplay2(3,ii,2);ii= t_buf%10 ;ndisplay2(4,ii,2);if ( t_buf3==1 ) ndisplay2(5,17,2); //加if ( t_buf3==2 ) ndisplay2(5,16,2); //减ii=t_buf2/10%10;ndisplay2(6,ii,2);ii= t_buf2%10 ;ndisplay2(7,ii,2);}void delayms(void) //误差0us 50ms{unsigned char a,b,c;for(c=7;c>0;c--)for(b=16;b>0;b--)for(a=110;a>0;a--);}void KEY_k(){unsigned char hms1,hms2;if (key1 ==0 ){delay(50);if (key1==0) { k1=k1+1; }}if (key2 ==0 ){delay(50);if (key2==0) { k2=k2+1; }}if (key3 ==0 ){delay(50);;if (key3==0) { k3=k3+1; }}if ( key4 ==0 ){delay(25);if ( key4==0) { k4=k4+1; }}if ( k1>50 ) {led_NO=led_NO+1;k1=0;if ((led_NO==2 ) || (led_NO ==5 )) led_NO=led_NO+1; }if ( k2>70 ) {k2=0;switch (led_NO){case 0:led_NO=8 ;break;case 3:led_NO=led_NO-2;break;case 6:led_NO=led_NO-2;break;default:led_NO=led_NO-1;break;}}if ( led_NO > 13 ) led_NO=0;if (k3>70) {k3=0;if (led_NO != 8){switch (led_NO){case 0:hms1=time_buf[0]/10%10 ;hms2=time_buf[0]%10 ;hms1=hms1+1;if (hms1>2) hms1=0;time_buf[0]=hms1*10+hms2;break;case 1:hms1=time_buf[0]/10%10 ;hms2=time_buf[0]%10 ;hms2=hms2+1;if (hms2>9) hms2=0;time_buf[0]=hms1*10+hms2;break;case 3:hms1=time_buf[1]/10%10 ;hms2=time_buf[1]%10 ;hms1=hms1+1;if (hms1>5) hms1=0;time_buf[1]=hms1*10+hms2;break;case 4:hms1=time_buf[1]/10%10 ;hms2=time_buf[1]%10 ;hms2=hms2+1;if (hms2>9) hms2=0;time_buf[1]=hms1*10+hms2;break;case 6:hms1=time_buf[2]/10%10 ;hms2=time_buf[2]%10 ;hms1=hms1+1;if (hms1>5) hms1=0;time_buf[2]=hms1*10+hms2;break;}}}}void main(){P24=0;Time0_Init();uTH0=uTH0-0; // 越大越慢 2ix=50;while(1){zz=zz+1;if ( zz==10 ) zz=0;delay(20);KEY_k();////if (( ist == 5 ) && (time_buf[2] == 59) ) // 调快慢每五分钟调减t_buf2: 秒if ( ( t_buf2 > 0 ) && ( t_buf3 == 2 ) ) // 减{// time_buf[1]=time_buf[1]-1; //time_buf[2]=time_buf[2]-t_buf2;// ist=time_buf[0]; //ist = 0;}if (( ist == 5 ) && (time_buf[2] == 0) ) // 调快慢每五分钟调加t_buf2: 秒if ( ( t_buf2 > 0 ) && ( t_buf3==1 )) // 加{time_buf[2]=time_buf[2]+t_buf2;// ist=time_buf[0];ist = 0;}/////if ((led_NO<9) || (led_NO>13)) display0();else display();}}。
毕业设计<论文)题目:八位数显示时钟的设计与制作2018年8月28日毕业设计任务书1.毕业设计题目:八位数显时钟题目类型实验研究题目来源教师科研题毕业设计内容要求:<一)设计任务:1、用单片机设计8位数显电子时钟;2、走时,误差精度控制在1s/天;3、调时,小时、分钟加减调整及闪烁显示;4、闹铃,可以设置三组闹铃,默认闹铃时间为1分钟,可按任意键推出闹铃。
<二)涉及要求:1、总体方案设计及框图;2、设计原理电路图及分析;3、独立编写程序;4、完成protues仿真设计;5、使用protel设计pcb并制作、调试电路。
2.主要参考资料[1]电子工业出版社[51单片机典型系统开发实例精讲]白延敏;[2]复旦大学出版社[单片微型机原理、应用和实验] 张友德;[3]海纳电子资讯网[IC中文资料];摘要时间是现代社会中不可缺少的一项参数,无论是平时生活还是社会生产都需要对时间进行控制,有的场合对其精确性还有很高的要求.采用单片机进行计时,对于社会生产有着十分重要的作用。
本文首先介绍了电子时钟的特点和功能,然后对单片机和LCD 显示做了详细的介绍,提出了系统总体设计方案,并设计了各部分硬件模块和软件流程,再用Protues软件进行了仿真和调试,结果证明了该设计系统的可行性。
由于AT89S52系列单片机的控制器运算能力强,处理速度快,可以精确计时,很好地解决了实际生产生活中对计时高精确度的要求,因此该设计在现代社会中具有广泛的适用性。
关键字:单片机;LCD1602液晶显示器;C程序设计目录第一章系统设计要求及功能51.1设计本电子定时闹钟的目的和意义51.2本LCD电子闹钟的特点和功能介绍51.2.1本电子钟设计特点51.2.2本电子钟的主要功能5第二章方案设计与比较62.1数字时钟方案62.2显示方案7第三章系统硬件的设计83.1单片机的选择及管脚介绍83.1.1单片机的选择及主要性能83.1.2单片机管脚介绍93.2LCD1602的管脚及功能介绍113.2.1引脚说明113.2.2控制器接口说明123.3总体设计133.3.1系统说明133.3.2整体系统框图133.4各部分功能实现143.5元件清单143.6电子钟电路原理图153.7时钟仿真各功能分析及图解16第四章软件总体设计方案204.1主程序流程图:204.2、闹钟的实现22第五章课程设计结果分析23致谢24参考文献25附录26<1)控制电路的C语言源程序26<2)8位数显时钟成品展示图35第一章系统设计要求及功能1.1 设计本电子定时闹钟的目的和意义1、复习和巩固所学过的知识,利用此毕业设计正好可以对所学过的知识进行系统的回顾和总结。
长沙学院《单片机原理及应用》课程设计说明书题目 LED数码管显示电子秒表设计系(部) **系专业(班级) *************姓名邹部长9931学号******指导教师***起止日期 2016.12.19—2016.12.24《单片机原理及应用》课程设计任务书1系(部):**系专业:******长沙学院课程设计鉴定表目录摘要 (5)第一章概述 (6)1.1电子秒表的设计要求 (6)1.2电子秒表的电路图 (6)1.3电子秒表的设计原理及方案 (7)第二章电子秒表的程序设计 (8)2.1 程序设计流程图 (8)2.2程序设计源代码 (10)第三章程序的调试 (16)第四章设计总结 (17)参考文献 (18)摘要随着经济与社会的发展对智能化和信息化技术要求的不断提高,单片机作为智能控制的核心,逐渐渗透到社会生产和生活的各个方面。
而本文则主要阐述基于单片机设计的数码管秒表,这次设计所采用的的单片机为stc89c52单片机,数码管则是使用2个4位共阴LED数码管组成的8位。
为减少I/O口,而使用了SM74HC138 和74HCT573这2片芯片实现数码管显示8位数据。
利用单片机内部定时器实现计时功能,分别显示为:分—秒—0.01秒。
控制则是使用一键控制,可实现计时开始,计时暂停,计时清零3个功能的循环。
本次的程序设计采用C语言编写,包括显示程序,定时中断服务程序,延时程序。
最后在单片机电路板来观察工作状态。
第一章概述1.1电子秒表的设计要求○1显示要求在初始状态显示的是00—00—00,最左边的2位显示分钟,中间2位显示秒,左边2位显示十分之一秒和百分之一秒,还有个2个LED数码管只显示中间那一段,用作间隔符。
○2然后还的有一个键用来控制秒表,要求按第一下开始计时,按第二下暂停计时,按第三下清零,以此往复循环控制。
○3使用单片机T0方式实现计时0.01秒。
1.2电子秒表的电路图1.3电子秒表的设计原理及方案设计原理根据单片机本身的定时计数器实现1秒的计时。
基于8位数码管的可调时钟时钟课程设计这个东西折腾我快两个月啊~!也是带啦做的不是一直在做是一边学习一边玩弄来的啊~!但是怎么说我也弄出来啊~!心里好满足啊~!因为这个可算是自己的成果。
也给谢谢这次课程设计因为就这个设计让我理解很多东西让我感觉进步很多。
现在就差自己做PCB 板啊~!然后就是全部搞定啊~!哈哈~!电路很简单8 位共阴数码管(如果没有买的可以买2 个四位数码管)段选接P2 口位选接p1 口,用stc 单片机可以直接连接,两个按键接p1.6 和p1.7,实现时间的调整功能.完整程序代码下载地址:51hei/f/dzszkt.rar这个就是我自己弄的程序小时钟的:#include#define uchar unsigned char#define uint unsigned intuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0xff};ucharcode kai[]={0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7};sbit tiao=P1;sb itgai=P1;u c h a r hour,min,sec,e,set,dada,x,i,j,u,v,w,s,m,n,p,q;void delay(uchar k){ uchar a,b;for(a=0;a3){ e=1;}delay(200);}//tiaozhengvoid display_h(void){P2=table[i];P1=kai[0];delay(20);P2=table[j];P1=kai[1];delay(20);P2=table[11];P1=kai[0];delay(20);P2=table[11];P1=kai[1];delay(20);i=hour/10;j=hour%1 0;}//display_hvoiddisplay_m(void){P2=table[u];P1=kai[3];delay(20);P2=table[v];P1=kai[4];delay(20);P2=table[11];P1=kai[3];delay(20);P2=table[11];P1=kai[4];delay(20);u=min/10;v=mi n%10;}//display_mvoid tiaozheng(void){ if(gai==0) TR0=0; KEY_tiao(); switch(e){ case 1 :{ if(tiao==0) { hour++; display_h(); if(hour>24) { hour=0; } } }//case 1 break; case 2 :{ if(tiao==0) { min++; display_m(); if(min>60) { min=0; } } }//case 2 break;}//switch}//tiaozhengtips:感谢大家的阅读,本文由我司收集整编。
8位动态LED数码管显示实验(精)8位动态LED数码管显示实验2008-03-18 18:048.1 实物图与原理图本实验仪配置带8位动态扫描显示模块一个。
实物图如下:为减少IO的使用,我们采用串入并出芯片CD4094来扩展了IO 口,即采用3个IO来实现数据的传输。
原理图如下:所以,我们占用3个IO来传输数据,8个IO来进行8个LED数码管的位选。
在本实验仪中链接管教分布如下:STK-----P2.5DAT-----P2.6CLK-----P2.7B0、B1、B2、B3、B4、B5、B6、B7接P0口(P0.0 P0.1 P0.2 P0.3 P0.4 P0.5P0.6 P0.7)由于上一节已经讲述了CD4094驱动一位LED数码管的问题,这里我们讲如何来扫描8位数码管。
8.2 LED动态显示原理根据原理图管脚连接,我们知道P0口控制了8个LED数码管的位选中,所以如果想让8个数码管都亮起来,我们可以逐位扫描8位数码管。
动态显示原理:原理上同一时刻只有一位LED是点亮的,但只要扫描的频率足够高(一般大于25Hz),由于人眼的视觉暂留特性,直观上感觉却是连续点亮的,这就是常说的动态扫描显示。
动态扫描的频率有一定的要求,频率太低,LED将出现闪烁现象。
如频率太高,由于每个LED点亮的时间太短,LED的亮度太低,所以一般均取几个ms左右为宜。
8.3 DG3000 动态显示头文件display_s.h//----------------------------------------------------------//程序作用:显示头文件display_s.h//----------------------------------------------------------#ifndef _display_#define _display_#includesbit SDA=P2^6; //定义显示管脚sbit CLK=P2^7;unsigned char data display_bit;unsigned char codeled[20]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0x 89,0x8C };//定义段码//延时程序void delay(unsigned int k){ unsigned int i,j;for(i=0;i<k;i++)< bdsfid="131" p=""></k;i++)<>for(j=0;j<100;j++);}//数据传输void send(unsigned char a){unsigned char i;for(i=0;i<8;i++){if(_crol_(a,i)&0x80)SDA=1;elseSDA=0;CLK=0;CLK=1;}}//显示程序 8位LED数码管扫描void display(unsigned chardisplay_buffer[8]){unsigned char i,k;display_bit=0xfe;for(i=0;i<8;i++){k=led[display_buffer[i]];send(k);P0=display_bit;delay(0x01);P0=0xff;display_bit=_crol_(display_bit,1);}display_bit=0xfe;8.4 8位数码管动态显示01234567(C51程序)//----------------------------------------------------------//程序作用:动态扫描显示01234567//---------------------------------------------------------- #include#include //调用显示头文件main(){unsigned chara[8]={0x0,0x1,0x2,0x3,0x4,0x5,0x6, 0x7};//显示01234567 while(1){display(a); //显示数据}}。
libraryieee;use ieee.std_logic_1164.all;useieee.std_logic_unsigned.all;entity qudong_8 isport(clk:instd_logic;--动态显示刷新速度时钟QQ:instd_logic_vector(31 downto 0);--32位BCD码输入,最0~3低位,28~31最高位qudong1:outstd_logic_vector(7 downto 0);--驱动信号输出,0~7分别为abcdefgpcontrl:bufferstd_logic_vector(2 downto 0)); --数码管位选输出,000最低位数码管有效,111最高位数码管有效end qudong_8;architecture behavior of qudong_8 issignaldisp:std_logic_vector(3 downto 0);signaltemp:std_logic_vector(2 downto 0);beginprocess(clk)beginifclk'event and clk='1' thentemp<=temp+1;end if;contrl<=temp;end process;process(contrl)--位选信号产生进程begincasecontrl iswhen"000"=>disp<=QQ(3 downto 0);when"001"=>disp<=QQ(7 downto 4);when"010"=>disp<=QQ(11 downto 8);when"011"=>disp<=QQ(15 downto 12);when"100"=>disp<=QQ(19 downto 16);when"101"=>disp<=QQ(23 downto 20);when"110"=>disp<=QQ(27 downto 24);when"111"=>disp<=QQ(31 downto 28);when others=>disp<="0000";end case;end process;process(disp)--译码进程begincasedisp iswhen"0000"=>qudong1<="00111111";when"0001"=>qudong1<="00000110"; when"0010"=>qudong1<="01011011"; when"0011"=>qudong1<="01001111"; when"0100"=>qudong1<="01100110"; when"0101"=>qudong1<="01101101"; when"0110"=>qudong1<="01111101"; when"0111"=>qudong1<="00000111"; when"1000"=>qudong1<="01111111"; when"1001"=>qudong1<="01101111"; when others=>qudong1<="00000000"; end case;end process;end behavior;。
use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;--------------------------------------------------------------------entity seg_display isport( clk : in std_logic; --定义动态扫描时钟信号reset : in std_logic; --定义复位信号ledag : out std_logic_vector(6 downto 0); --定义数码管的七段输出信号del : out std_logic_vector(2 downto 0) --定义八位数码管位置显示信号);end seg_display;--------------------------------------------------------------------architecture whphtao of seg_display issignal clk1Khz : std_logic; --数码管扫描时钟signal clk1hz : std_logic; --计数时钟signal cq : std_logic_vector(3 downto 0);--计数值beginPROCESS(clk) --产生1hz信号variable cnt : INTEGER RANGE 0 TO 49999999;BEGINIF clk='1' AND clk'event THENIF cnt=49999999 THEN cnt:=0;ELSEIF cnt<25000000 THEN clk1hz<='1';ELSE clk1hz<='0';END IF;cnt:=cnt+1;END IF;END IF;end process;PROCESS(clk) --产生1Khz信号variable cnt1 : INTEGER RANGE 0 TO 49999;BEGINIF clk='1' AND clk'event THENIF cnt1=49999 THEN cnt1:=0;ELSEIF cnt1<25000 THEN clk1khz<='1';ELSE clk1khz<='0';END IF;cnt1:=cnt1+1;END IF;END IF;process(clk1hz,reset)variable cqi : std_logic_vector(3 downto 0);beginif reset='0' then cqi:=(others =>'0');-- 计数器异步复位elsif clk1hz'event and clk1hz='1' then--检测时钟上升沿if cqi<15 then cqi:=cqi+1;else cqi:=(others =>'0');end if;--end if;end if;cq<=cqi;--计数值向端口输出end process;process(clk1KHZ) --数码管动态扫描variable dount : std_logic_vector(2 downto 0);beginif clk1kHZ'event and clk1kHZ='1' then--检测时钟上升沿dount:=dount+1;--计数器dount累加end if;del<=dount;end process;process(cq)--数码管显示begincase cq iswhen "0000" => ledag <="0111111";when "0001" => ledag <="0000110";when "0010" => ledag <="1011011";when "0011" => ledag <="1001111";when "0100" => ledag <="1100110";when "0101" => ledag <="1101101";when "0110" => ledag <="1111101";when "0111" => ledag <="0000111";when "1000" => ledag <="1111111";when "1001" => ledag <="1101111";when "1010" => ledag <="1110111";when "1011" => ledag <="1111100";when "1100" => ledag <="0111001";when "1101" => ledag <="1011110";when "1110" => ledag <="1111001";when "1111" => ledag <="1110001";when others => null;end case;end whphtao;。
8位数码管秒表C程序/***********************************************************实验名称:8位数码管秒表达例程序程序阐明:烧好程序,短接J1的左端,按下S6即可看到秒表运行,再按下S6秒表暂停计时,按第三下秒表归零。
作者:RF-X1开发板团体日期:-08-01***********************************************************/#include <reg51.h>#include <intrins.h>unsigned char data dis_digit;unsigned char key_s, key_v;unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3 0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, offunsigned char dis_buf[8]; // 显示缓冲区unsigned char sec_bcd[8]; // 秒计数值, BCD码unsigned char dis_index; //unsigned char key_times; // K1 按下次数 //void clr_time();void update_disbuf();bit scan_key();void proc_key();void delayms(unsigned char ms);sbit K1 = P3^2;/******************************************/ /* 主函数 */ /******************************************/ void main(void) {P0 = 0xff;P2 = 0xff;TMOD = 0x11; // 定时器0, 1工作模式1, 16位定时方式TH1 = 0xdc;TL1 = 0;TH0 = 0xFC;TL0 = 0x17;clr_time(); //dis_digit = 0x7f; // 初始显示P30口数码管dis_index = 0; //key_times = 0;key_v = 0x01;IE = 0x8a; // 使能timer0, timer1中断TR0 = 1;TR1 = 0;while(1){if(scan_key()){delayms(10);if(scan_key()){key_v = key_s;proc_key();}}}}/******************************************/ /* 清零 *//******************************************/ void clr_time(){sec_bcd[0] = 0x0;sec_bcd[1] = 0x0;sec_bcd[2] = 0x0;sec_bcd[3] = 0x0;sec_bcd[4] = 0x0;sec_bcd[5] = 0x0;sec_bcd[6] = 0x0;sec_bcd[7] = 0x0;update_disbuf();}/******************************************//* 键盘扫描子程序 */ /******************************************/ bit scan_key(){key_s = 0x00;key_s |= K1;return(key_s ^ key_v);}/******************************************//* 键盘解决子程序 */ /******************************************/ void proc_key(){if((key_v & 0x01) == 0){key_times++;if(key_times == 1){TR1 = 1;}else if(key_times == 2){TR1 = 0;}else{clr_time();key_times = 0;}}}/*******************************************//*定时器0中断服务程序, 用于数码管的动态扫描*//*dis_index --- 显示索引, 用于标记目前显示的数码管和缓冲区的偏移量 */ /*dis_digit --- 位选通值,传送到P2口用于选通目前数码管的数值, 如等于0xfe时,选通P2.0口数码管*/ /*dis_buf ---显于缓冲区基地址 *//******************************************/ void timer0() interrupt 1{TH0 = 0xFC;TL0 = 0x17;P2 = 0xff; // 先关闭全部数码管P0 = dis_buf[dis_index]; // 显示代码传送到P0口P2 = dis_digit; //dis_digit = _cror_(dis_digit,1); // 位选通值右移(P20<-P27),下次中断时选通下一位数码管dis_index++; //dis_index &= 0x07; //8个数码管全部扫描完一遍之后,再回到第一种开始下一次扫描}/******************************************/ /* 定时中断1 *//******************************************/ void timer1() interrupt 3 {unsigned char i;TH1 |= 0xdc;for(i = 0; i < 8; i++){sec_bcd[i]++; // 低位加1if(sec_bcd[i] < 10) // 如果低位满10则向高位进1break; // 低位未满10sec_bcd[i] = 0; // 低位满10清0}update_disbuf(); // 更新显示缓冲区}/******************************************/ /* 更新显示缓冲区 */ /******************************************/ void update_disbuf() {dis_buf[0] = dis_code[sec_bcd[7]];dis_buf[1] = dis_code[sec_bcd[6]];dis_buf[2] = dis_code[sec_bcd[5]];dis_buf[3] = dis_code[sec_bcd[4]];dis_buf[4] = dis_code[sec_bcd[3]];dis_buf[5] = dis_code[sec_bcd[2]]& 0x7f; // 加上小数点dis_buf[6] = dis_code[sec_bcd[1]];dis_buf[7] = dis_code[sec_bcd[0]]; }/******************************************//* 延时子程序 */ /******************************************/ void delayms(unsigned char ms) {unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}。
本人依据AT89C51和8位数码管为素材,以最少的见实现最多的功能! 本程序开机流动显示学号可实现时钟,日历,定时闹钟,秒表等功能!
C程序: #include
unsigned char led[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00}; //用一维数组定义-9、横杠、全灭
unsigned char num[12]={2,0,0,9,3,5,0,7,0,1,2,0} ; unsigned char a[8]; unsigned char second=0,minute=0,hour=0,year=0,mon=1,day=1,day1,hsec,sec_m,min_m,N,temp1; unsigned char minute1=0,hour1=0; unsigned char b[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //扫描 unsigned char k=0; unsigned int temp; // 记录毫秒为秒的变量 unsigned char M,S_flag; //M是模式,更新时间的种模式加上正常模式 S_flag闪烁标志 sbit K0=P3^7; //K0是闹钟起停标志位 sbit K1=P3^0; sbit K2=P3^1; sbit K3=P3^2; sbit BEEP=P3^3;
void delay(unsigned n) //0.2毫秒 { int x,y; for(x=0;xfor(y=0;y<24;y++); }
void init1() { S_flag=0; //闪烁标志位 TMOD=0x10; //定时器以方式定时 TH1=0xfc; TL1=0x18; EA=1; //打开总中断 ET1=1; //允许定时器中断 TR1=1; //开启定时器(开始定时计数)
} void init0() { TMOD=0x01; //定时器以方式定时 TH0=0xff; TL0=0xff; EA=1; //打开总中断 ET0=1; //允许定时器中断 TR0=0; //关闭定时器(关闭定时计数)
} void display_led() //流动显示学号 { int x; char l,a,m; for(a=0;a<21;a++) { x=a-8; for(l=0;l<6;l++) { for(m=0;m<8;m++) { P2=b[m]; if(x>=0&&x<12) P1=led[num[x]]; else P1=led[11];
delay(10); x++; } x-=8; } } } void display() //显示时钟及显示调节位 { switch(M) { case 0: { a[0]=led[hour/10]; a[1]=led[hour%10]; a[2]=led[10]; a[3]=led[minute/10]; a[4]=led[minute%10]; a[5]=led[10]; a[6]=led[second/10]; a[7]=led[second%10];
}break; case 1: { if(S_flag==1) { a[0]=led[hour/10]; a[1]=led[hour%10]; } else { a[0]=led[11]; a[1]=led[11]; } a[2]=led[10]; a[3]=led[minute/10]; a[4]=led[minute%10]; a[5]=led[10]; a[6]=led[second/10]; a[7]=led[second%10]; }break; case 2: { a[0]=led[hour/10]; a[1]=led[hour%10]; a[2]=led[10]; if(S_flag==1) { a[3]=led[minute/10]; a[4]=led[minute%10]; } else { a[3]=led[11]; a[4]=led[11]; } a[5]=led[10]; a[6]=led[second/10]; a[7]=led[second%10]; }break;
case 3: { if(S_flag==1) { a[0]=led[year/10]; a[1]=led[year%10]; } else { a[0]=led[11]; a[1]=led[11]; } a[2]=led[10]; a[3]=led[mon/10]; a[4]=led[mon%10]; a[5]=led[10]; a[6]=led[day/10]; a[7]=led[day%10]; }break; case 4: { a[0]=led[year/10]; a[1]=led[year%10]; a[2]=led[10]; if(S_flag==1) { a[3]=led[mon/10]; a[4]=led[mon%10]; } else { a[3]=led[11]; a[4]=led[11]; } a[5]=led[10]; a[6]=led[day/10]; a[7]=led[day%10]; }break; case 5: { a[0]=led[year/10]; a[1]=led[year%10]; a[2]=led[10]; a[3]=led[mon/10]; a[4]=led[mon%10]; a[5]=led[10]; if(S_flag==1) { a[6]=led[day/10]; a[7]=led[day%10]; } else { a[6]=led[11]; a[7]=led[11]; }
}break;
case 6: { if(S_flag==1) { a[0]=led[hour1/10]; a[1]=led[hour1%10]; } else { a[0]=led[11]; a[1]=led[11]; } a[2]=led[10]; a[3]=led[minute1/10]; a[4]=led[minute1%10]; a[5]=led[10]; a[6]=led[11]; a[7]=led[11]; }break; case 7: { a[0]=led[hour1/10]; a[1]=led[hour1%10]; a[2]=led[10]; if(S_flag==1) { a[3]=led[minute1/10]; a[4]=led[minute1%10]; } else { a[3]=led[11]; a[4]=led[11]; } a[5]=led[10]; a[6]=led[11]; a[7]=led[11]; }
} }
void key_prc() //时钟和闹钟调节 {
if(K1==0) { delay(10); //延时去抖 if(K1==0) //按K1进行模式切换 { M++; if(M==8) M=0; } while(!K1);//等待按键释放 } if(M!=0) { switch(M) { case 1: //模式--调时 { if(K2==0) { delay(10); //延时去抖 if(K2==0) //加键按下 { if(hour<23) hour++; else hour=0; } while(!K2); //等待按键释放 }
if(K3==0) { delay(10); if(K3==0) { if(hour> 0) hour--; else hour=23; } while(!K3); } } break;
case 2: //模式--调分 { if(K2==0) { delay(10); if(K2==0) { if(minute<59) minute++; else minute=0; } while(!K2); }