60秒倒计时时钟 单片机AT89C51 C语言程序

合集下载

89C51单片机时钟程序

89C51单片机时钟程序

89C51单片机时钟程序第一篇:89C51单片机时钟程序SECOND EQU 40H;给内存RAM空间中40H单元起名SECOND MINUTE EQU 41H ;给内存RAM空间中41H单元起名MINUTE HOUR EQU 42H;给内存RAM空间中42H单元起名HOUR SECONDGEWEI EQU 43H;给43H单元起名SECONDGEWEI存秒的个位SECONDSHIWEI EQU 44H;给44H单元起名SECONDSHIWEI存秒的十位MINUTEGEWEI EQU 45H;给45H单元起名MINUTEGEWEI存分的个位MINUTESHIWEI EQU 46H;给46H单元起名MINUTESHIWEI存分的十位HOURGEWEI EQU 47H;给47H单元起名HOURGEWEI存小时的个位HOURSHIWEI EQU 48H;给48H单元起名HOURSHIWEI存小时的十位 ORG 0000H;复位时程序从此开始 SJMP START;跳到START进行初始化 ORG 000BH;定时器 0中断入口 AJMP TIMER0;跳转到TIMER0处ORG 0030H;初始化程序从30H开始;---------------初始化START------------------------------START:MOV SECOND, #0;给秒存储单元SECOND赋初始值0 MOV MINUTE, #0;给分存储单元MINUTE赋初始值0 MOV HOUR , #12;给小时存储单元HOUR赋初始值12 MOV DPTR , #TAB;给数据指针赋值,将DPTR指向TAB数据表头处 MOV 30H, #0 ;给30H单元赋初始值0(用于计20次的50ms中断)MOV TH0,#3CH;给计数容器的高8位TH0赋初始值3CH MOV TL0,#0B0H;给计数容器的低8位TL0赋初始值B0H MOV TMOD,#00000001B;C/T位设置为0,M1M0设置位10,即模式1定时MOV TCON,#00010000B;TR0设置为1,即启动定时器0开始工作 SETB ET0;IE中的ET0位设置为1,开定制器中断0 SETB EA;IE中的EA位设置为1,开总中断;-----------------------主程序MAIN-----------------------------MAIN:CALL KEY;调按键子程序KEY CALL PROCESS;调数据处理子程序PROCESS CALL DISPLAY;调显示子程序DISPLAY SJMP MAIN;跳转到MAIN标号处;------------------------------按键子程序KEY调时-------------------KEY:MOV P1,#0FEH;行扫描 LCALL DELAY;JNB P1.4,HOURJIA;P1.4引脚如果是低电平就跳到HOURJIA处JNB P1.5,HOURJIAN;P1.5引脚如果是低电平就跳到HOURJIAN处JNB P1.6,MINUTEJIA;P1.6引脚如果是低电平就跳到MIMUTEJIA处JNB P1.7,MINUTEJIAN;P1.7引脚如果是低电平就跳到MIMUTEJIAN处 FANHUI:RET;子程序返回(如果没有按键按下)HOURJIA:CALL DELAY;调延时程序目的是跳过按键抖动期(去抖)JB P1.4,FANHUI;P1.4如果是高电平就跳到FANHUI处(没键按)JNB P1.4,$;如果P1.4是低电平就停在当前位置等键释放MOV R4,HOUR CJNE R4,#23,A1;判断时数字是否为23 AJMP A2A1:INC HOUR;把小时位加1 MOV SECOND, #0;小时进位,秒归0RETA2:MOV HOUR,#0;小时数为23时加一为0MOV SECOND, #0;小时进位,秒归0RET;子程序返回HOURJIAN:CALL DELAY;调延时程序目的是跳过按键抖动期(去抖)JB P1.5,FANHUIJNB P1.5,$MOV R5,HOUR CJNE R5,#0,A3AJMP A4 A3:DEC HOURMOV SECOND, #0RET A4:MOV HOUR,#23MOV SECOND, #0 RETMINUTEJIA:CALL DELAYJB P1.6,FANHUIJNB P1.6,$MOV R6,MINUTECJNE R6,#59,A5AJMP A6 A5:INC MINUTEMOV SECOND, #0RET A6:MOV SECOND, #0MOV MINUTE, #0MOV R4,HOUR CJNE R4,#23,A10MOV HOUR,#0RET A10:INC HOURRETMINUTEJIAN:CALL DELAYJB P1.7,FANHUIJNB P1.7,$MOV R7,MINUTE CJNE R7,#0,A7AJMP A8 A7:DEC MINUTE;P1.5如果是高电平就跳到FANHUI处(没键按) ;如果P1.5是低电平就停在当前位置等键释放;判断时数字是否为23;把小时位减1;小时数为0时减一为23;子程序返回;调延时程序目的是跳过按键抖动期(去抖);P1.6如果是高电平就跳到FANHUI处(没键按) ;如果P1.6是低电平就停在当前位置等键释放;判断分钟数是否为59;把分钟位加1;给秒存储单元SECOND赋初始值0;分钟数为59则分钟归0;判断时数字是否为23;23时增1归0;分钟数为59 自增1后小时增1;子程序返回;调延时程序目的是跳过按键抖动期(去抖);P1.7如果是高电平就跳到FANHUI处(没键按) ;如果P1.7是低电平就停在当前位置等键释放;判断分钟数是否为0;分钟不为0把分钟位减1MOV SECOND, #0RETA8:MOV MINUTE, #59;分钟数为0时减一为59 MOV R4,HOUR CJNE R4,#0,A9;判断时钟数是否为0 MOV HOUR,#23;时钟数为0减1为23 MOV SECOND, #0 RETA9:DEC HOUR;时钟数不为0则减1 MOV SECOND, #0RET;子程序返回;-------------------处理子程序PROCESS-----------------------PROCESS:MOV A, SECOND;把SECOND中的秒值拷贝给A MOV B, #10;给寄存器B赋值10 DIV AB;A除以B,结果存入A中,余数存入B中 MOV SECONDSHIWEI , A;结果即秒的十位数拷贝给SECONDSHIWEI MOV SECONDGEWEI , B;余数即秒的个位拷贝给SECONDGEWEI MOV A, MINUTE;把MINUTE中的分值拷贝给A MOV B, #10;给寄存器B赋值10 DIV AB;A除以B,结果存入A中,余数存入B中 MOV MINUTESHIWEI , A;结果即分的十位拷贝给MINUTESHIWEI MOV MINUTEGEWEI , B;余数即分的个位拷贝给MINUTEGEWEI MOV A, HOUR;把HOUR中的小时值拷贝给A MOV B, #10;给寄存器B赋值10 DIV AB;A除以B,结果存入A中,余数存入B中 MOV HOURSHIWEI , A;结果即小时的十位拷贝给HOURSHIWEI MOV HOURGEWEI , B ;余数即小时的个位拷贝给HOURGEWEI RET;子程序结束返回到主程序;-----------------显示子程序DISPLAY--------------DISPLAY:MOV A, HOURSHIWEI;小时的十位拷贝给A MOVC A, @A+DPTR;到A+DPRT这个数对应的地方找显示段码拷贝给A MOV P0, A ;把显示段码(小时的十位)送到P0 CLR P2.0;将P2.0置低电平,对应的三极管导通 CALL DELAY;调延时(让显示小时十位的数码管持续亮一段时间)SETB P2.0 ;将P2.0置高电平,对应三极管截止,对应数码管灭MOV A, HOURGEWEI;小时的个位拷贝给A MOVC A,@A+DPTR;到A+DPRT这个数对应的地方找显示段码拷贝给A MOV P0, A ;把显示段码(小时的个位)送到P0 CLR P2.1;将P2.1置低电平,对应的三极管导通CALL DELAY;调延时(让显示小时个位的数码管持续亮一段时间)SETB P2.1 MOV P0,#7FH CLR P2.1 CALL DELAY SETB P2.1;将P2.1置高电平,对应三极管截止,对应数码管灭MOV A, MINUTESHIWEI;分钟的十位拷贝给A MOVC A,@A+DPTR;到A+DPRT这个数对应的地方找显示段码拷贝给A MOV P0, A ;把显示段码(分钟的十位)送到P0 CLR P2.2;将P2.2置低电平,对应的三极管导通 CALL DELAY;调延时(让显示分钟十位的数码管持续亮一段时间)SETB P2.2 ;将P2.2置高电平,对应三极管截止,对应数码管灭MOV A, MINUTEGEWEI;分钟的个位拷贝给A MOVC A,@A+DPTR;到A+DPRT这个数对应的地方找显示段码拷贝给A MOV P0, A ;把显示段码(分钟的个位)送到P0 CLR P2.3;将P2.3置低电平,对应的三极管导通CALL DELAY;调延时(让显示分钟个位的数码管持续亮一段时间)SETB P2.3 ;将P2.3置高电平,对应三极管截止,对应数码管灭MOV P0,#7FH CLR P2.3 CALL DELAY SETB P2.3MOV A, SECONDSHIWEI;秒的十位拷贝给A MOVC A,@A+DPTR;到A+DPRT这个数对应的地方找显示段码拷贝给A MOV P0, A ;把显示段码(秒钟的十位)送到P0 CLR P2.4;将P2.4置低电平,对应的三极管导通 CALL DELAY;调延时(让显示秒钟十位的数码管持续亮一段时间)SETB P2.4 ;将P2.4置高电平,对应三极管截止,对应数码管灭MOV A, SECONDGEWEI;秒的个位拷贝给A MOVC A,@A+DPTR;到A+DPRT这个数对应的地方找显示段码拷贝给A MOV P0, A ;把显示段码(秒钟的个位)送到P0 CLR P2.5;将P2.5置低电平,对应的三极管导通CALL DELAY;调延时(让显示秒钟个位的数码管持续亮一段时间)SETB P2.5 ;将P2.5置高电平,对应三极管截止,对应数码管灭 RET;显示子程序结束返回主程序;--------------------中断服务子程序----------------------------TIMER0:MOV R3, A;把A中的数据送入R3保护起来 INC 30H;30H单元中的数加1 MOV A, 30H;30H单元中的数据拷贝给A CJNE A,#20,JIXU;A中的数据与20比较不相等就跳转到JIXU处 MOV 30H,#0;(如果30H单元计满20了)给30H赋值0 INC SECOND;把SECOND中的秒钟数加1 MOV A,SECOND;把SECOND中的数据拷贝给A CJNE A, #60, JIXU;A中的数据与60比较不相等就跳转到JIXU处MOV SECOND,#0;给秒SECOND赋值0 INC MINUTE;把MINUTE中的分钟数加1 MOV A, MINUTE;把MINUTE中的数据拷贝给A CJNE A, #60, JIXU;A中的数据与60比较不相等就跳转到JIXU处 MOV MINUTE, #0 ;给分钟MINUTE赋值0 INC HOUR;把HOUR中的小时数据加1 MOV A, HOUR;把HOUR中的数据拷贝给A CJNE A, #24, JIXU;A中的数据与24比较不相等就跳转到JIXU处 MOV HOUR, #0 ;给小时HOUR赋值0 JIXU: MOV A,R3;把刚才送入R3中的数据还给A MOV TH0,#3CH;给计数容器的高8位TH0赋初始值3CH MOV TL0,#0B0H;给计数容器的低8位TL0赋初始值B0H RETI;中断子程序返回主程序;---------------------------延时子程序----------------------------DELAY:MOV R0, #50;给R0赋值50 D2:MOV R1, #10;给R1赋值10 D1:DJNZ R1, D1;R1减1不等于0跳到D1处 DJNZ R0, D2;R0减1不等于0跳到D2处RET;延时子程序结束返回调用该程序的下一条;---------------下面的数据表中存储的是显示段码(共阳)-------------------TAB:DB 0C0H,0F9H,0A4H,0B0H,99H;从TAB处开始存储0、1、2、3、4DB 92H ,82H ,0F8H,80H ,90H;5、6、7、8、9对应的显示段码 END;程序结束第二篇:基于单片机的时钟控制器设计时钟控制器设计任务书1.设计目的与要求设计出一个用于数字时钟的控制器,准确地理解有关要求,独立完成系统设计,要求所设计的电路具有以下功能:(1)显示:可以显示时、分和秒(2)调时功能:时(0-24)、分和秒(0-60)可以连续可调(3)时间日误差< 2秒(4)增加整点报时功能(5)增加闹钟任意设定功能 2.设计内容(1)画出电路原理图,正确使用逻辑关系;(2)确定元器件及元件参数;(3)进行电路模拟仿真;(4)SCH文件生成与打印输出;(5)PCB文件生成与打印输出; 3.编写设计报告写出设计的全过程,附上有关资料和图纸,有心得体会。

