数码管电子秒表程序
8位数码管显示电子时钟c51单片机程序【精选】
8位数码管显示电子时钟c51单片机程序时间:2012-09-10 13:52:26 来源:作者:/*8位数码管显示时间格式 05—50—00 标示05点50分00秒S1 用于小时加1操作S2 用于小时减1操作S3 用于分钟加1操作S4 用于分钟减1操作*/#include<reg52.h>sbit KEY1=P3^0; //定义端口参数sbit KEY2=P3^1;sbit KEY3=P3^2;sbit KEY4=P3^3;sbit LED=P1^2; //定义指示灯参数code unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极数码管0—9unsigned char StrTab[8]; //定义缓冲区unsigned char minute=19,hour=23,second; //定义并初始化为 12:30:00void delay(unsigned int cnt){while(--cnt);}/******************************************************************//* 显示处理函数*//******************************************************************/void Displaypro(void){StrTab[0]=tab[hour/10]; //显示小时StrTab[1]=tab[hour%10];StrTab[2]=0x40; //显示"-"StrTab[3]=tab[minute/10]; //显示分钟StrTab[4]=tab[minute%10];StrTab[5]=0x40; //显示"-"StrTab[6]=tab[second/10]; //显示秒StrTab[7]=tab[second%10];}main(){TMOD |=0x01; //定时器0 10ms inM crystal 用于计时TH0=0xd8; //初值TL0=0xf0;ET0=1;TR0=1;TMOD |=0x10; //定时器1用于动态扫描TH1=0xF8; //初值TL1=0xf0;ET1=1;TR1=1;EA =1;Displaypro(); //调用显示处理函数while(1){if(!KEY1) //按键1去抖以及动作{delay(10000);if(!KEY1){hour++;if(hour==24)hour=0; //正常时间小时加1 Displaypro();}}if(!KEY2) //按键2去抖以及动作{delay(10000);if(!KEY2){hour--;if(hour==255)hour=23; //正常时间小时减1 Displaypro();}}if(!KEY3) //按键去抖以及动作{delay(10000);if(!KEY3){minute++;if(minute==60)minute=0; //分加1Displaypro();}}if(!KEY4) //按键去抖以及动作{delay(10000);if(!KEY4){minute--;if(minute==255)minute=59; //分减1Displaypro();}}}}/******************************************************************//* 定时器1中断 */ /******************************************************************/void time1_isr(void) interrupt 3 using 0 //定时器1用来动态扫描{static unsigned char num;TH1=0xF8; //重入初值TL1=0xf0;switch (num){case 0:P2=0;P0=StrTab[num];break; //分别调用缓冲区的值进行扫描 case 1:P2=1;P0=StrTab[num];break;case 2:P2=2;P0=StrTab[num];break;case 3:P2=3;P0=StrTab[num];break;case 4:P2=4;P0=StrTab[num];break;case 5:P2=5;P0=StrTab[num];break;case 6:P2=6;P0=StrTab[num];break;case 7:P2=7;P0=StrTab[num];break;default:break;}num++; //扫描8次,使用8个数码管if(num==8)num=0;}/******************************************************************//* 定时器0中断 */ /******************************************************************/void tim(void) interrupt 1 using 1{static unsigned char count; //定义内部局部变量TH0=0xd8; //重新赋值TL0=0xf0;count++;switch (count){case 0:case 20:case 40:case 60:case 80:Displaypro();break; //隔一定时间调用显示处理case 50:P1=~P1;break; //半秒 LED 闪烁default:break;}if (count==100){count=0;second++; //秒加1if(second==60){second=0;minute++; //分加1if(minute==60){minute=0;hour++; //时加1if(hour==24)hour=0;}}}}基于单片机的LCD1602控制总线模式时间:2012-09-10 13:50:39 来源:作者:第一行显示"Welcome";第二行显示="Happy day";若要显示其他字符,请直接往数组LCMLineOne[16]和LCMLineTwo[16]填充相应的代码。
51单片机流水灯、数码管、定时器、秒表、计算器程序
51单片机流水灯、数码管、定时器、秒表、计算器程序流水灯 #include<reg52.h>char data_group[]={0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e};unsigned int a;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=100;j>0;j--);}}void move_mid_side(void) {int m;for(m=0;m<7;m++){P1=data_group[m];delay(500);}}void move_right_only(void) {int a,temp;delay(500);temp=0x80;for(a=7;a>=0;a--){temp=~temp;P1=temp;delay(500);temp=~temp;temp>>=1;}temp=0x80;delay(1000);}void move_left_only(void) { int a,temp;delay(500);temp=0x01;for(a=7;a>=0;a--){temp=~temp;P1=temp;delay(500);temp=~temp;temp<<=1;}temp=0x01;delay(1000);}void move_right_hlod(void) { int a,temp;temp=0x7f;for(a=8;a>=0;a--){P1=temp;delay(500);temp=temp>>1;}temp=~temp;delay(1000);}void move_left_hold(void) { int a,temp;temp=0xfe;for(a=8;a>=0;a--){P1=temp;delay(500);temp<<=1;}temp=~temp;delay(1000);}void main(){while(1){move_left_hold();move_mid_side();move_right_hlod();move_mid_side();move_left_only();move_right_only();}}数码管 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00}; //0xff全关,之后为第一个数码管到第八个数码管//char data_wei_add[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}void show_number_only(void){int i;P2=data_wei[1]; //P2为位选for(i=0;i<10;i++){P0=data_duan[i]; //P0为段选delay(500);}}/*******************数码管动态显示子程序***************/ void move_show1(void){int i;for(i=1;i<2;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}void move_show2(void){int i;for(i=1;i<3;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}void move_show3(void) {int i;for(i=1;i<4;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show4(void) {int i;for(i=0;i<5;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show5(void) {int i;for(i=0;i<6;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show6(void) {int i;for(i=0;i<7;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show7(void) {int i;for(i=0;i<8;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show8(void) {int i;for(i=0;i<9;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}/********数码管动态显示,实现数码管由1~8在八个数码管上一次显示************/void move_show_hold(void){int temp,i;temp=1000;for(i=temp;i>0;i--)move_show1();temp=600;for(i=temp;i>0;i--)move_show2();temp=400;for(i=temp;i>0;i--)move_show3();temp=200;for(i=temp;i>0;i--)move_show4();temp=200;for(i=temp;i>0;i--)move_show5();temp=200;for(i=temp;i>0;i--)move_show6();temp=100;for(i=temp;i>0;i--)move_show7();temp=100;for(i=temp;i>0;i--)move_show8();}void show_all(void) //将所有的位选端口打开,变化段选,显示整体变化1~9{int i;P2=data_wei[9];for(i=0;i<10;i++){P0=data_duan[i];delay(500);}}int main(void) {while(1){// show_number_only();move_show8();//move_show_hold(); // show_all(); }}独立按键#include <reg52.h>sbit key1=P3^0; sbit d2=P1^0;int temp,number=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=100;j>0;j--) ;}}int main(void) {temp=0xfe;while(1){d2=1;key1=1;P1=temp;if(key1==0){delay(100);if(key1==0){number++;if(number<=7){temp=~temp;temp=temp<<1;temp=~temp;P1=temp;}else{temp=0xfe;number=0;}}}}}矩阵按键 #include<reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80 ,0xc6,0xc0,0x86,0x8e,};//0~9 chardata_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00};int number=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}//void move_show1(void)//{// int i;// for(i=1;i<2;i++){ // P2=data_wei[i]; // P0=data_duan[i]; // delay(1);// }//}//void move_show2(void)//{// int i;// for(i=1;i<3;i++){ // P2=data_wei[i];// P0=data_duan[i]; // delay(1);// }//}void scan_key(void){int temp;P1=0xfe;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=12;break; case 0xd0:number=13;break; case 0xb0:number=14;break; case 0x70:number=15;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfd;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=8;break; case 0xd0:number=9;break; case 0xb0:number=10;break; case 0x70:number=11;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfb;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=4;break; case 0xd0:number=5;break; case 0xb0:number=6;break; case 0x70:number=7;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=0;break; case 0xd0:number=1;break; case 0xb0:number=2;break; case 0x70:number=3;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}// return number;}int main(void){// int num=0;while(1){// num=scan_key(num);scan_key();P2=data_wei[1];P0=data_duan[number];}}定时器中断 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00}; //0xff全关,之后为第一个数码管到第八个数码管int number=0,time=0;int main(void){// TMOD=0x01;//设置工作方式定时器0// TH0=(65536-50000)/256; //给计数器装初值 // TL0=(65535-50000)%256;// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 // TR0=1; //启动定时器0TMOD=0x10;//设置工作方式定时器1TH1=(65536-50000)/256; //给计数器装初值TL1=(65535-50000)%256;EA=1; //开总中断ET1=1; //定时器T1中断允许TR1=1; //启动定时器1while(1){if(number==20){P2=data_wei[2];P0=data_duan[4];}if(time==40){P2=data_wei[0];number=0;time=0;}}}void exter3() interrupt 3{TH1=(65536-50000)/256; //给计数器装初值TL1=(65535-50000)%256;time++;number++;}//void exter1() interrupt 1//{// TH0=(65536-50000)/256; //给计数器装初值 // TL0=(65535-50000)%256;// time++;// number++;//}时钟 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00};unsigned long int second=0,minute=0,hour=0,point=0,tip=0;unsigned long int time=0,sign=0,number=0,key=0,variable=0; unsigned long int S1=0,S2=0,M1=0,M2=0,H1=0;H2=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}void key_scan(void){int temp; //应用按键检测P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=1;break; case 0xd0:number=2;break; case 0xb0:number=3;break; case 0x70:number=4;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}// P1=0xfb;// temp=P1;// temp=temp&0xf0; // while(temp!=0xf0){ // delay(1);// temp=P1;// temp=temp&0xf0; // while(temp!=0xf0){ // switch(temp){ // case 0xe0:number=5;break; // case 0xd0:number=6;break; // case0xb0:number=7;break; // case 0x70:number=8;break; // } // while(temp!=0xf0){ // temp=P1;// temp=temp&0xf0; // }// }////// }}void adjust_alarm(void) {if(number==1){ //控制时钟的启动与停止key=!key;if(key==1){EA=0;variable=time;}if(key==0){EA=1;}number=0;}if(number==2){ //调节时间选择标志位tip=tip+1;tip=tip%6;if(tip==0){tip=6;}number=0;}if((number==3)&&(EA==0)){if(tip==1)time=time-1;if(tip==2)time=time-10;if(tip==3)time=time-60;if(tip==4)time=time-600;if(tip==5)time=time-3600;if(tip==6)time=time-36000;number=0;}if((number==4)&(EA==0)){if(tip==1)time=time+1;if(tip==2)time=time+10;if(tip==3)time=time+60;if(tip==4)time=time+600;if(tip==5)time=time+3600;if(tip==6)time=time+36000;number=0;}// if((number==5)&&(EA==0)){ // if(tip==1) // variable=variable-1; // if(tip==2)// variable=variable-10; // if(tip==3)// variable=variable-60; // if(tip==4)// variable=variable-600; // if(tip==5)// variable=variable-3600; // if(tip==6)// variable=variable-3600; // number=0;// }// if((number==6)&(EA==0)){ // if(tip==1)// variable=variable+1; // if(tip==2)// variable=variable+10; // if(tip==3)// variable=variable+60; // if(tip==4)// variable=variable+600; // if(tip==5)// variable=variable+3600; // if(tip==6)// variable=variable+36000; // number=0;// }}void compare_time(void){if(time>variable){;}}void alarm_show_s(void){int sign2;for(sign2=1;sign2<2;sign2++){ //数码管动态显示S1=second%10;P2=data_wei[sign2];P0=data_duan[S1];delay(1);}for(sign2=2;sign2<3;sign2++){ S2=second/10;P2=data_wei[sign2];P0=data_duan[S2];delay(1);}for(sign2=3;sign2<4;sign2++){ P2=data_wei[sign2];P0=0xbf;delay(1);}for(sign2=4;sign2<5;sign2++){ M1=minute%10;P2=data_wei[sign2];P0=data_duan[M1];delay(1);}for(sign2=5;sign2<6;sign2++){ M2=minute/10;P2=data_wei[sign2];P0=data_duan[M2];delay(1);}for(sign2=6;sign2<7;sign2++){P2=data_wei[sign2];P0=0xbf;delay(1);}for(sign2=7;sign2<8;sign2++){H1=hour%10;P2=data_wei[sign2];P0=data_duan[H1];delay(1);}for(sign2=8;sign2<9;sign2++){H2=hour/10;P2=data_wei[sign2];P0=data_duan[H2];delay(1);}}void record_set_alarm(void) //设定闹钟所改变的值 { second=variable%60;minute=variable/60%60;hour=variable/3600%24;if(hour==24){variable=0;}}void record_time(void) {second=time%60;minute=time/60%60; hour=time/3600%24;if(hour==24){time=0;}}int main(void){TMOD=0x01;TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1;ET0=1;TR0=1;while(1){record_time();// record_set_alarm(); alarm_show_s();key_scan();adjust_alarm();}}void extern1() interrupt 1 //定时器中断0 { TH0=(65536-50000)/256; //重装值TL0=(65536-50000)%256;sign++;if(sign==20){time++;sign=0;}}。
0-99S的秒表计时器程序与调试
设计要求:1.设计一个秒表/计时器系统,显示时间为00.00~99.99秒,个位每秒自动加一。
2.设计一个按键,一上电数码管显示四个0,按一下按键秒表开始计时,按第二下秒表停止计时,保持数码管显示的值,按第三下秒表归零。
一.程序代码#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit SB0=P3^0;sbit SB1=P3^1;sbit SB2=P3^2;uchar codesmgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x80};uchar Xian[]={10,10,10,10,10,10,10,10,};uint Time=0;bit ST=0;void delayms(uint x){ uchar i;while(x--)for(i=0;i<125;i++);}void main(){TMOD=0x11;TH0=(65536-2000)>>8;TL0=(65536-2000)&0xff;TH1=(65536-10000)>>8;TL1=(65536-10000)&0xff;TR1=1;ET1=1;TR0=1;ET0=1;EA=1;while(1){if(SB0==0){ST=1;}if(SB1==0){ST=0;}if(SB2==0){ ST=0;Time=0;}}}void ET_1() interrupt 1 {static uchar j=0;static uchar i=7;TH0=(65536-2000)>>8;TL0=(65536-2000)&0xff;P0=0x00;P2=j<<2|0x03;P0=smgduan[Xian[i]];j++;i--;if(j==8){j=0;i=7;}}void ET_3() interrupt 3{TH1=(65536-10000)>>8;TL1=(65536-10000)&0xff;if(ST){Time++;if(Time==9999){ST=0;}}Xian[0]=Time/1000;Xian[1]=Time/100%10;Xian[2]=11;Xian[3]=Time/10%10;Xian[4]=Time%10;}二.仿真调试图1.原理图2.调试图。
51单片机4位数码管秒表代码
主题:51单片机4位数码管秒表代码内容:1. 介绍51单片机51单片机是一种通用的单片机系列,广泛应用于各种电子设备中。
它具有稳定性好、成本低、易于编程等优点,因此备受电子爱好者和专业工程师的青睐。
2. 4位数码管秒表4位数码管秒表是一种常见的电子计时器,通过LED数码管显示出当前的时间,可以用于各种计时应用,比如比赛计时、实验计时等。
3. 代码编写以下是一段简单的51单片机4位数码管秒表代码:```c#include <reg52.h>#include <intrins.h>// 数码管位选端口sbit wei1 = P2^2;sbit wei2 = P2^3;sbit wei3 = P2^4;sbit wei4 = P2^5;// 数码管显示段选端口sbit se2 = P0^2;sbit se1 = P0^3;sbit se4 = P0^4;sbit se3 = P0^5;unsigned char code smgduan[17] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; // 显示0~9,A,b,C,d,E,F,无的值void delay(unsigned int i) { // 延时while(i--);}void display(unsigned char *tab) { // 数码管显示 unsigned char i;for(i=0; i<7; i++) {P0=0; // 清除段选,以选中所显示的数码管 switch(i) { //确定位选case(0):wei1=0;wei2=wei3=wei4=1;break;case(1):wei2=0;wei1=wei3=wei4=1;break;case(2):wei3=0;wei1=wei2=wei4=1;break;case(3):wei4=0;wei1=wei2=wei3=1;break;default:break;}P0=tab[i]; //段码输出delay(5); // 数码管微秒级延迟}}void m本人n() {unsigned char a=0,b=0,c=0,d=0; //时钟的4位数据 unsigned int i=0;wei1=wei2=wei3=wei4=1; //段选、位选初始化while(1) {a++; // 微秒级的计数if(a==100) { //达到100a=0; b++; //b加1if(b==60) { //当b=60时b=0; c++; //c加1if(c==60) { //当c=60时c=0; d++; //d加1if(d==24) { //当d=24时d=0; //归零}}}}display(smgduan+d10); //显示个秒wei1=1;wei2=wei3=wei4=0; //位选delay(500); //延时display(smgduan+c/10+10); //显示十秒wei2=1;wei1=wei3=wei4=0; //位选delay(500); //延时display(smgduan+b10); //显示个分wei3=1;wei1=wei2=wei4=0; //位选delay(500); //延时display(smgduan+b/10+10); //显示十分wei4=1;wei1=wei2=wei3=0; //位选delay(500); //延时if(i++==200) { //当i=200时i=0;}}}```4. 代码分析该代码通过对51单片机的引脚进行控制,实现了4位数码管秒表的计时功能。
汇编程序-电子秒表的制作子秒表的设计
微机原理课程设计:电子秒表的制作子秒表的设计一、设计要求利用8253a,用实验箱上的数码管模拟一个秒表,要求具有一般秒表的功能。
二、设计内容1、能显示实时时间(时间可用实验箱上的按键进行调整)。
时间值的变化可采用查询8253a的计数器值来进行计算。
2、按“1”键时,进入秒表准备状态,再按“1”键开始秒表计时(计时单位为1/100秒),再按“1”键时停止秒表计时。
秒表计时的时间在数码管上显示。
3、按“2”键退出秒表计时状态,显示实时时间。
STACK1 SEGMENT STACKDW 200 DUP (?)TP DB 256 DUP(0)TPP EQU LENGTH TPSTACK1 ENDSDATA SEGMENTMESS DB 0AH,0DH,' >>WELCOME to USE!<<',0AH,0DH,0AH,0DHDB ' ***************>>ELECTRONICCLOCK<<****************',0AH,0DHDB ' * *',0AH,0DHDB ' * MAJOR : ELECTRONIC INFORMATION*',0AH,0DHDB ' * CLASS : 0304 *',0AH,0DHDB ' * NO : 16 *',0AH,0DHDB ' * NAME : Yang Shiwei *',0AH,0DHDB ' * TEACHER:XIAO FENG *',0AH,0DHDB ' * *',0AH,0DHDB '****************************************************','$'DBUFFER DB 8 DUP (':'),12 DUP (' ')STR1 DB 0DH,0AH, 0AH,0DH,' PLEASE INPUT TIME(T) OR STOPWATCH(S)OR QUIT(Q) OR RESET(R) OR PAUSE(P):$'STR2 DB 0DH,0AH,0DH,0AH,' The current time is : $'COUNT DB 0T1 DB ' The stopwatch time is:'TENH DB 30HHOUR DB 30HDB ':'MINUTE DB 30HDB ':'TENS DB 30HSECOND DB 30H,13,'$' ;不换行DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK1START: MOV AX,DATAMOV DS,AXMOV ES,AXCALL CLEAR ;调用清屏子程序MOV AH,02HMOV DX,0000H ;定显示位置MOV BH,0INT 10HLEA DX,MESSMOV AH,09HINT 21HLEA DX,STR1 ;显示提示信息MOV AH,09INT 21HA: MOV AH,1 ;从键盘输入单个字符INT 21HCMP AL,'S'JNE BCALL STOPWATCHB: CMP AL,'T' ;AL='T'?JNE DCALL TIME ;显示系统时间D: CMP AL,'Q' ;AL='Q'?JNE STARTMOV AH,4CH ;返回dos状态INT 21HSTOPWATCH PROCMOV DX,0F1FH ;定时间显示颜色位置MOV CX,8 ;显示颜色长度MOV BX,02CH ;设置背景颜色(2)和前景颜色(C) MOV AX,1300HINT 10HMOV AH,02HMOV DX,0F00H ;定显示位置MOV BH,0INT 10HMOV AX,0PUSH AXCLIMOV AX,DATAMOV DS,AXMOV AX,STACK1MOV SS,AXMOV SP,TPPMOV AX,351CHINT 21HPUSH BXPUSH ESMOV DX,SEG TIMERMOV DS,DXLEA DX,TIMERMOV AX,251CHINT 21HMOV AX,DATAMOV DS,AX CHECK: MOV AH,1INT 16HJZ TICKON2E: CLIMOV AH,00HINT 16HCMP AL,'S'JE TICKONCMP AL,'P'JE TICKON1CMP AL,'R'JE RESETCMP AL,'T'JE TCMP AL,'Q'JE TICKOFFJMP TICKONT: JMP STARTTICKON1: MOV AX,DATAMOV DS,AXMOV AX,351CHINT 21HMOV DX,SEG TIMER1MOV DS,DXLEA DX,TIMER1MOV AX,251CHINT 21HMOV AX,DATAMOV DS,AXJMP ERESET: MOV COUNT,0MOV SECOND,30HMOV TENS,30HMOV MINUTE, 30HMOV TENM,30HMOV HOUR, 30HMOV TENH,30HMOV DX,OFFSET T1MOV AH,9INT 21HMOV AH,0INT 16HCMP AL,'Q'JE TICKOFFCMP AL,'S'JNE RESETTICKON: MOV AX,351CHINT 21HMOV DX,SEG TIMERMOV DS,DXLEA DX,TIMERMOV AX,251CHINT 21HMOV AX,DATAMOV DS,AXTICKON2: MOV DX,OFFSET T1MOV AH,9INT 21HJMP CHECKTICKOFF: CLIPOP DSPOP DXMOV AX,251CHINT 21HSTI MOV AH,4CHINT 21HRETSTOPWATCH ENDPTIMER1 PROCIRETTIMER1 ENDPTIMER PROC FARPUSH AXMOV AX,DATAMOV DS,AXASSUME DS:DATAINC COUNTCMP COUNT,18JL EXIT ;计数不满18跳回 MOV COUNT,0 ;计数满18清0重置 INC SECOND ;秒加1CMP SECOND,39HJLE EXITMOV SECOND,30H ;等于9清0重计INC TENS ;十位加一CMP TENS,36HJL EXITMOV TENS,30HINC MINUTECMP MINUTE,39HJLE EXITMOV MINUTE, 30HINC TENMCMP TENM,36HJL EXITMOV TENM,30HINC HOURCMP HOUR,39HJLE EXITMOV HOUR, 30HINC TENHCMP TENH,32HJE TIME1JL EXITTIME1: CMP HOUR , 34HJL EXITMOV TENH,30HEXIT: POP AXIRETTIMER ENDPTIME PROC NEAR ;显示时间子程序MOV AH,02HMOV DX,0D25H ;定显示位置MOV BH,0INT 10HLEA DX,STR2MOV AH,9INT 21HDISPLAY1: MOV SI,0MOV BX,100DIV BLMOV AH,2CH ;取时间INT 21HMOV AL,CHCALL BCDASC ;将时间数值转换成ASCII码字符 INC SIMOV AL,CLCALL BCDASCINC SIMOV AL,DHCALL BCDASCMOV BP,OFFSET DBUFFERMOV DX,0F1FH ;定时间显示颜色位置MOV CX,8 ;显示颜色长度MOV BX,02CH ;设置背景颜色(2)和前景颜色(C) MOV AX,1300HINT 10HMOV AH,02HMOV DX,0F26H ;定显示位置,光标MOV BH,0INT 10HMOV BX,0018RE: MOV CX,0FFFFHREA: LOOP READEC BXJNZ REMOV AH,01HINT 16HJE DISPLAY1JMP AMOV AX,4C00HINT 21HRETTIME ENDPBCDASC PROC NEAR ;时间数值转换成ASCII码字符子程序PUSH BXCBWMOV BL,10DIV BLADD AL,'0'MOV DBUFFER[SI],ALINC SIADD AH,'0'MOV DBUFFER[SI],AHINC SIPOP BXRETBCDASC ENDPCLEAR PROC NEARPUSH AX ;入栈保护现场PUSH BXPUSH CXPUSH DXMOV AX,0600H ;ah=06(滚动)al=00(全屏空白) MOV BH,02FH ;设置背景颜色(2)和前景颜色(f) SUB CX,CXMOV DX,5F5FHINT 10HPOP DX ;出栈恢复现场POP CXPOP BXPOP AXRETCLEAR ENDPCODE ENDSEND START。
实验5.电子秒表显示器
,0x7d,0x07,0x7f,0x6f};//0-9数码管段码
timer0() interrupt 1//T0中断函数声明
/*以下函数实现秒计数
实现方式为:
count自增,若count=20则count清零,s增1*/
软件编程原理:采用T0定时方式1中断法编程,其中1s定时采用20次50ms定时采用20次50ms定时中断的方案实现,编程流程图如图A.66所示。
【实验内容】
(1)理解定时器的工作原理,完成定时中断程序的编写与调试;
(2)练习μVision3与ISIS的联机仿真方法。
【实验步骤】
(1)提前阅读与实验5相关的阅读材料;
while(1);//无限循环
}【仿真截ຫໍສະໝຸດ 】略【实验小结】通过这次实验,我掌握C51程序编写与调试方法,并且对定时器和计数器的工作原理有了一定的了解,学会了如何编写中断程序及如何使用定时器和计数器完成一些功能,在以后的学习过程中还要多动手练习。
(2)参考图A.65;和表A.6,在ISIS中完成原理图的绘制;
(3)在KeilμVision3中编写和编译C51程序,并生成可执行文件;
(4)在μVision3中启动ISIS的仿真运行,并进行联机调试。
【实验要求】
提交实验报告并包括如下内容:电路原理图、C51源程序(含注释语句)、软件调试分析、仿真运行截图及实验小结。
R2~8/1k
RES
Resistors
R1/100Ω
RES
Optoelectronics
LED1~LED2
7SEG-COM-CAT-GRN
自己用单片机数码管做的秒表
bai,uint
shi,uint
ge,uint
doufrist,uint
dousecond){closedu=0xff;closewe=0xff;wenum=0;P1=wetable[wenum];P0=dutable[
bai];delay(1);P1=closewe;P0=closedu;wenum++;P1=wetable[wenum];P0=dutable[sh
自己用单片机数码管做的秒表
基于 51hei 单片机开发板电路图可从官网去下载,p1 为位选 p0 为段选/*
实现功能,数码管前五位计数,显示时间的变化,误差
1/1000s*/#include#include#define uint unsigned int#define uchar unsigned charuchar
TMOD=0x01;TH0=(65536-10000)/256;TL0=(65536-
10000)%256;EA=1;ET0=1;TR0=1;}
void delay(uint z)//延时 1ms{uint x,y;for(x=z;x>0;x--){for(y=0;yvoid display(uint
void main(){init();while(1){display(bai,shi,ge,doufirst,dousecond);}}
void
init(){num=0;dounum=0;doucount=0;decimal=0x80;count=0;wenum=0;closedu=0xf
f;closewe=0xff;P1=closewe;//关闭位选 P0=closedu;//关闭段选
1{TH0=(65536-10000)/256;TL0=(65536-
单片机+数码管简单秒表程序,带停止启动复位
单片机+数码管简单秒表程序,带停止启动复位p0 口是数码管的位选入口,P2 口是数码管的段选用4 位一体的数码管,P3.0 P3.1 P3.2 分别是启动停止和复位按钮#include #define uchar unsigned char#define uint unsigned int#define DATA P2sbit start=P3;sbit stop=P3;sb it reset=P3 ;//---------启停标志-----bit SAT=0;bit RST=0;//------------数码管码表----------uchar tab[10]={0x3F, 0x06, 0x5B, 0x4F,0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};//------------uint time=0; //时间uint cnt=0; //计数//-------------void delay(int k){while(k--);}void startkey(){static uchar i,j;if(start==0){if(i==0){j++; if(j>3){ if(start==0){i=1;j=0;SAT=1;}}}}else{i=j=0;}}void stopkey(){static uchar i,j; if(stop==0){if(i==0){j++;if(j>3){ if(stop==0){i=1;j=0; SAT=0;}}}}else{i=j=0;}}void resetkey(){static uchar i,j; if(reset==0){if(i==0){j++; if(j>3){ if(reset==0){i=1;j=0; RST=1;}}}}else{i=j=0;RST=0;}}//---------数码管显示00.0-------void shownumber(int num) {DATA=tab[num%10];P0=7;delay(100);DATA=0x80;P0=6;delay(100);DATA=tab[ num%100/10];P0=5;delay(100);DATA=tab[num/100];P0=4;delay(100);}//---------定时器初始化ˉ---------void time0_init(){TMOD=0x01;TH0=(65536-18348)/256;TL0=(65536-18348)%256;EA=1;ET0=1;}void T0_time()interrupt1{TH0=(65536-18348)/256;TL0=(65536-18348)%256;cnt++;if(cnt==5){time++;cnt=0;}}voidmain(void){delay(50000);time0_init();while(1){shownumber(time);if(SAT==1)TR0=1;if(SAT==0)TR0=0;if(RST==1){TR0=0;SAT=0;time=0;}startkey();stopkey();rese tkey();}}tips:感谢大家的阅读,本文由我司收集整编。
数码管电子秒表程序
数码管电子秒表程序8位数码管电子秒表,显示精确到0.01秒。
使用共阳数码管,51单片机的P0口输出段码,P2口输出位码。
晶振11.0592MHz。
控制按钮K1接P1.0口,单片机检测低电平。
第一次按下时,启动开始计时;第二次按下时,停止计时、显示当前值;第三次按下时,显示归零,做好重新计时准备。
完整源程序:#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, off unsigned 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 = P1^0;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; // 初始显示P20口数码管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;}}}void timer0() interrupt 1// 定时器0中断服务程序, 用于数码管的动态扫描// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,// 选通P2.0口数码管// dis_buf --- 显于缓冲区基地址{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个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描}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[0]];dis_buf[1] = dis_code[sec_bcd[1]];dis_buf[2] = dis_code[sec_bcd[2]] & 0x7f; // 加上小数点dis_buf[3] = dis_code[sec_bcd[3]];dis_buf[4] = dis_code[sec_bcd[4]];dis_buf[5] = dis_code[sec_bcd[5]];dis_buf[6] = dis_code[sec_bcd[6]];dis_buf[7] = dis_code[sec_bcd[7]];}void delayms(unsigned char ms)// 延时子程序{unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}#include<reg52.h>sbit ksec=P3^0;sbit kmin=P3^1;sbit khour=P3^2;sbit P33=P3^3;unsigned charsecshi=0,secge=0,minshi=0,minge=0,hourshi=0,hourge=0;unsigned int num=0,sec=0,min=0,hour=0,x,n;unsigned char code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};void delay(unsigned int);void keyscan();void display();main(){ TMOD=0x11;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TH1=(65536-50000)/256;TL1=(65536-50000)%256;EA=1;ET0=1;TR0=1; TR1=0; ET1=1; while(1){display();keyscan();}}void delay(unsigned int z) {unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void time0() interrupt 1{num++;TH1=(65536-50000)/256;TL1=(65536-50000)%256;}void time1() interrupt 3{n++;TH0=(65536-50000)/256;TL0=(65536-50000)%256;}void display(){if(min==0){TR1=1;}else{TR1=0;}if(n>10){n=0;P33=~P33;}if(num==20){num=0;sec++;if(sec==60){sec=0;min++;if(min==60){min=0;hour++;if(hour==24) {hour=0;min=0;sec=0;}}}}secge=sec%10; secshi=sec/10; minge=min%10; minshi=min/10; hourge=hour%10; hourshi=hour/10; P2=1;P0=table[secge]; delay(5);P2=2;P0=table[secshi]; delay(5);P2=4;P0=191;delay(5);P2=8;P0=table[minge]; delay(5);P2=16;P0=table[minshi]; delay(5);P2=32;P0=191;delay(5);P2=64;P0=table[hourge]; delay(5);P2=128;P0=table[hourshi]; delay(5);}void keyscan() {if(ksec==0){delay(10);if(ksec==0){sec++;if(sec>=60)sec=0;}while(ksec==0) display();}if(kmin==0){delay(10);if(kmin==0){min++;if(min>=60)min=0;}while(kmin==0) display();}if(khour==0){delay(10);if(khour==0){hour++;if(hour>=24) hour=0;}while(khour==0) display();}}。
LED数码管秒表的制作
LED数码管秒表的制作
一、课程设计要求及原始资料:
制作一个LED数码管显示的秒表,用2位数码管显示计时时间,最小计时单位为“百毫秒”,计时范围0.1~9.9s。
当第一次按下并松开计时功能键时,秒表开始计时并显示时间;
当第二次按下并松开计时功能键时,停止计时,计算两次按下计时功能键的时间,并把时间值送入数码管显示;
当第三次按下计时功能键时,秒表清零,等待下一次按下计时功能键。
如果计时到9.9s时,将停止计时,按下计时功能键,秒表清零,再按下重新开始计时。
二、课程设计进度:
三、主要参考文献:
[1]张毅刚.单片机原理及应用[M].北京:高等教育出版社,2010
[2]张毅刚.单片机原理及接口技术[M].北京:人民邮电出版社,2008
[3]张毅刚.基于Proteus的单片机课程的基础实验与课程设计[M].北京:人民邮
电出版社,2013
专业班级学生课程设计工作起止时间
课程设计评语。
51单片机流水灯、数码管、定时器、秒表、计算器程序
51单片机流水灯、数码管、定时器、秒表、计算器程序流水灯 #include<reg52.h>char data_group[]={0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e};unsigned int a;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=100;j>0;j--);}}void move_mid_side(void) {int m;for(m=0;m<7;m++){P1=data_group[m];delay(500);}}void move_right_only(void) {int a,temp;delay(500);temp=0x80;for(a=7;a>=0;a--){temp=~temp;P1=temp;delay(500);temp=~temp;temp>>=1;}temp=0x80;delay(1000);}void move_left_only(void) { int a,temp;delay(500);temp=0x01;for(a=7;a>=0;a--){temp=~temp;P1=temp;delay(500);temp=~temp;temp<<=1;}temp=0x01;delay(1000);}void move_right_hlod(void) { int a,temp;temp=0x7f;for(a=8;a>=0;a--){P1=temp;delay(500);temp=temp>>1;}temp=~temp;delay(1000);}void move_left_hold(void) { int a,temp;temp=0xfe;for(a=8;a>=0;a--){P1=temp;delay(500);temp<<=1;}temp=~temp;delay(1000);}void main(){while(1){move_left_hold();move_mid_side();move_right_hlod();move_mid_side();move_left_only();move_right_only();}}数码管 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00}; //0xff全关,之后为第一个数码管到第八个数码管//char data_wei_add[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}void show_number_only(void){int i;P2=data_wei[1]; //P2为位选for(i=0;i<10;i++){P0=data_duan[i]; //P0为段选delay(500);}}/*******************数码管动态显示子程序***************/ void move_show1(void){int i;for(i=1;i<2;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}void move_show2(void){int i;for(i=1;i<3;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}void move_show3(void) {int i;for(i=1;i<4;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show4(void) {int i;for(i=0;i<5;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show5(void) {int i;for(i=0;i<6;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show6(void) {int i;for(i=0;i<7;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show7(void) {int i;for(i=0;i<8;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show8(void) {int i;for(i=0;i<9;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}/********数码管动态显示,实现数码管由1~8在八个数码管上一次显示************/void move_show_hold(void){int temp,i;temp=1000;for(i=temp;i>0;i--)move_show1();temp=600;for(i=temp;i>0;i--)move_show2();temp=400;for(i=temp;i>0;i--)move_show3();temp=200;for(i=temp;i>0;i--)move_show4();temp=200;for(i=temp;i>0;i--)move_show5();temp=200;for(i=temp;i>0;i--)move_show6();temp=100;for(i=temp;i>0;i--)move_show7();temp=100;for(i=temp;i>0;i--)move_show8();}void show_all(void) //将所有的位选端口打开,变化段选,显示整体变化1~9{int i;P2=data_wei[9];for(i=0;i<10;i++){P0=data_duan[i];delay(500);}}int main(void) {while(1){// show_number_only();move_show8();//move_show_hold(); // show_all(); }}独立按键#include <reg52.h>sbit key1=P3^0; sbit d2=P1^0;int temp,number=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=100;j>0;j--) ;}}int main(void) {temp=0xfe;while(1){d2=1;key1=1;P1=temp;if(key1==0){delay(100);if(key1==0){number++;if(number<=7){temp=~temp;temp=temp<<1;temp=~temp;P1=temp;}else{temp=0xfe;number=0;}}}}}矩阵按键 #include<reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80 ,0xc6,0xc0,0x86,0x8e,};//0~9 chardata_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00};int number=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}//void move_show1(void)//{// int i;// for(i=1;i<2;i++){ // P2=data_wei[i]; // P0=data_duan[i]; // delay(1);// }//}//void move_show2(void)//{// int i;// for(i=1;i<3;i++){ // P2=data_wei[i];// P0=data_duan[i]; // delay(1);// }//}void scan_key(void){int temp;P1=0xfe;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=12;break; case 0xd0:number=13;break; case 0xb0:number=14;break; case 0x70:number=15;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfd;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=8;break; case 0xd0:number=9;break; case 0xb0:number=10;break; case 0x70:number=11;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfb;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=4;break; case 0xd0:number=5;break; case 0xb0:number=6;break; case 0x70:number=7;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=0;break; case 0xd0:number=1;break; case 0xb0:number=2;break; case 0x70:number=3;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}// return number;}int main(void){// int num=0;while(1){// num=scan_key(num);scan_key();P2=data_wei[1];P0=data_duan[number];}}定时器中断 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00}; //0xff全关,之后为第一个数码管到第八个数码管int number=0,time=0;int main(void){// TMOD=0x01;//设置工作方式定时器0// TH0=(65536-50000)/256; //给计数器装初值 // TL0=(65535-50000)%256;// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 // TR0=1; //启动定时器0TMOD=0x10;//设置工作方式定时器1TH1=(65536-50000)/256; //给计数器装初值TL1=(65535-50000)%256;EA=1; //开总中断ET1=1; //定时器T1中断允许TR1=1; //启动定时器1while(1){if(number==20){P2=data_wei[2];P0=data_duan[4];}if(time==40){P2=data_wei[0];number=0;time=0;}}}void exter3() interrupt 3{TH1=(65536-50000)/256; //给计数器装初值TL1=(65535-50000)%256;time++;number++;}//void exter1() interrupt 1//{// TH0=(65536-50000)/256; //给计数器装初值 // TL0=(65535-50000)%256;// time++;// number++;//}时钟 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00};unsigned long int second=0,minute=0,hour=0,point=0,tip=0;unsigned long int time=0,sign=0,number=0,key=0,variable=0; unsigned long int S1=0,S2=0,M1=0,M2=0,H1=0;H2=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}void key_scan(void){int temp; //应用按键检测P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=1;break; case 0xd0:number=2;break; case 0xb0:number=3;break; case 0x70:number=4;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}// P1=0xfb;// temp=P1;// temp=temp&0xf0; // while(temp!=0xf0){ // delay(1);// temp=P1;// temp=temp&0xf0; // while(temp!=0xf0){ // switch(temp){ // case 0xe0:number=5;break; // case 0xd0:number=6;break; // case0xb0:number=7;break; // case 0x70:number=8;break; // } // while(temp!=0xf0){ // temp=P1;// temp=temp&0xf0; // }// }////// }}void adjust_alarm(void) {if(number==1){ //控制时钟的启动与停止key=!key;if(key==1){EA=0;variable=time;}if(key==0){EA=1;}number=0;}if(number==2){ //调节时间选择标志位tip=tip+1;tip=tip%6;if(tip==0){tip=6;}number=0;}if((number==3)&&(EA==0)){if(tip==1)time=time-1;if(tip==2)time=time-10;if(tip==3)time=time-60;if(tip==4)time=time-600;if(tip==5)time=time-3600;if(tip==6)time=time-36000;number=0;}if((number==4)&(EA==0)){if(tip==1)time=time+1;if(tip==2)time=time+10;if(tip==3)time=time+60;if(tip==4)time=time+600;if(tip==5)time=time+3600;if(tip==6)time=time+36000;number=0;}// if((number==5)&&(EA==0)){ // if(tip==1) // variable=variable-1; // if(tip==2)// variable=variable-10; // if(tip==3)// variable=variable-60; // if(tip==4)// variable=variable-600; // if(tip==5)// variable=variable-3600; // if(tip==6)// variable=variable-3600; // number=0;// }// if((number==6)&(EA==0)){ // if(tip==1)// variable=variable+1; // if(tip==2)// variable=variable+10; // if(tip==3)// variable=variable+60; // if(tip==4)// variable=variable+600; // if(tip==5)// variable=variable+3600; // if(tip==6)// variable=variable+36000; // number=0;// }}void compare_time(void){if(time>variable){;}}void alarm_show_s(void){int sign2;for(sign2=1;sign2<2;sign2++){ //数码管动态显示S1=second%10;P2=data_wei[sign2];P0=data_duan[S1];delay(1);}for(sign2=2;sign2<3;sign2++){ S2=second/10;P2=data_wei[sign2];P0=data_duan[S2];delay(1);}for(sign2=3;sign2<4;sign2++){ P2=data_wei[sign2];P0=0xbf;delay(1);}for(sign2=4;sign2<5;sign2++){ M1=minute%10;P2=data_wei[sign2];P0=data_duan[M1];delay(1);}for(sign2=5;sign2<6;sign2++){ M2=minute/10;P2=data_wei[sign2];P0=data_duan[M2];delay(1);}for(sign2=6;sign2<7;sign2++){P2=data_wei[sign2];P0=0xbf;delay(1);}for(sign2=7;sign2<8;sign2++){H1=hour%10;P2=data_wei[sign2];P0=data_duan[H1];delay(1);}for(sign2=8;sign2<9;sign2++){H2=hour/10;P2=data_wei[sign2];P0=data_duan[H2];delay(1);}}void record_set_alarm(void) //设定闹钟所改变的值 { second=variable%60;minute=variable/60%60;hour=variable/3600%24;if(hour==24){variable=0;}}void record_time(void) {second=time%60;minute=time/60%60; hour=time/3600%24;if(hour==24){time=0;}}int main(void){TMOD=0x01;TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1;ET0=1;TR0=1;while(1){record_time();// record_set_alarm(); alarm_show_s();key_scan();adjust_alarm();}}void extern1() interrupt 1 //定时器中断0 { TH0=(65536-50000)/256; //重装值TL0=(65536-50000)%256;sign++;if(sign==20){time++;sign=0;}}。
第9章 用LED数码管显示的秒表设计
图9-4 定时器中断程序
程序清单见课程设计指导书或配套仿真软件
5
9.4 仿真与实验结果
图9-5 按下Stop按键时的仿真结果
6
9.4 仿真与实验结果
图9-6 按下S 用LED数码管显示的秒表设计
9.1 项目任务 9.2 硬件设计 9.3 程序设计 9.4 仿真与实验结果
1
秒表是一个重要的计时工具,可用于比赛计时、实验研究以及生 活计时等。
2
9.1 项目任务
用STC89C52单片机与两位数码管设计并制作一个秒表,实现 电子秒表的基本功能,显示时间为00~59,每秒自动加1,至59 秒后再回到00,继续循环。运用“开始”、“暂停”、“复位” 按键实现对秒表计时控制。
3
9.2 硬件设计
图9-2 LED数码管显示的秒表设计电路原理图 4
9.3 程序设计
开始 定时器初始化 开中断、开始计时
1秒时间到? N
Y 1秒标志位清0,秒加1
秒=60? N
停止键按下? N
继续计时?
Y 秒计数器清零 Y
停止计时 结束
开始 定时器重新置初值 50ms中断次数加1
结束
显示秒
图9-3 主程序流程图
用数码管(8位)显示的数字时钟程序
用数码管(8位)显示的数字时钟程序
一、程序概述
本程序使用单片机AT89S52,通过数码管(8位)显示当前时间,支持12小时制和24小时制切换,精度为秒。
二、程序实现
程序首先定义了数码管的连接方式和每个数字的位图数据,然后定义了时间变量和函数,包括:
1.初始化函数:设置数码管端口和时钟计数器的计数方式。
2.读时钟函数:读取时钟计数器及寄存器,返回当前时间的小时、分钟和秒数。
3.显示函数:将当前时间转化为8个数码管显示的位图数据,用数字和符号映射表将数字和符号的位图数据与数码管连接方式对应起来,输出到数码管上。
在主函数中,程序初始化后循环执行读时钟函数和显示函数,实现时钟的实时显示。
三、程序特点
1.采用8位数码管显示,时间更加直观。
2.支持12小时制和24小时制切换,适用于不同场景。
3.实现精度为秒的实时显示,更加准确。
四、程序优化
1.增加闹钟功能,提醒用户打卡或者起床。
2.加入温度传感器模块,实现显示温度的功能。
3.优化显示效果,增加字体和颜色等选项。
五、程序应用
本程序可应用于家庭、办公室、学校等场合,用于显示时间,提醒用户合理安排时间和时间管理,也可作为DIY电子制作的教学和实验材料,提高学生的动手实践能力和电子信息技术水平。
单片机控制8位数码管显示秒表课程设计
长沙学院《单片机原理及应用》课程设计说明书题目 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秒的计时。
51单片机数码管电子时钟C程序
//**单片机stc89c52, 8位共阴数码管12M晶振//*******P0 位选,P2 段选❖******//#include 〃reg52・ h〃#define uchar unsigned char#define uint unsigned intuchar code tab[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, Oxff}; uchar n;uchar hh, mm, ss;uchar nhh, nmm, nss;uint year;uchar day, mon, week;uchar hhs, hhg, mms, mmg, sss, ssg;uchar days,dayg, mons, mong;uchar nhhs, nhhg, nmms, nmmg, nsss, nssg;uchar setl=l, set2=l;sbit dula=P3 3;sbit fm=P3 2;sbit kl二P3"4;sbit k2二P3"5;sbit k3二P3飞;sbit k4二P3"7;uchar tablel[] = {31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 〃闰年uchar table2[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //非闰年void jishi ();void baoshi ();void alarm();void set_time();void set_alarm();void set_mdw();void key_change():void key_set ();void delay (int m) 〃延时程序,延时m*0. 5msuint i;uint j;for (i=0;i<m;i++){for(j=0;j<500;j++){}}}void timerO() interrupt 1 {TMOD二0x01;TH0=0x3c;TLO=Oxbl;n++;JishiO;}main()TMOD二0x01;TH0=0x3c;TLO二Oxbl;TRO二1;EA二1;ETO二1;hh=12;mm=00;ss=00;nhh二7;nmm=30;nss=0;year=2012;mon=01;day=01;week=7; while(1){hhs=hh/10%10; // 时分秒hhg=hh%10;mms=mm/10%10;mmg=mm%10;sss=ss/10%10;ssg=ss%10;nhhs=nhh/10%10; 〃闹钟nhhg=nhh%10; nmms=nmm/10%10;nmmg=nmm%10; nsss=nss/10%10;nssg=nss%10; days=day/10%10;//月Hday萨day%10; mons=mon/10%10;mong=mon%10;key_change () ; //kl 按键扫描key_set (); //k2 按键扫描set_time() ; //设置时间set.mdwO ; //设置月日星期set_alarm() ; //设置闹钟辻(setl-1) //正常走时显示dula=l: P2=tab [hhs] ; dula=O: P2=0xff; PO=Oxef; delay (1) ;P0二Oxff; //时十位dula二1;P2二tab[hhg]; dula=0;P2=0xff;PO=Oxdf;delay(1) ; PO二Oxff;//时个位dula=l;P2=tab[10]:dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxffdula=l: P2=tab [mms] : dula=0: P2 二Oxff ;P0 二0x7f; delay (1) ;P0 二Oxff; //分十位dula=l; P2=tab [mmg] ; dula=0; P2=0xf f; P0=0xfe; delay (1) ; PO 二Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1); PO二Oxffdula二1;P2二tab[sss]; dula=0;P2=0xff;PO=Oxfb:delay(1) ; PO二Oxff;//秒十位dula二1;P2二tablssg]; dula=0:P2=0xff;P0=0xf7; delay(1) ;P0二Oxff; //秒个位}辻(set 1=2) //设置时间dula=l; P2=tab [hhs] ; dula=0; P2=Oxff; PO=Oxef; delay (1) ;P0二Oxff; //时十位dula二1;P2二tablhhg]; dula=0:P2=0xff;PO=Oxdf;delay(1) ; PO二Oxff;//时个位dula=l:P2=tab[10]:dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxffdula=l: P2=tab [mms] : dula=0: P2 二Oxff ;P0 二0x7f; delay (1) ;P0 二Oxff; //分十位dula=l; P2=tab [mmg] ; dula=0: P2=0xf f: P0=0xfe; delay (1) ; PO 二Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1); PO二Oxffdula二1;P2二tab[sss]; dula=0;P2=0xff;PO=Oxfb:delay(1) ; PO二Oxff;//秒十位dula二1;P2二tablssg]; dula=0:P2=0xff;P0=0xf7; delay(1) ;P0二Oxff; //秒个位}辻(set 1-3) //正常显示月日-星期(肆匕诂S )M心T P 鏗\m x o u o 匕(DAPWZJXOUOddxouzdoudnp 二席*〕qpf Zd二 H d n p 创+忌、、d x o u o d - (I )A p w q J x o u o d d x o u z d o H £n p =s 〕q p f z d =%-n p 、、—、、、、QJXOUOd - (I)xp^p&Jxouod2Jxouzdo%w 〔OI 〕qeTzd=%-np 心T p g 'm x o u o d - u)APW*xouoddxouzd oUPTnp 二"App 〕qpfzd二%-np^+、、dxouocr(DAP^PQZXOUOmxouzdou d n p 二 SAPP 〕qpfzd 二%-np 、、—、、、、QJXOUOdJI) A32P cu q x o u o d 世o %I n p 二2〕q e F CN d 二%H T P 鏗\m x o u o 匕(DAPWZJXOUOddxouzdoudnp 二席*〕qpf Zd二 H d n p 创+忌、、d x o u o d - (I )A p w q J x o u o d d x o u z d o H £n p =s 〕q p f z d =%-n p 、、—、、、、心 J x o u o d - (I)xp^p&Jxouod2Jxouzdo%w 〔OI 〕qeTzd=%-np 心T p g 'm x o u o d - u)APW*xouoddxouzd oUPTnp 二"App 〕qpfzd 二%-np ^+0、、d x ouocr(DAP^PQZXOUOmxouzdoudnp二SAPP〕qpfzd二%-np 、、—、、、、QJXOUOd J I ) A32Pcu q x o u o d £0 世dula=l; P2=tab [nhhs]; dula=O; P2二Oxff; PO二Oxef; delay (1) ; PO二Oxff; 〃时十位dula=l;P2=tab[nhhg]; dula=0;P2=0xff;PO=Oxdf; delay (1) ; PO二Oxff;//时个位dula=l;P2=tab[10];dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxff dula=l:P2=tab [nmms] : dula=0; P2=0xff ;P0=0x7f; delay (1) ;PO=Oxff; //分十位dula=l;P2=tab[nmmg] :dula=0;P2=0xff;PO=Oxfe; delay (1) ; PO=Oxff;//分个位dula=l;P2=tab[10]; dula=0:P2=0xff;PO=Oxfd:delay(1) ; PO二Oxffdula=l ;P2=tab[nsss] : dula=0;P2=0xff ;PO=Oxfb; delay (1) ; PO二Oxff;//秒十位dula=l;P2=tab[nssg] ; dula=0: P2=0xff; PO=Oxf7; delay (1) ;PO=Oxff; //秒个位} if(setl—6) //设置闹钟定时dula=l; P2=tab [nhhs] ; dula=0; P2二Oxff; PO二Oxef; delay (1) ; PO二Oxff; 〃时十位dula=l;P2=tab[nhhg]; dula=0;P2=0xff;PO=Oxdf; delay (1) ; PO二Oxff;//时个位dula=l;P2=tab[10];dula=0;P2=0xff; PO=Oxbf;delay(1); PO二Oxff dula=l:P2=tab [nmms] : dula=0; P2=0xff ;P0=0x7f; delay (1) ;PO=Oxff; //分十位dula=l;P2=tab[nmmg] :dula=0;P2=0xff;PO=Oxfe;delay(1) ; PO二Oxff;//分个位dula=l;P2=tab[10]; dula=0;P2=0xff;PO=Oxfd:delay(1); PO二Oxff dula=l;P2=tab[nsss]; dula二0;P2二Oxff;P0二Oxfb;delay(l) ; PO二Oxff;//秒十位dula=l;P2=tab[nssg] ; dula=0: P2=0xff; PO=Oxf7; delay (1) ;P0二Oxff; //秒个位}baoshi () : //整点报时alarm () ; //闹钟}}void JishiO 〃计时函数辻(n二二20){n=0;ss++;辻(ss=60){ss二0;mm++;if(mm二二60){mm^O;hh++;辻(hh=24){hh二0;day++;week++;if(week==8){week二0;}if (year%4==0&&year%100! =0 year%400==0) //闰年if(day=二tablel[mon]+l){day=0;mon++;if(mon==13){mon二0;year++;}}else //非闰年{辻(day—table2 [mon]+l){day=0;mon++;辻(mon—13){mon二0;year++;}}}}}}}}uchar incone (uchar n) //加 1 函数{辻(k3=0){delay(20);if(k3==0){n++;while(!k3);}}return(n);}uchar decone(uchar m) //减 1 函数{ if (k4==0){delay(20);if(k4==0)辻(m<0){m 二0;}}}}void key_change() //kl 按键扫描{ if(kl==0){delay(20);if(kl==0){setl++;while(!kl);if(setl==7){setl二1;}}void key_set() //k2 按键扫描{if(k2==0){delay(20);{set2++;while(!k2);辻(set2=4){set2=l;}}}}void baoshi () //整点报时函数{ fm=O;}if(ss==l){fm=l;}}void alarm() //闹钟函数{uchar x;if(nhh==0){goto end;}if(hh==nhh&&mm二二nmm&&ss==nss)fm=O; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay(20); fm=0; delay(30); fm=l; delay (180);end:;}void set_time() //设置时间函数{辻(setl==2){辻(set2==l){hh=incone(hh);if(hh==24){hh=0;}if(hh==-l){hh二23;}hh二decone(hh);}mm=incone(mm); if(mm==60) {mm 二0;}if(mm==-l) {mm=59;}mm=decone(mm); }辻(set2=3){ss=incone(ss);辻(ss=60){ss=O;}if (ss—-1){ss=59;}ss二decone (ss);}void set_mdw() //设置月日星期函数{ 辻(setl==4) {辻(set2==l){mon=incone(mon);if(mon二二13){mon=l;}mon=decone(mon);if(mon==0){mon二12;}}if(set2==2)day=incone(day);if(day==32){day=l;} day=decone(day);if (day—0){day=31;}}辻(set2=3){week=incone(week);if(week==8){week二1;}week二decone(week);if(week==0){week=7;}}}void set_alarm() //设置闹钟函数{ if(setl二二6){辻(set2=l){nhh二incone(nhh);辻(nhh二二24) {nhh二0;}辻(nhh—-1){nhh二23;}nhh二decone(nhh); }if(set2==2){nmm二incone(nmm); if (nmm—60) {nmm二0;}nmm二decone(nmm); if (nmm 二二 T){nmm=59;}}辻(set2二二3) {nss=incone (nss); if (nss=60){nss=0;}nss二decone(nss); if(nss==-l){nss二59;}}}。
多功能电子钟程序(完全好使)
/*设计功能:1.时钟功能(上排数码管)每秒更新一次时钟显示,显示方式为MM.SS,其中M为分钟,S为秒。
可以通过按键调整当前时间,调整时间时需要闪烁调整位置的数值。
2.秒表功能(下排数码管)按开始按键开始走秒,按停止按键停止走秒,按清除按键秒表归零,显示方式为:SSS.U,其中S为秒,U为0.1秒。
3.闹钟功能(下排数码管)用按键设置闹钟时间,显示格式为MM.SS。
闹钟时间到达后,闪烁一个指示灯。
可以用按键设置闹钟、取消闹钟。
各个按键功能可以自行定义,每按一次任何按键,D2灯会翻转一次状态*//*硬件连接:一个有上下两个4位共阳数码管,4个按键,2个LED指示灯P2高四位控制上排数码管位选,低4位控制下排数码管位选,P0控制段选四个按键为独立按键,与P2高4位相连,与数码管复用LED0接P34,LED1接P35*//*使用方法:第一步:设定系统时间,在上排的4位数码管显示,注意系统时间设定确认后就不得修改了第二步:选择秒表模式或闹钟模式,在下排的4位数码管显示。
两种模式只能选择一种,并且不能切换。
1.设定系统时间此时按键定义:S5 移位,S6 加,S7 减,S8确认一开始上电时数字全0不闪烁,默认从第一位开始设置,按下加减进行调节,如此要更换调节位置,每按一次S5会右移一位,移到第四位再按会重新移回第一位。
设置完系统时间,按下S8确认,跳出设定环节,进入秒表和闹钟模式选择环节。
2。
秒表和闹钟模式选择此时按键定义:S5 改变模式标志,S6 S7未用,S8确认进入该模式设置完系统时间,进入秒表和闹钟模式选择环节。
此时第一位为0 。
然后按S5,第一位会在1和2之间来回切换,在显示1时按S8进入秒表模式,在显示2时按S8进入闹钟模式,2.1秒表模式此时按键定义:S5 未用,S6 开始,S7停止,S8清除2.2闹钟模式此时按键定义:S5 移位,S6 加,S7 减,S8按一次确认,等报警到了,再按S8停止报警如设定系统时间的步骤,设定好闹钟时间,按S8确认设定(S8只能按一次哦),等时间到了D1灯会不断闪烁表示报警,按S8停止报警*/#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit keysource= P1^7;sbit S5= P2^4;sbit S6= P2^5;sbit S7= P2^6;sbit S8= P2^7;sbit led0=P3^4; //每按一次任何按键,D2灯会翻转一次状态sbit led1=P3^5; //闹钟报警用的灯uint shuju_1;uint shuju_2;uint count;uint stopwatch_count;int miao;int fen;int warn_miao;int warn_fen;uint shanshuo; //1 2 3 4bit shanshuo1,shanshuo2,shanshuo3,shanshuo4;uint num_settime_cnt; //标识按键5设置时间时,按下的次数uint num_setmode_cnt; //1 or 2uint stopwatch_miao;uint stopwatch_Umiao;uint stopwatch_miao_1;uint stopwatch_Umiao_1;uint mode_flag;uint warn_flag;uint stopflag = 1; //初始时先让秒表停止uchar code shuma[] = {0xC0,/*0*/0xF9,/*1*/0xA4,/*2*/0xB0,/*3*/0x99,/*4*/0x92,/*5*/0x82,/*6*/0xF8,/*7*/0x80,/*8*/0x90,/*9*/}; // 共阳数码管void delay(uint z) // 1ms{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void display_1() // 上排{uchar qian,bai,shi,ge;qian = shuju_1/1000;bai = shuju_1%1000/100;shi = shuju_1%100/10;ge = shuju_1%10;////xianshi 1////P2 |= 0xf0; //高4位全部置1P2 &= 0xef; //改变高4位,低4位不变if(shanshuo1 == 1)P0= 0xff;elseP0= shuma[qian];delay(1);////xianshi 2////P2 |= 0xf0;P2 &= 0xdf;if(shanshuo2 == 1)P0= 0xff;elseP0=shuma[bai]&0x7f; //要点亮小数点delay(1);////xianshi 3////P2 |= 0xf0;P2 &= 0xbf;if(shanshuo3 == 1)P0= 0xff;elseP0=shuma[shi];delay(1);////xianshi 4////P2 |= 0xf0;P2 &= 0x7f;if(shanshuo4 == 1)P0= 0xff;elseP0=shuma[ge];delay(1);P2 = 0xff; //解除位选}void display_2() // 下排{uchar qian,bai,shi,ge;qian = shuju_2/1000;bai = shuju_2%1000/100;shi = shuju_2%100/10;ge = shuju_2%10;////xianshi 1////P2 |= 0x0f; //低4位全部置1P2 &= 0xfe; //改变低4位,高4位不变if(shanshuo1 == 1)P0= 0xff;elseP0= shuma[qian];delay(1);////xianshi 2////P2 |= 0x0f;P2 &= 0xfd;if(shanshuo2 == 1)P0= 0xff;else if (mode_flag == 2){P0=shuma[bai]&0x7f;}else{P0=shuma[bai] ;}delay(1);////xianshi 3////P2 |= 0x0f;P2 &= 0xfb;if(shanshuo3 == 1)P0= 0xff;else if (mode_flag == 1){P0=shuma[shi]&0x7f;}else{P0=shuma[shi] ;}delay(1);////xianshi 4////P2 |= 0x0f;P2 &= 0xf7;if(shanshuo4 == 1)P0= 0xff;elseP0=shuma[ge];delay(1);P2 = 0xff; //解除位选}void check_ledflash() //判断哪一位正在设置中,让该位闪烁{switch(shanshuo) //利用shanshuo标志来判断,当前正在在哪一位设定{case 1:shanshuo1 = ~shanshuo1; //如果为第一位,则第一位闪烁,其它位不闪烁shanshuo2 =0;shanshuo3 =0;shanshuo4 =0;break;case 2:shanshuo2 = ~shanshuo2;//如果为第二位,则第一位闪烁,其它位不闪烁shanshuo1 =0;shanshuo3 =0;shanshuo4 =0;break;case 3:shanshuo3 = ~shanshuo3;//如果为第三位,则第一位闪烁,其它位不闪烁shanshuo1 =0;shanshuo2 =0;shanshuo4 =0;break;case 4:shanshuo4 = ~shanshuo4;//如果为第四位,则第一位闪烁,其它位不闪烁shanshuo1 =0;shanshuo2 =0;shanshuo3 =0;break;default:shanshuo1 =0;shanshuo2 =0;shanshuo3 =0;shanshuo4 =0;break;}}void settime()//设定系统时间,时间格式:分-分。
单片机数码管秒表程序
单片机数码管秒表程序
数码管秒表是一种常见的计时工具,它利用单片机控制数码管的显示来实现计时功能。
下面我将为大家介绍一种基于单片机的数码管秒表程序。
程序的实现思路如下:首先,我们需要使用单片机的定时器来实现时间的计数。
通过设置定时器的计数周期和中断处理函数,我们可以在每个固定的时间间隔内进行一次计数。
然后,我们需要将计数的结果通过数码管进行显示。
为了方便显示,我们可以将计数结果分为小时、分钟和秒三个部分,分别显示在数码管的不同位上。
程序的具体实现步骤如下:
1. 初始化单片机的定时器,并设置计数周期为1秒。
2. 设置一个全局变量来保存计数的结果,初始值为0。
3. 在定时器的中断处理函数中,每次中断时将计数结果加1。
4. 在主函数中,设置一个循环来不断检测计数结果的变化,并将其转换为时、分、秒的形式。
5. 将转换后的时、分、秒分别显示在数码管的不同位上,通过控制数码管的引脚来实现。
通过以上步骤,我们就可以实现一个简单的数码管秒表程序。
当程序运行时,数码管会不断地显示计时结果,从0开始递增,以秒为单位。
当需要停止计时时,可以通过外部按键等方式来暂停或重置计数结果。
这种数码管秒表程序可以广泛应用于各种计时场景,比如运动比赛、实验计时等。
它的实现简单、成本低廉,并且可以精确地显示时间,非常实用。
希望通过以上介绍,大家对基于单片机的数码管秒表程序有了更深入的了解。
希望这个简单的程序能够帮助大家更好地实现计时功能,提高工作和学习的效率。
谢谢大家!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数码管电子秒表程序8位数码管电子秒表,显示精确到0.01秒。
使用共阳数码管,51单片机的P0口输出段码,P2口输出位码。
晶振11.0592MHz。
控制按钮K1接P1.0口,单片机检测低电平。
第一次按下时,启动开始计时;第二次按下时,停止计时、显示当前值;第三次按下时,显示归零,做好重新计时准备。
完整源程序:#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, off unsigned 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 = P1^0;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; // 初始显示P20口数码管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;}}}void timer0() interrupt 1// 定时器0中断服务程序, 用于数码管的动态扫描// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,// 选通P2.0口数码管// dis_buf --- 显于缓冲区基地址{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个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描}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[0]];dis_buf[1] = dis_code[sec_bcd[1]];dis_buf[2] = dis_code[sec_bcd[2]] & 0x7f; // 加上小数点 dis_buf[3] = dis_code[sec_bcd[3]];dis_buf[4] = dis_code[sec_bcd[4]];dis_buf[5] = dis_code[sec_bcd[5]];dis_buf[6] = dis_code[sec_bcd[6]];dis_buf[7] = dis_code[sec_bcd[7]];}void delayms(unsigned char ms)// 延时子程序{unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}#include<reg52.h>sbit ksec=P3^0;sbit kmin=P3^1;sbit khour=P3^2;sbit P33=P3^3;unsigned charsecshi=0,secge=0,minshi=0,minge=0,hourshi=0,hourge=0;unsigned int num=0,sec=0,min=0,hour=0,x,n;unsigned char code table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};void delay(unsigned int);void keyscan();void display();main(){ TMOD=0x11;TH0=(65536-50000)/256;TL0=(65536-50000)%256;TH1=(65536-50000)/256;TL1=(65536-50000)%256;EA=1;ET0=1;TR0=1; TR1=0; ET1=1; while(1){display();keyscan();}}void delay(unsigned int z) {unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void time0() interrupt 1{num++;TH1=(65536-50000)/256;TL1=(65536-50000)%256;}void time1() interrupt 3{n++;TH0=(65536-50000)/256;TL0=(65536-50000)%256;}void display(){if(min==0){TR1=1;}else{TR1=0;}if(n>10){n=0;P33=~P33;}if(num==20){num=0;sec++;if(sec==60){sec=0;min++;if(min==60){min=0;hour++;if(hour==24) {hour=0;min=0;sec=0;}}}}secge=sec%10; secshi=sec/10; minge=min%10; minshi=min/10; hourge=hour%10; hourshi=hour/10; P2=1;P0=table[secge]; delay(5);P2=2;P0=table[secshi]; delay(5);P2=4;P0=191;delay(5);P2=8;P0=table[minge]; delay(5);P2=16;P0=table[minshi]; delay(5);P2=32;P0=191;delay(5);P2=64;P0=table[hourge]; delay(5);P2=128;P0=table[hourshi]; delay(5);}void keyscan() {if(ksec==0){delay(10);if(ksec==0){sec++;if(sec>=60)sec=0;}while(ksec==0) display();}if(kmin==0){delay(10);if(kmin==0){min++;if(min>=60)min=0;}while(kmin==0) display();}if(khour==0){delay(10);if(khour==0){hour++;if(hour>=24) hour=0;}while(khour==0) display();}}。