51-数字时钟-89C52-单片机C语言程序

51-数字时钟-89C52-单片机C语言程序

51-数字时钟-89C52-单片机C语言程序数字时钟89C52 单片机C语言程序STC89C52|/************** 【数字时钟】****************//****【功能】1、时间显示2、秒表3、闹钟4、日期显示都可以设置****/#include /*包含器件配置文件*/#define uchar unsigned char /*宏定义字符型数据整型数据*/ #define uint unsigned intuchar code H[] = {0x0f, 0x07, 0x0b, 0x0d, 0x0e}; /*按键【P3】端口断码用于按键*/ char Code[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,0x7d, 0x07, 0x7f, 0x6f}; /*显示【0 1 2 3 4 5 6 7 8 9】数字的数码管的段码*/ uchar code C[] = {0x0, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};/*列扫描控制LED1位2位3位4位5位6位7位8位*/uchar MON[]={0,31,28,31,30,31,30,31,31,30,31,30,31};uchar A;uchar BIN=0; /* 【BIN】作为倒计时开始的标志*/uchar hour = 0; /* 定义[时][分][秒] */uchar min = 0;uchar sec = 0;uint shi=12;uint fen=30;uchar Mmin=0;uchar Msec=30;uchar M0=0;uchar m=0;uchar year=9;uchar month=7;uchar month2;uchar day=19;uchar set1 = 1; /* set1=1 是调节时分秒set1=2时时调节年月日set=3时事调节闹钟*/uchar set2 = 1; /* set2=1时是调节【时】位set2=2时事调节【分】位*/uint x = 0; /* x 每【0.01s】自加一*/void Delay(uint k);void Timer0() /*定时器T0 5mS初始化*/{TMOD = 0x01; /*设置*定时器0**计数方式一* (每12个时钟脉冲计数一次)或IT0=1 第二种计数方式*/TH0 = (65536 - 10000) / 256; /*给定计时器高位赋予初值=15536/256*/TL0 = (65536 - 10000) % 256; /*给定计时器低位赋予初值=15536%256 */ET0 = 1; /*打开定时器外部终断0允许ET1是中断器1的开关*/ EA = 1; /*打开总中断允许*/TR0 = 1;}void T0_srv(void) interrupt 1 /*5mS定时中断服务函数秒分时的值*/{TH0 = (65536 - 10000) / 256; /*给定计时器高位赋予初值=15536/256*/TL0 = (65536 - 10000) % 256; /*给定计时器低位赋予初值=15536%256 */x++;if(x==100){sec++;x=0; /*没每一秒【sec】加一*/if(sec==60){min++;sec=0;if(min==60) /*每一分钟【min】加一*/ {min = 0;hour++;if(hour==24){hour = 0; /*每一小时【hour】加一*/ day++;if(year%4==0) /*是否闰年的判断*/ MON[2]=29;else MON[2]=28;if(day==MON[month]){day=0;month++;}}}}}if(BIN==1)if(Mmin!=0||Msec!=0){M0 = 100-x;if(M0==100){ if(Mmin>0){Msec--;if(Msec==0){Msec=60;Mmin-- ;}if(Msec==0) {Mmin=0;Msec=0;M0=0;} }if(Mmin==0){if(Msec!=0)Msec--;if(Msec==0){Msec=0;M0=0;}}}}if(Mmin==0&&Msec==0){M0=0;}} /*秒表分秒M0的赋值*/}void Scan_key() /*按键扫描函数【Scan_key()】*/ {P3=H[0];if(P3!=H[0])Delay(1);if(P3==H[4]){set1++;if(set1>4) set1 = 1;er1: if(P3==H[4]) goto er1; /*按下键后未释放,在此等候*/ }Delay(1);if(P3==H[3]){set2++;if(set2>3) set2 = 1;er2: if(P3==H[3]) goto er2; /*按下键后未释放,在此等候*/ }Delay(1);if(P3==H[1]){BIN++;if(BIN>1) BIN=0;er3: if(P3==H[1]) goto er3; /*按下键后未释放,在此等候*/ }}}void Time_show() /*时间的显示变量为【时】【分】【秒】*/ { P0 = Code[hour/10]; /*第一位数字显示【时】的【十】位*/ P2 = C[1];Delay(1);P0 = Code[hour%10]; /*第二位数字显示【时】的【个】位*/P2 = C[2];Delay(1);if(x/50==0)P0 = 0x40; /*第三位符号【-】的显示*/elseP0 = 0x00;P2 = C[3];Delay(1);P0 = Code[min/10]; /*第四位的数字的显示【分】的【十】位*/ P2 = C[4];Delay(1);P0 = Code[min%10]; /*第五位的数字显示【分】的【个】位*/ P2 = C[5];Delay(1);Delay(1);if(x/50==0)P0 = 0x40; /*第六位符号【-】的显示*/elseP0 = 0x00;P2 = C[6];Delay(1);P0 = Code[sec/10]; /*第七位数字的显示【秒】的【十】位显示*/P2 = C[7];Delay(1);P0 = Code[sec%10]; /*第八位数字的显示【秒】的【个】位显示*/ P2 = C[8];Delay(1);}void Year_show(){P0 = Code[year/10]; /*第一位数字显示【年】的【十】位*/P2 = C[1];Delay(1);P0 = Code[year%10]; /*第二位数字显示【年】的【个】位*/P2 = C[2];Delay(1);P0 = 0x40; /*第三位符号【-】的显示*/P2 = C[3];Delay(1);P0 = Code[month/10]; /*第四位的数字的显示【月】的【十】位*/P2 = C[4];Delay(1);P0 = Code[month%10]; /*第五位的数字显示【月】的【个】位*/P2 = C[5];Delay(1);Delay(1);P0 = 0x40; /*第六位符号【-】的显示*/P2 = C[6];Delay(1);P0 = Code[day/10]; /*第七位数字的显示【天】的【十】位显示*/P2 = C[7];Delay(1);P0 = Code[day%10]; /*第八位数字的显示【天】的【个】位显示*/ P2 = C[8];Delay(1);}void Clock_show(){P0 = Code[shi/10]; /*第一位数字显示【时】的【十】位*/P2 = C[4];P0 = Code[shi%10]; /*第二位数字显示【时】的【个】位*/P2 = C[5];Delay(1);P0 = 0x40; /*第三位符号【-】的显示*/P2 = C[6];Delay(1);P0 = Code[fen/10]; /*第四位的数字的显示【分】的【十】位*/ P2 = C[7];Delay(1);P0 = Code[fen%10]; /*第五位的数字显示【分】的【个】位*/P2 = C[8];Delay(1);}void Miao_show() /*时间的显示变量为【时】【分】【秒】*/ { P0 = Code[Mmin/10]; /*第一位数字显示【时】的【十】位*/P2 = C[1];Delay(1);P0 = Code[Mmin%10]; /*第二位数字显示【时】的【个】位*/ P2 = C[2];Delay(1);P0 = 0x40; /*第三位符号【-】的显示*/P2 = C[3];Delay(1);P0 = Code[Msec/10]; /*第四位的数字的显示【分】的【十】位*/ P2 = C[4];Delay(1);P0 = Code[Msec%10]; /*第五位的数字显示【分】的【个】位*/ P2 = C[5];Delay(1);P0 = 0x40; /*第六位符号【-】的显示*/P2 = C[6];Delay(1);P0 = Code[M0/10]; /*第七位数字的显示【秒】的【十】位显示*/P2 = C[7];Delay(1);P0 = Code[M0%10]; /*第八位数字的显示【秒】的【个】位显示*/ P2 = C[8];Delay(1);}void Time_set() /*调整时间的函数time_set() */{Scan_key();if(set1==1){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) hour++; /*按一下第三行的键hour 就加一*/Delay(1);if(hour>24) hour=0;while(P3==H[2]); /*按键未释放,在此等候*/}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) min++; /*按一下第三行的键hour 就加一*/Delay(1);if(min>60){ min=0; hour++;}while(P3==H[2]); /*按键未释放,在此等候*/}}}void Year_set() /*调整时间的函数time_set() */{Scan_key();if(set1==2){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) year++; /*按一下第三行的键hour 就加一*/ Delay(1);if(year>100) year=0;while(P3==H[2]);}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) month++; /*按一下第三行的键hour 就加一*/ Delay(1);if(month>12){ month=0; year++;}while(P3==H[2]);}if(set2==3){if(P3==H[2]) day++; /*按一下第三行的键hour 就加一*/ Delay(1);if(day>MON[month]){ day=0; month++;}while(P3==H[2]); /*按键未释放,在此等候*/}}}Clock_set(){Scan_key();if(set1==3){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) shi++; /*按一下第三行的键hour 就加一*/ Delay(1);if(shi>24) shi=0;while(P3==H[2]); /*按键未释放,在此等候*/}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) fen++; /*按一下第三行的键hour 就加一*/ Delay(1);if(fen>60){ fen=0; shi++;}while(P3==H[2]); /*按键未释放,在此等候*/}}}void Miao_set() /*调整时间的函数time_set() */{Scan_key();if(set1==4){if(set2==1) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) Mmin++; /*按一下第三行的键hour 就加一*/Delay(1);if(Mmin>24) Mmin=0;while(P3==H[2]); /*按键未释放,在此等候*/}if(set2==2) /*当set1=1 set2=1时位时的设置*/{if(P3==H[2]) Msec++; /*按一下第三行的键hour 就加一*/ Delay(1);。

60秒倒计时时钟 单片机AT89C51 C语言程序

60秒倒计时时钟 单片机AT89C51 C语言程序

#include<reg51.h>typedef unsigned char uint8;typedef unsigned int uint16;/*七段共阳管显示定义*/uint8 code dispcode[ ]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};/*定义并初始化变量*/uint8 seconde=59;uint16 mstcnt=0;/*函数声明*/void delay(uint8 k ); //延时子程序void time_pro( ); //时间处理子程序void display( ); //显示子程序/*****************************//*延时子程序*//****************************/void delay (uint8 k){uint8 j;while((k--)!=0){for(j=0;j<125;j++){;}}}/**************************//*时间处理子程序*//**************************/void time_pro( void){if(seconde==0)//秒钟设为59进制{ seconde=59; }}/*****************************//* 显示子程序*//*****************************/void display(void){P1=dispcode[seconde/10]; //显示秒的十位delay(4);P2=dispcode[seconde%10]; //显示秒的个位delay(4);}/**************************//*1s定时定时*//**************************/void timer0(void) interrupt 1 using 0//定时器0方式1,250us中断一次{TH0=0xff;TL0=0x19;TMOD = 0x01;mstcnt++;if(mstcnt==4000){seconde--;mstcnt=0; //注意对计数单元的清零}}/**************************//*主函数*//**************************/void main(void){ P1=0xff; //初始化p0口,全设为1使数码管P2=0xff; //初始化p2口,全设为1使数码管TMOD = 0x01; //time0为定时器,方式1TH0=0xff; //预置计数初值TL0=0x19;EA=1;ET0=1;TR0=1;while (1){time_pro( ); //时间处理display( ); //显示时间}}。

AT8951单片机带闹钟数字时钟 C语言编程

AT8951单片机带闹钟数字时钟 C语言编程

{
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;
}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[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];

89C51单片机60秒倒计时的模拟与仿真设计

89C51单片机60秒倒计时的模拟与仿真设计

单片机结课设计论文学院:班级:姓名:学号:任课老师:二〇一二年五月目录1学习心得 (2)2结课设计 (2)3正文 (4)3.1 设计要求 (4)3.2 结课设计的目标 (4)3.3 设计方法和内容 (4)3.3.1硬件设计方法 (5)3.3.2软件设计方法 (9)3.4 软件调试过程 (11)3.4.1 系统调试工具keil C51 (11)3.4.2 系统调试工具PROTEUS (11)4设计总结 (12)5参考文献 (13)学习心得单片机课程是我们专业一个很重要的课程,因为单片机方面的很多知识都应用在机电一体化中。

现代人类生活中所用的几乎每件电子和机械产品中都会集成有单片机。

了解到单片机的重要性,一开始我就决定了一定要好好学这门课。

刚开始接触单片机是很陌生的,当学到89C51单片机的结构及原理这一章的时候,感觉书本里面的内容抽象且难以理解,心里面本能地就有一股抵制情绪在作怪。

但是一想到单片机是如此的重要又不得不逼着自己去学去记。

学到指令系统这部分内容的时候,里面的很多指令往往让自己感到厌烦,面对一些冗长的汇编程序,往往不用看到最后就已经失去兴趣了。

感觉自己学习单片机的过程其实就是一个对陌生领域的本能的抵制而又渴望征服的过程!我意识到单片机的重要性也从心里面想过要学好这门课程,在学习的过程中我尽力的克服了由本能产生的对抽象知识的抵制情绪,上课认真听讲,做好笔记,最后总算对单片机有一个比较全面的了解。

特别是最后做的那七个实验的时候,每一次我都会认真的思考该怎么去实现这个功能,怎么样从书本中得到答案,怎么样去做好理论联系实际。

在实验的实践过程中,我发现要学好单片机不仅仅要认认真真学习书本上的理论知识,更要学得透彻,还要实际操作单片机。

理论联系实际,这样的学习才不会变得更加生动,更容易调动学习积极主动性。

虽然单片机这门课程已经结课了,但是老师传授给我的知识将使我终身受益!短短几十个学时的学习,老师作为领路者把我带入了单片机这一奇妙的领域。

AT89C51时钟程序

AT89C51时钟程序

;; A T89C51时钟程序;;DISPFIRST EQU 30H ;显示首址存放单元BELL EQU P1.7 ;小喇叭CONBS EQU 2FH ;存放报时次数;;; 中断入口程序;;;ORG 0000H ;程序执行开始地址LJMP START ;跳到标号START执行ORG 0003H ;外中断0中断程序入口RETI ;外中断0中断返回ORG 000BH ;定时器T0中断程序入口LJMP INTT0 ;跳至INTTO执行ORG 0013H ;外中断1中断程序入口RETI ;外中断1中断返回ORG 001BH ;定时器T1中断程序入口LJMP INTT1 ;跳至INTT1执行ORG 0023H ;串行中断程序入口地址RETI ;串行中断程序返回;; 以下程序开始;整点报时用QQQQ : LCALL DI ;发音200msLCALL NO_DI ;静音200msLCALL DICLR 08H ;清整点报时标志AJMP START1;; 主程序开始;;START: MOV R0,#00H ;清00H-7FH内存单元MOV R7,#80H ;CLEARDISP: MOV @R0,#00H ;INC R0 ;DJNZ R7,CLEARDISP ;MOV 20H,#00H ;清20H(标志用)MOV 7AH,#0AH ;放入"熄灭符"数据MOV TMOD,#11H ;设T0、T1为16位定时器MOV TL0,#0B0H ;50MS定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值MOV TL1,#0B0H ;50MS定时初值(T1闪烁定时用)MOV TH1,#3CH ;50MS定时初值SETB EA ;总中断开放SETB ET0 ;允许T0中断SETB TR0 ;开启T0定时器MOV R4,#14H ;1秒定时用计数值(50MS×20)MOV DISPFIRST,#70H ;显示单元为70-75H;以下主程序循环START1: LCALL DISPLAY ;调用显示子程序JNB P1.0,SETMM1 ;P1.0口为0时转时间调整程序JNB P1.1,FUNSS ;秒表功能,P1.1按键调时时作减1加能JNB P1.2,FUNPT ;秒表STOP,PUSE,CLRJNB P1.3,TSFUN ;定时闹铃设定JB 08H, QQQQAJMP START1 ;P1.0口为1时跳回START1;FUNPT: LJMP FUNPTT;以下闹铃时间设定程序,按P1.3进入设定TSFUN: LCALL DS20MSJB P1.3,START1 ;WAIT113: JNB P1.3,WAIT113 ;等待键释放JB 05H,CLOSESP ;闹铃已开的话,关闹铃MOV DISPFIRST,#50H ;进入闹铃设定程序,显示50-55H闹钟定时单元MOV 50H,#0CH ;"-" 闹铃设定时显示格式00:00: -MOV 51H,#0AH ;"黑";DSWAIT: SETB EALCALL DISPLAYJNB P1.2,DSFINC ;分加1JNB P1.3,DSSFU ;进入时调整AJMP DSWAIT;CLOSESP: CLR 05H ;关闹铃标志CLR BELLAJMP START1DSSFU: LCALL DS20MS ;消抖JB P1.3, DSWAITLJMP DSSFUNN ;进入时调整;SETMM1: LJMP SETMM ;转到时间调整程序SETMM;DSFINC : LCALL DS20MS ;消抖JB P1.2, DSWAITDSWAIT12: LCALL DISPLAY ;等键释放JNB P1.2, DSWAIT12CLR EAMOV R0,#53H ;LCALL ADD1 ;闹铃设定分加1MOV A,R3 ;分数据放入ACLR C ;清进位标志CJNE A,#60H,ADDHH22 ;ADDHH22: JC DSWAIT ;小于60分时返回ACALL CLR0 ;大于或等于60分时分计时单元清0DSDEC : LCALL DS20MS ;消抖JB P1.0, DSWAITDSWAITEE: LCALL DISPLAY ;等键释放JNB P1.0, DSWAITEECLR EAMOV R0,#53H ;LJMP DSWAIT;以下秒表功能/时钟转换程序;按下P1.1 可进行功能转换FUNSS: LCALL DS20MSJB P1.1,START11WAIT11: JNB P1.1,WAIT11CPL 03HJNB 03H,TIMFUNMOV DISPFIRST,#60H ;显示秒表数据单元MOV 60H,#00HMOV 61H,#00HMOV 62H,#00HMOV 63H,#00HMOV 64H,#00HMOV 65H,#00HMOV TL1,#0F0H ;10MS定时初值()MOV TH1,#0D8H ;10MS定时初值SETB TR1SETB ET1START11: LJMP START1TIMFUN:MOV DISPFIRST,#70H ;显示时钟数据单元CLR ET1CLR TR1START12: LJMP START1;以下秒表暂停\清零功能程序;按下P1.2暂停或清0,按下P1.1退出秒表回到时钟计时FUNPTT: LCALL DS20MSJB P1.2,START12WAIT22: JNB P1.2,WAIT21CLR ET1CLR TR1WAIT33: JNB P1.1,FUNSSJB P1.2,WAIT31LCALL DS20MSJB P1.2,WAIT33WAIT66: JNB P1.2,WAIT61MOV 60H,#00HMOV 61H,#00HMOV 62H,#00HMOV 64H,#00HMOV 65H,#00HWAIT44: JNB P1.1,FUNSSJB P1.2,WAIT41LCALL DS20MSJB P1.2,WAIT44WAIT55: JNB P1.2,WAIT51SETB ET1SETB TR1AJMP START1;以下键等待释放时显示不会熄灭用WAIT21: LCALL DISPLAYAJMP WAIT22WAIT31: LCALL DISPLAYAJMP WAIT33WAIT41: LCALL DISPLAYAJMP WAIT44WAIT51: LCALL DISPLAYAJMP WAIT55WAIT61: LCALL DISPLAYAJMP WAIT66;;; 1秒计时程序;T0中断服务程序INTT0: PUSH ACC ;累加器入栈保护PUSH PSW ;状态字入栈保护CLR ET0 ;关T0中断允许CLR TR0 ;关闭定时器T0MOV A,#0B7H ;中断响应时间同步修正ADD A,TL0 ;低8位初值修正MOV TL0,A ;重装初值(低8位修正值)MOV A,#3CH ;高8位初值修正ADDC A,TH0 ;MOV TH0,A ;重装初值(高8位修正值)SETB TR0 ;开启定时器T0DJNZ R4, OUTT0 ;20次中断未到中断退出ADDSS: MOV R4,#14H ;20次中断到(1秒)重赋初值CPL 07H ;闹铃时间隔呜叫用MOV R0,#71H ;指向秒计时单元(71H-72H)ACALL ADD1 ;调用加1程序(加1秒操作)MOV A,R3 ;秒数据放入A(R3为2位十进制数组合)CLR C ;清进位标志CJNE A,#60H,ADDMM ;ADDMM: JC OUTT0 ;小于60秒时中断退出ACALL CLR0 ;大于或等于60秒时对秒计时单元清0MOV R0,#77H ;指向分计时单元(76H-77H)ACALL ADD1 ;分计时单元加1分钟MOV A,R3 ;分数据放入ACLR C ;清进位标志CJNE A,#60H,ADDHH ;ADDHH: JC OUTT0 ;小于60分时中断退出ACALL CLR0 ;大于或等于60分时分计时单元清0LCALL DS20MS ;正点报时SETB 08HMOV R0,#79H ;指向小时计时单元(78H-79H)ACALL ADD1 ;小时计时单元加1小时MOV A,R3 ;时数据放入ACLR C ;清进位标志CJNE A,#24H,HOUR ;HOUR: JC OUTT0 ;小于24小时中断退出ACALL CLR0 ;大于或等于24小时小时计时单元清0 OUTT0: MOV 72H,76H ;中断退出时将分、时计时单元数据移MOV 73H,77H ;入对应显示单元MOV 74H,78H ;MOV 75H,79H ;LCALL BAOJPOP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器SETB ET0 ;开放T0中断RETI ;中断返回;;; 闪动调时程序\秒表功能程序;;;T1中断服务程序,用作时间调整时调整单元闪烁指示或秒表计时INTT1: PUSH ACC ;中断现场保护PUSH PSW ;JB 03H, MMFUN ;=1时秒表MOV TL1, #0B0H ;装定时器T1定时初值MOV TH1, #3CH ;DJNZ R2,INTT1OUT ;0.3秒未到退出中断(50MS中断6次)MOV R2,#06H ;重装0.3秒定时用初值CPL 02H ;0.3秒定时到对闪烁标志取反JB 02H,FLASH1 ;02H位为1时显示单元"熄灭"MOV 72H,76H ;02H位为0时正常显示MOV 73H,77H ;MOV 74H,78H ;MOV 75H,79H ;INTT1OUT: POP PSW ;恢复现场POP ACC ;RETI ;中断退出FLASH1: JB 01H,FLASH2 ;01H位为1时,转小时熄灭控制MOV 72H,7AH ;01H位为0时,"熄灭符"数据放入分MOV 73H,7AH ;显示单元(72H-73H),将不显示分数据MOV 74H,78H ;MOV 75H,79H ;AJMP INTT1OUT ;转中断退出FLASH2: MOV 72H,76H ;01H位为1时,"熄灭符"数据放入小时MOV 73H,77H ;显示单元(74H-75H),小时数据将不显示MOV 74H,7AH ;MOV 75H,7AH ;AJMP INTT1OUT ;转中断退出;MMFUN : CLR TR1MOV A,#0F7H ;中断响应时间同步修正,重装初值(10ms)ADD A,TL1 ;低8位初值修正MOV TL1,A ;重装初值(低8位修正值)MOV A,#0D8H ;高8位初值修正ADDC A,TH1 ;MOV TH1,A ;重装初值(高8位修正值)SETB TR1 ;开启定时器T0MOV R0,#61H ;指向秒计时单元(71H-72H)ACALL ADD1 ;调用加1程序(加1秒操作)CLR C ;MOV A,R3 ;JZ FSS1 ;加1后为00,C=0AJMP OUTT01 ;加1后不为00,C=1FSS1: ACALL CLR0 ;大于或等于60秒时对秒计时单元清0 MOV R0,#63H ;指向分计时单元(76H-77H)ACALL ADD1 ;分计时单元加1分钟MOV A,R3 ;分数据放入ACLR C ;清进位标志CJNE A,#60H,ADDHH1 ;ADDHH1: JC OUTT01 ;小于60分时中断退出LCALL CLR0 ;大于或等于60分时分计时单元清0MOV R0,#65H ;指向小时计时单元(78H-79H)ACALL ADD1 ;小时计时单元加1小时OUTT01:POP PSW ;恢复状态字(出栈)POP ACC ;恢复累加器RETI ;中断返回;;; 加1子程序;;ADD1: MOV A,@R0 ;取当前计时单元数据到ADEC R0 ;指向前一地址SWAP A ;A中数据高四位与低四位交换ORL A,@R0 ;前一地址中数据放入A中低四位ADD A,#01H ;A加1操作DA A ;十进制调整MOV R3,A ;移入R3寄存器ANL A,#0FH ;高四位变0MOV @R0,A ;放回前一地址单元MOV A,R3 ;取回R3中暂存数据INC R0 ;指向当前地址单元SWAP A ;A中数据高四位与低四位交换ANL A,#0FH ;高四位变0MOV @R0,A ;数据放入当削地址单元中RET ;子程序返回;; 清零程序;对计时单元复零用CLR0: CLR A ;清累加器MOV @R0,A ;清当前地址单元DEC R0 ;指向前一地址MOV @R0,A ;前一地址单元清0RET ;子程序返回;;; 时钟时间调整程序;当调时按键按下时进入此程序SETMM: cLR ET0 ;关定时器T0中断CLR TR0 ;关闭定时器T0LCALL DL1S ;调用1秒延时程序LCALL DS20MS ;消抖JB P1.0,CLOSEDIS ;键按下时间小于1秒,关闭显示(省电)MOV R2,#06H ;进入调时状态,赋闪烁定时初值MOV 70H,#00H ;调时时秒单元为00 秒MOV 71H,#00HSETB ET1 ;允许T1中断SETB TR1 ;开启定时器T1SET2: JNB P1.0,SET1 ;P1.0口为0(键未释放),等待SETB 00H ;键释放,分调整闪烁标志置1SET4: JB P1.0,SET3 ;等待键按下LCALL DL05S ;有键按下,延时0.5秒LCALL DS20MS ;消抖JNB P1.0,SETHH ;按下时间大于0.5秒转调小时状态MOV R0,#77H ;按下时间小于0.5秒加1分钟操作LCALL ADD1 ;调用加1子程序MOV A,R3 ;取调整单元数据CLR C ;清进位标志CJNE A,#60H,HHH ;调整单元数据与60比较HHH: JC SET4 ;调整单元数据小于60转SET4循环LCALL CLR0 ;调整单元数据大于或等于60时清0CLR C ;清进位标志AJMP SET4 ;跳转到SET4循环CLOSEDIS: SETB ET0 ;省电(LED不显示)状态。

基于AT89C51芯片制作的数字时钟

基于AT89C51芯片制作的数字时钟

龙岩学院课程设计报告课程设计题目基于AT89C51芯片制作的数字时钟班级05 电本(2)班姓名邵利威学号2005040324任务书一.任务利用(AT89C51芯片)单片机定时器制作数字时钟二.设计目的通过课程设计的教学实践,进一步学习、掌握单片机应用系统的有关知识,加深了解单片机的工作原理。

初步掌握简单单片机应用系统的设计、制作、调试的方法。

提高动手实践能力、提高科学的思维能力。

要求三.设计要求1)数码管显示当前的时间值;2)时间精度为0.5秒,由时、分之间的分隔点的闪烁体现;3)两个按钮,一个用作“时”的设定另一个做“分”的设定;四.制作要求1.掌握单片机最小系统的电路原理图;2.硬件的焊接、连接;3.独立编辑、编译软件;数字时钟目前市场上提供的无论是机械钟还是石英钟在晚上无照明的情况下都是不可见的。

要知道当前的时间,必须先开灯,故较为不便。

现在市场上也出现了一些电子钟,它以四只LED数码管来显示时分,与传统的以指针显示秒的方式不同,违背了人们传统的习惯与理念,而且这类电子钟一般是采用大型显示器件,只适用于银行、车站等公共场所,且外观设计欠美观,很少进入百姓家庭。

此外无论是机械钟、石英钟还是电子钟,都价格比较昂贵。

针对以上存在的问题,我们设计了一款采用LED显示器件显示的电子时钟,经济实惠,且正确度高,又便于在无照明的情况下查看时间。

是一款真正价廉物美的电子时钟。

1 系统主要功能电子钟的主要功能有:四只LED数码管显示当前时分;两个按钮,一个用作“时”的设定另一个做“分”的设定。

长按按钮可进行快进调节。

2 系统的硬件构成及功能电脑钟的原理框图如图1所示。

它由以下几个部件组成:单片机89C2051、电源、时分显示部件以及显示驱动部分。

时分显示采用静态扫描,用74LS164驱动数码管显示时分,显示驱动的数据输出和时钟信号输出都通过AT89C2051的P1.0和P1.1口控制。

电源部分:电源部分有二部分组成。

AT89C51单片机设计60s倒计时

AT89C51单片机设计60s倒计时

目录一、课程设计的目的、要求和设计目标 (1)1、目的 (1)2、要求 (1)3、目标.................................................................. 1二、硬件要求 (2)1、 AT89C51的芯片 (2)2、 LED 数码管显示器概述 (3)3、其他元器件介绍及参数选择.......................................... 6三、软件设计 (7)1、程序流程图 (7)2、程序导图 (7)3、定时 /计数器初值计算 (7)4、软件程序 (8)5、软件仿真设计………………………………………………… 9四、软件调试…………………………………………………………101、 <.HEX>文件的生成 (10)2、PROTEUS …………………………………………………… 10五、心得体会…………………………………………………………11一、课程设计的目的、要求和设计目标1、目的单片机课程即将结束, 课程的最后一项是单片机的课程设计。

通过课程设计, 我们要将在一个学期中所学的东西进行整理、归纳, 要把学到的知识转化成实际的运用,进一步的了解单片机的实质。

通过动手设计,深入学习,体验单片机在日常生活中的运用,提升专业知识。

课程设计的总体包括:对单片机的了解、运用,设计思路的解析,报告文字的处理等。

通过一系列的实际操作, 完善对课程的学习, 提升自我的学习能力和动手能力。

2、要求(1用单片机 AT89C51的定时器实现 60s 倒计时。

本例中用两位数码管静态显示倒计时秒值。

(2用 PROTEUS 设计,仿真基于 AT89c51单片机的 60s 倒计时实验。

(3通过 Keil uVision2软件,生成 .HEX 格式程序并植入 AT59C51单片机并调试、运行。

3、目标通过自主完成课程设计内容, 整理学期中所学到的知识, 了解单片机的程序过程和一系列的基础操作,将理论和实践相结合,完善课业。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<reg51.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
/*七段共阳管显示定义*/
uint8 code dispcode[ ]={0x40,0x79,0x24,
0x30,0x19,0x12,0x02,
0x78,0x00,0x10};
/*定义并初始化变量*/
uint8 seconde=59;
uint16 mstcnt=0;
/*函数声明*/
void delay(uint8 k ); //延时子程序
void time_pro( ); //时间处理子程序
void display( ); //显示子程序
/*****************************/
/*延时子程序*/
/****************************/
void delay (uint8 k)
{
uint8 j;
while((k--)!=0)
{
for(j=0;j<125;j++)
{;}
}
}
/**************************/
/*时间处理子程序*/
/**************************/
void time_pro( void)
{
if(seconde==0)//秒钟设为59进制
{ seconde=59; }
}
/*****************************/
/* 显示子程序*/
/*****************************/
void display(void)
{
P1=dispcode[seconde/10]; //显示秒的十位
delay(4);
P2=dispcode[seconde%10]; //显示秒的个位
delay(4);
}
/**************************/
/*1s定时定时*/
/**************************/
void timer0(void) interrupt 1 using 0//定时器0方式1,250us中断一次{
TH0=0xff;
TL0=0x19;
TMOD = 0x01;
mstcnt++;
if(mstcnt==4000)
{
seconde--;
mstcnt=0; //注意对计数单元的清零
}
}
/**************************/
/*主函数*/
/**************************/
void main(void)
{ P1=0xff; //初始化p0口,全设为1使数码管P2=0xff; //初始化p2口,全设为1使数码管TMOD = 0x01; //time0为定时器,方式1
TH0=0xff; //预置计数初值
TL0=0x19;
EA=1;
ET0=1;
TR0=1;
while (1)
{
time_pro( ); //时间处理
display( ); //显示时间
}
}。

相关文档
最新文档