基于单片机的电子钟C语言程序
单片机电子闹钟程序亲自编写-可用
单片机电子闹钟程序(亲自编写-可用)————————————————————————————————作者:————————————————————————————————日期:学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。
其中正常时间显示和闹钟时间显示可用一个开关来调整。
芯片选择STC89C52程序:#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//定义显示段码uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};uchar codebbtime[]={0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar clock[]={0,0,0,0};uchar clock1[]={12,30,0};uchar weikong[6];uchar bbduration=4;uchar lingtime=9;//学校打铃时间组uchar shangwu1[]={8,30};uchar shangwu2[]={10,0};uchar shangwu3[]={10,20};uchar shangwu4[]={11,50};uchar xiawu1[]={13,30};uchar xiawu2[]={15,00};uchar xiawu3[]={15,15};uchar xiawu4[]={16,45};//按键定义sbit mode=P1^7;sbit sec_clr=P1^0;sbit min_set_add=P1^3;sbit min_set_sub=P1^4;sbit hour_set_add=P1^1;sbit hour_set_sub=P1^2;sbit bb_set_add=P1^5;sbit bb_set_sub=P1^6;sbit speaker=P2^6;//延时函数void delay(unsigned int t){while(t--);//时钟进位函数void clockjinwei(){clock[0]++;if(clock[0]==20){clock[1]++;clock[0]=0;if(clock[1]==60){clock[2]++;clock[1]=0;if(clock[2]==60){clock[3]++;clock[2]=0;if(clock[3]==24)clock[3]=0;}}}}//定时器0中断服务函数void timer0(void) interrupt 1 using 1 {TMOD=0x01;TH0=0x3c;TL0=0xb0;clockjinwei();}//时钟分位显示函数void fenwei(){weikong[0]=clock[3]/10;weikong[1]=clock[3]%10;weikong[2]=clock[2]/10;weikong[3]=clock[2]%10;weikong[4]=clock[1]/10;weikong[5]=clock[1]%10;}//闹钟分位显示函数void naofen(){weikong[0]=clock1[0]/10;weikong[1]=clock1[0]%10;weikong[2]=clock1[1]/10;weikong[3]=clock1[1]%10;weikong[4]=clock1[2]/10;weikong[5]=clock1[2]%10; }//闹钟定时显示函数void naozhongdisplay(){uchar z,s;uchar x=0x01;naofen();for(z=0;z<6;z++){P2=0;P0=table[weikong[z]];P2=x;x=_crol_(x,1);for(s=0;s<255;s++);}}//时钟显示函数void display(){uchar i,j;uchar x=0x01;fenwei();for(i=0;i<6;i++){P2=0;P0=table[weikong[i]];P2=x;x=_crol_(x,1);for(j=0;j<255;j++);}}//总显示函数void zhongxian(){if(mode==1)delay(100);if(mode==1)display();if(mode==0)delay(100);if(mode==0)naozhongdisplay();}//按键处理程序void key_set(){zhongxian();P1=0xff;if(min_set_add==0){delay(100);if(min_set_add==0){if(mode==1){clock[2]++;if(clock[2]==60){clock[2]=0;}while(min_set_add==0)zhongxian();}}if(mode==0){clock1[1]++;if(clock1[1]==60){clock1[1]=0;}while(min_set_add==0)zhongxian();}}//if(min_set_sub==0){delay(100);if(min_set_sub==0){if(mode==1){clock[2]--;if(clock[2]==0)clock[2]=59;}while(min_set_sub==0)zhongxian();if(mode==0){clock1[1]--;if(clock1[1]==0)clock1[1]=59;}while(min_set_sub==0)zhongxian();}}//if(hour_set_add==0){delay(100);if(hour_set_add==0){if(mode==1){clock[3]++;if(clock[3]==24){clock[3]=0;}while(hour_set_add==0)zhongxian();}if(mode==0){clock1[0]++;if(clock1[0]==24){clock1[0]=0;}while(hour_set_add==0)zhongxian();}}}//if(hour_set_sub==0){delay(100);if(hour_set_sub==0){if(mode==1){clock[3]--;if(clock[3]==0)clock[3]=23;}while(hour_set_sub==0)zhongxian();if(mode==0){clock1[0]--;if(clock1[0]==0)clock1[0]=23;}while(hour_set_sub==0)zhongxian();}}//if(sec_clr==0){delay(100);if(sec_clr==0){clock[1]=0;}while(sec_clr==0)zhongxian();}}//闹钟响铃函数void bb(){if(clock[1]<=bbduration){speaker=1;delay(100);speaker=0;}else speaker=0;}//打铃函数void daling(){if(clock[1]<=lingtime){speaker=1;delay(100);speaker=0;}else speaker=0;}//时间比较函数void bijiao(){if(clock[3]==shangwu1[0]){if(clock[2]==shangwu1[1])daling();}if(clock[3]==shangwu2[0]){if(clock[2]==shangwu2[1])daling();}if(clock[3]==shangwu3[0]){if(clock[2]==shangwu3[1])daling();}if(clock[3]==shangwu4[0]){if(clock[2]==shangwu4[1])daling();}if(clock[3]==xiawu1[0]){if(clock[2]==xiawu1[1])daling();}if(clock[3]==xiawu2[0]){if(clock[2]==xiawu2[1])daling();}if(clock[3]==xiawu3[0]){if(clock[2]==xiawu3[1])daling();}if(clock[3]==xiawu4[0]){if(clock[2]==xiawu4[1])daling();}}//闹钟比较void naobijiao(){if(clock[3]==clock1[0]){if(clock[2]==clock1[1]||clock[2]==clock1[1]+1||clock[2]==clock1[1]+2) bb();}}//响铃时长显示函数void bbtimeshow(){P3=bbtime[bbduration];if(bbduration>15)bbduration=0;}//响铃按键处理函数void bbtime_set(){bbtimeshow();if(bb_set_add==0){delay(100);if(bb_set_add==0)bbduration++;while(bb_set_add==0)bbtimeshow();}if(bb_set_sub==0){delay(100);if(bb_set_sub==0)bbduration--;while(bb_set_sub==0)bbtimeshow();}}//主程序void main(){EA=1;ET0=1;TR0=1;while(1){key_set();bijiao();bbtime_set();naobijiao();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到询问。
基于单片机电子时钟的设计与实现
基于单片机电子时钟的设计与实现一、设计目标设计一个基于单片机的电子时钟,能够准确显示时间并能够进行设置和调整。
二、硬件设计1.时钟部分:采用晶振芯片提供准确的时钟信号2.数码管显示部分:使用共阴数码管进行数字显示3.按键部分:设计几个按键用于设置和调整时间4.电源部分:采用直流电源供电三、软件设计1.功能设计a.时间设置功能:通过按键可以设置当前的时间,包括小时、分钟和秒钟。
b.时间调整功能:通过按键可以调整当前的时间,包括小时、分钟和秒钟。
c.时间显示功能:通过数码管可以实时显示当前的时间。
2.代码实现以C语言为例,以下是一个基于单片机的电子时钟的代码实现示例:```c#include <reg51.h>sbit DS18B20=P1^3; // 定义18B20数据线接口sbit beep=P2^3; // 定义蜂鸣器接口unsigned char hour,min,sec; // 定义小时、分钟、秒钟变量//函数声明void Delay_1ms(unsigned int count);bit Ds18b20Init(;unsigned char Ds18b20ReadByte(;void ReadTime(;void WriteTime(;void DisplayTime(;//主函数void mainP2=0x00;WriteTime(; // 写入时间while(1)ReadTime(; // 读取时间DisplayTime(; // 显示时间Delay_1ms(1000); // 延时1秒}//毫秒延时函数void Delay_1ms(unsigned int count) unsigned int i, j;for(i=0; i<count; i++)for(j=0; j<1275; j++);//18B20初始化函数bit Ds18b20Initbit presence;DS18B20=0;Delay_1ms(100); // 延时450us~1000us DS18B20=1;Delay_1ms(10); // 延时15us~60us presence=DS18B20;Delay_1ms(30); // 延时60us~240us return presence;//18B20读取字节函数unsigned char Ds18b20ReadByte unsigned char i, dat;for(i=0; i<8; i++)DS18B20=0;//主机发起读时序_nop_(; // 延时1us_nop_(; // 延时1us_nop_(; // 延时1usDS18B20=1;//主机释放总线_nop_(; // 延时1us_nop_(; // 延时1us_nop_(; // 延时1usdat,=(DS18B20<<i); // 读取数据位,存放在dat变量中Delay_1ms(3); // 读时序完成后等待48us再接收下一位}return dat;//读取时间函数void ReadTimeunsigned char temp;temp=0x00;while(temp!=0xaa)Ds18b20Init(; // 初始化温度传感器Delay_1ms(1);DS18B20=0xcc;Delay_1ms(1);DS18B20=0xbe;Delay_1ms(1);temp=Ds18b20ReadByte(; // 读取时间数组的标志位}for(temp=0; temp<7; temp++)//写入时间函数void WriteTimeunsigned char i,j;while(1)Ds18b20Init(;Delay_1ms(1);DS18B20=0xcc;Delay_1ms(1);DS18B20=0x4e;Delay_1ms(1);for(i=0; i<7; i++)DS18B20=0x55;Delay_1ms(1);DS18B20=0xaa;Delay_1ms(1);Ds18b20Init(;Delay_1ms(1);DS18B20=0xcc;Delay_1ms(1);DS18B20=0x48;Delay_1ms(1);j=Ds18b20ReadByte(; // 判断是否写入成功if(j==0x0a)break;}//显示时间函数void DisplayTimeP1=seg[hour/10]; // 显示十位小时P2=(P2&0xf0),0x08; // 点亮第一个数码管Delay_1ms(5); // 延时一段时间P2=0x0f;//熄灭数码管P1=seg[hour%10]; // 显示个位小时P2=(P2&0xf0),0x04; // 点亮第二个数码管Delay_1ms(5); // 延时一段时间P2=0x0f;//熄灭数码管P1=seg[min/10]; // 显示十位分钟P2=(P2&0xf0),0x02; // 点亮第三个数码管Delay_1ms(5); // 延时一段时间P2=0x0f;//熄灭数码管P1=seg[min%10]; // 显示个位分钟P2=(P2&0xf0),0x01; // 点亮第四个数码管Delay_1ms(5); // 延时一段时间P2=0x0f;//熄灭数码管P1=0x00;//空显示P2=0x00;//熄灭数码管```四、总结通过以上的硬件设计和软件实现,可以实现一个基于单片机的电子时钟。
51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)
51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)效果图:程序如下://51单片机c语言电子钟(已加入调时、闹铃、整点报时功能)#include<reg51.h>#include<absacc.h>#define uchar unsigned char#define uint unsigned int/*七段共阴管显示定义*///此表为LED 的字模,共阴数码管0-9 -uchar code dispcode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制/*定义并初始化变量*/uchar seconde=0;//秒uchar minite=0;//分uchar hour=12; //时uchar shi=0;//闹铃功能uchar fen=0;uchar bjcs;//报警次数sbit P1_0=P1^0; //second 调整定义sbit P1_1=P1^1; //minite调整定义sbit P1_2=P1^2; //hour调整定义sbit P1_5=P1^5; //整点报时sbit P1_3=P1^3; //闹铃功能,调整时间sbit P1_6=P1^6; //调整时sbit P1_7=P1^7; //调整分sbit P1_4=P1^4; //关闭闹铃/*函数声明*/void delay(uint k ); //延时子程序void time_pro( ); //时间处理子程序void display( ); //显示子程序void keyscan( ); //键盘扫描子程序/*xx子程序*/void delay (uint k){uchar j;while((k--)!=0){for(j=0;j<125;j++){;}}}/*时间处理子程序*/void time_pro(void){if(seconde==60){seconde=0;minite++;if(minite==60){minite=0;hour++;if(hour==24){hour=0;}}}}/*显示子程序*/void display(void){if(P1_3==1){P2=0XFE; P0=dispcode[seconde%10];//秒个位delay(1);P2=0XFD;P0=dispcode[seconde/10];//秒十位delay(1);P2=0XFB;P0=dispcode[10];//间隔符-delay(1);P2=0XF7;P0=dispcode[minite%10];//分个位delay(1);P2=0XEF;P0=dispcode[minite/10];//分十位delay(1);P2=0XDF;P0=dispcode[10];//间隔符-delay(1);P2=0XBF;P0=dispcode[hour%10];//时个位delay(1);P2=0X7F;P0=dispcode[hour/10];//时十位delay(1);}}/*键盘扫描子程序*/void keyscan(void){if(P1_0==0)//秒位的调整{delay (30);if(P1_0==0){seconde++;if(seconde==60){seconde=0;}}delay(250);}if(P1_1==0)//分位的调整{delay(30);if(P1_1==0){minite++;if(minite==60){minite=0;}}delay(250);}if(P1_2==0)//时位的调整{delay(30);if(P1_2==0){hour++;if(hour==24){hour=0;}}delay(250);}}/*整点报警*/void zhengdian (void){if((seconde==0)&(minite==0))//整点报时{P1_5=0;delay(1000);P1_5=1;}}/*定时闹钟*/void dingshi(void){if(P1_3==0)//按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。
超详细注释的C语言单片机电子时钟
ClockBeep(); //整点报时
}
ห้องสมุดไป่ตู้ }
}
void Init(void)
TL0 = (65536 - INTERRUPT_TIME * 1000) % 256;
ET0 = 1; //允许定时器0开启
EA = 1; //全局中断开启
//位选码,控制位选
//如若总线直连更为简单,使用译码器节约接口
unsigned char code bit_select[]={0xe3,0xe7,0xeb,0xef,0xf3,0xf7,0xfb,0xff};
//段选码,8位共阴极数码管的段选都连到P0口
//各个数码管为并联关系
unsigned char code segment_select[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
P0 = segment_select[CLEAR]; //清空数码管段选
TR0 = 0; //停止定时器0
reset = 0; //初始化各个变量
unsigned int time_count;//中断中的计数器
unsigned int beep_time = 0; //定义蜂鸣器时间变量
bit reset, start, beep_flag;//复位、开始、蜂鸣器的标志位
//初始化函数
void Init(void);
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};//0~F,清空,最后一位为分隔符
基于c51功能最全的电子钟程序(lcd1602)
功能最全的电子钟【单片机】c51数字时钟(带年月日显示)摘要:本设计以单片机为核心,lcd1602显示。
采用独立键盘输入能任意修改当前时间日期和设定闹钟时间。
具有显示年月日(区分闰年和二月),闹钟报警和整点报时功能主程序:/********************************************************************************************************************************************************************************* ****************************************** lcd1602电子钟********************************************************************************************************************************** *************************************************************************************************** ********************/# include <reg52.h># include "lcd16024.h"sbit key1 = P2^0; //调整sbit key2 = P2^1; //加1sbit key3 = P2^2; //减1sbit speaker = P2^3; //蜂鸣器sbit key4 = P2^4; //闹钟设计bit cal_year = 1; //进入判断闰年标志位bit leap_year; //闰年标志位bit calculate = 0; //日加一标记bit run = 0; //闹钟标志bit beep = 0; //整点报时标志//uint8 num = 0; //调整是给的脉冲uint8 code str1[] = "D: ";uint8 code str2[] = "T: ";uint8 code str3[] = "Wek";uint8 daystr[]="2013-07-29 "; //年月日格式uint8 timestr[]="21:30:59 N"; //时分秒格式uint8 daystr1[]="2013-07-29 "; //闹钟年月日格式uint8 timestr1[]="21:30:59 N"; //闹钟时分秒格式uint8 numweek = 0; //星期加1标记char week = 1; //星期char sec = 53; //秒char min = 50; //分char hour = 23; //时uint8 day = 30; // 日uint8 month = 9; //月uint16 year = 2013; //年char week1 = 1; //闹钟星期char sec1 = 58; //闹钟秒char min1 = 50; //闹钟分char hour1 = 23; //闹钟时uint8 day1 = 30; //闹钟日uint8 month1 = 9; //闹钟月uint16 year1 = 2013; //闹钟年uint8 WeekData1; //闹钟星期标记uint8 number = 0; //定时uint8 WeekData; //星期标记uint8 speaker_num; //整点报时次数uint8 scan_key(void); //函数声名/****************************************************************************** ***************************** 更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange(){//时分秒timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';timestr[4] = min%10+'0';timestr[3] = min/10+'0';timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';//年月日daystr[9] = day%10+'0';daystr[8] = day/10+'0';daystr[6] = month%10+'0';daystr[5] = month/10+'0';daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';//星期WeekData = week+'0';}/****************************************************************************** ***************************** 闹钟更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange1(){//时分秒timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';//年月日daystr1[9] = day1%10+'0';daystr1[8] = day1/10+'0';daystr1[6] = month1%10+'0';daystr1[5] = month1/10+'0';daystr1[3] = year1%10+'0';daystr1[2] = year1/10%10+'0';daystr1[1] = year1/100%10+'0';daystr1[0] = year1/1000+'0';//星期WeekData1 = week1+'0';}/****************************************************************************** ***************************** 初始化系统定时器0 ******************************************************************************************************************* *******/void systimer0_init(void){TMOD |=0x01;//设置为1时用或(|)TMOD &=0xfd;//设置为0时用与(&)TH0 = 0xDC; // 定时10msTL0 = 0x00;EA = 1;ET0=1;TR0=1;EX0 = 1;}/****************************************************************************** ***************************** 闹钟时间设置*************************************************************************************************************** *******/void naozhong(){uint8 number = 1;uint8 a = 0;uint8 b = 0;if(0 == key4){Delay1Ms(5);if(0 == key4){a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}while(!key4);}while(a){if(0 == key4){Delay1Ms(5);if(0 == key4){a = 0;run = ~run;while(!key4);}}if(run){timestr[9] = 'Y';}else{timestr[9] = 'N';}if(0 == key1){Delay1Ms(5);if(0 == key1){b = 1;}while(!key1);}while(b){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;if(4 == number)b = 0;}while(!key1);if(number == 1){LCD_write_command(0xc0+9);LCD_write_command(0x0f);}if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}}}switch(number){case 1:if(0 == key2) //闹钟秒加1的设置{Delay1Ms(5);if(0 == key2){sec1++;if(60 == sec1){sec1 = 0;}while(!key2);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}if(0 == key3) //闹钟秒减1的设置Delay1Ms(5);if(0 == key3){sec1--;if(sec1 < 0){sec1 = 59;}while(!key3);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}break;case 2:if(0 == key2) //闹钟分加1的设置{Delay1Ms(5);if(0 == key2){min1++;if(60 == min1){min1 = 0;}while(!key2);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}if(0 == key3) //闹钟分减1的设置{Delay1Ms(5);if(0 == key3){min1--;if(min1 < 0){min1 = 59;}while(!key3);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}break;case 3:if(0 == key2) //闹钟时加1的设置{Delay1Ms(5);if(0 == key2){hour1++;if(24 == hour1){hour1 = 0;}while(!key2);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //闹钟时减1的设置{Delay1Ms(5);if(0 == key3){hour1--;if(hour1 < 0){hour1 = 23;}while(!key3);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}break;case 4:b = 0;LCD_write_command(0x0c);break;}}}LCD_write_command(0x0c);while(!key4);}/****************************************************************************** ***************************** 判断按键进入时间调整*************************************************************************************************************** *******/uint8 scan_key(void){uint8 number = 1;uint8 a = 0;if(0 == key1){Delay1Ms(5);if(0 == key1){while(!key1);a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}}while(a){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;while(!key1);TR0 = 0;if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}if(number == 4){LCD_write_command(0x80+11);LCD_write_command(0x0f);}if(number == 5){LCD_write_command(0x80+8);LCD_write_command(0x0f);}if(number == 6){LCD_write_command(0x80+5);LCD_write_command(0x0f);}if(number == 7){LCD_write_command(0xc0+14);LCD_write_command(0x0f);}if(8 == number){LCD_write_command(0x0c);a = 0;number = 0;}}}switch(number){case 1:if(0 == key2) //秒加1的设置{Delay1Ms(5);if(0 == key2){sec++;if(60 == sec){sec = 0;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key2);}}if(0 == key3) //秒减1的设置{Delay1Ms(5);if(0 == key3){sec--;if(sec < 0){sec = 59;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key3);}}break;case 2:if(0 == key2) //分加1的设置{Delay1Ms(5);if(0 == key2){min++;if(60 == min){min = 0;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';;LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key2);}}if(0 == key3) //分减1的设置{Delay1Ms(5);if(0 == key3){min--;if(min < 0){min = 59;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key3);}}break;case 3:if(0 == key2) //时加1的设置{Delay1Ms(5);if(0 == key2){hour++;while(!key2);if(24 == hour){hour = 0;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //时减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);hour--;if(hour < 0){hour = 23;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}break;case 4:if(0 == key2) //日加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(day > 31){day=1;}}if(month==4|month==6|month==9|month==11){day++;if(day > 30){day=1;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day > 30){day=1;}}else{day++;if(day > 29){day=1;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}if(0 == key3) //日减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day--;if(day == 0){day=31;}}if(month==4|month==6|month==9|month==11){day--;if(day == 0){day=30;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day--;if(day == 0){day=30;}}else{day--;if(day == 0){day=29;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}break;case 5:if(0 == key2) //月加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);month++;if(13 == month){month = 1;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}if(0 == key3) //月减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);month--;if(month == 0){month = 12;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}break;case 6:if(0 == key2) //年加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);year++;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}if (0 == key3) //年减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);year--;if(year == 0){year = 2020;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}}break;case 7:if(0 == key2) //星期加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);week++;if(7 == week){week = 0;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}if (0 == key3) //星期减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);week--;if(week < 0){week = 6;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}break;case 8:TR0 = 1;break;}}}/****************************************************************************** ***************************** 主函数******************************************************************************************************************* *******/void main(void){systimer0_init();LCD_init();LCD_write_str(0,0,str1);LCD_write_str(0,1,str2);LCD_write_str(13,0,str3);speaker = 0;while (1){TimeChange();scan_key();naozhong();LCD_write_str(2,0,daystr);LCD_write_str(2,1,timestr);LCD_write_char(14,1,WeekData);if(1 == run){if(sec==sec1 & month==month1 & hour==hour){speaker_num =30;beep = 1;}}else{speaker_num =0;beep = 0;}}}/****************************************************************************** ***************************** 定时中断0 ******************************************************************************************************************* *******/void time_0() interrupt 1{TH0 = 0xDC; // 定时10msTL0 = 0x00;number++;if(number ==100){sec++;if(beep){speaker=!speaker;speaker_num--;if(speaker_num == 0){beep=0;speaker = 0;}}if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++; //小时加1speaker_num = hour%12; //蜂鸣器响的次数beep = 1;if(hour == 24){hour = 0;calculate = 1;if(calculate == 1) //判断这个月有多少天{if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(month==7|month==12){week++;if(7 == week){week = 0;}}else{if(day <= 31){week++;if(7 == week){week = 0;}}}if(day > 31){if(month==7|month==12){day = 1;}else{day=0;}month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month==4|month==6|month==9|month==11) {day++;week++;if(7 == week){week = 0;}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month == 2){while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day <= 30){week++;if(7 == week){week = 0;}}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}else{day++;week++;if(7 == week){week = 0;}if(day > 29){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}}}calculate=0;}}}}}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.c子程序:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /****************************************************************************** ***************************** lcd1602低层函数********************************************************************************************************************* *******/# include <reg52.h># include <intrins.h># include "lcd16024.h"# define LCD_DATA P0 //LCD1602的数据口定义sbit LCD_RS = P0^0; //LCD1602控制线的定义,4位控制方式sbit LCD_RW = P0^1;sbit LCD_EN = P0^2;/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Us(uint16 n){for(;n>0;n--){_nop_();}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Ms(uint16 n){while(n--){Delay1Us(1000);}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void LCD_en_write(void){LCD_EN=0;LCD_EN=1;Delay1Us(1);LCD_EN=0;}/****************************************************************************** ************************ LCD写一个字节命令函数************************************************************************************************************ *******/void LCD_write_command(uint8 command){Delay1Us(16);LCD_RS=0;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();command=command<<4;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();}/****************************************************************************** ********************** LCD写一个字节数据函数*************************************************************************************************************** *******/void LCD_write_data(uint8 Data){Delay1Us(16);LCD_RS=1;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();Data=Data<<4;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();}/****************************************************************************** ***************************** LCD1602光标定位函数************************************************ x--列0~15;y--行0~1********************************************************************************************************* *******/void LCD_set_xy(uint8 x,uint8 y){uint8 address;if(y==0)address=0x80+x;else address=0xc0+x;LCD_write_command(address);}/***************************************************************************************************** LCD1602 初始化函数,四位显示方式******************************************************************************************************* *******/void LCD_init(){LCD_write_command(0x28);// Delay1Us(40);LCD_write_command(0x28);LCD_write_command(0x0c);LCD_write_command(0x01);LCD_write_command(0x06);Delay1Ms(2);}/****************************************************************************** ***************************** LCD写字符串函数******************************************************* x--列0~15;y--行0~1******************************************************* s指向字符串数组**************************************************************************************************************** *******/void LCD_write_str(uint8 x,uint8 y,uint8 *s){LCD_set_xy(x,y);while(*s){LCD_write_data(*s);s++;}}/****************************************************************************** ***************************** LCD写一个字符函数******************************************************* x--列0~15;y--行0~1******************************************************* d--字符的ASCII码**************************************************************************************************************** *******/void LCD_write_char(uint8 x,uint8 y,uint8 d){LCD_set_xy(x,y);LCD_write_data(d);}/*////////////////////////////////////////////////////////////////// 等待繁忙标志/////////////////////////////////////////////////////////////////void LCD_wait(void){P0 = 0xFF;do{LCD_RS = 0;LCD_RW = 1;LCD_EN = 0;LCD_EN = 1;}while (BUSY == 1);LCD_EN = 0;}*//****************************************************************************** ***************************** LCD1602左移********************************************************************************************************************* *******void LCD_youyi(uint8 y,uint8 *s){LCD_write_str(17,y,s);for(a=0;a<16;a++){LCD_write_command(0x1c); //左移LCD_write_command(0x1c); 为右移Delay1Ms(6);}}*///LCD_write_command(0x0d);//光标闪烁//LCD_write_command(0x0e);//光标显示不闪烁//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.h头文件////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _LCD16024_H_#define _LCD16024_H_typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;void Delay1Us(uint16 n);void Delay1Ms(uint16 n);void LCD_write_data(uint8 dat);void LCD_write_command(uint8 com); //BuysC为0时忽略忙检测void LCD_set_xy(uint8 x,uint8 y);void LCD_en_write(void);void LCD_write_char(uint8 x, uint8 y, uint8 Data1);void LCD_write_str(uint8 x, uint8 y,uint8 *s);void LCD_init();//void LCD_wait(void);//void LCD_youyi(uint8 y,uint8 *s);#endif。
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];
基于C51单片机的数字时钟课程设计(C语言带闹钟)
单片机技术课程设计数字电子钟学院:班级:姓名:学号:教师:摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。
所以设计一个简易数字电子钟很有必要。
本电子钟采用AT89C52单片机为核心,使用12MHz 晶振与单片机AT89C52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。
该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEY5键,进行相应的操作就可实现校时、定时、复位功能。
具有时间显示、整点报时、校正等功能。
走时准确、显示直观、运行稳定等优点。
具有极高的推广应用价值。
关键词:电子钟 AT89C52 硬件设计软件设计目录NO TABLE OF CONTENTS ENTRIES FOUND.一、数字电子钟设计任务、功能要求说明及方案介绍1.1 设计课题设计任务设计一个具有特定功能的电子钟。
具有时间显示,并有时间设定,时间调整功能。
1.2 设计课题的功能要求说明设计一个具有特定功能的电子钟。
该电子钟上电或按键复位后能自动显示系统提示符“d.1004-22”,进入时钟准备状态;第一次按电子钟启动/调整键,电子钟从12时59分0秒开始运行,进入时钟运行状态;按电子钟S5键,则电子钟进入时钟调整状态,此时可利用各调整键调整时间,调整结束后可按S5键再次进入时钟运行状态。
1.3 设计课的设计总体方案介绍及工作原理说明本电子钟主要由单片机、键盘、显示接口电路和复位电路构成,设计课题的总体方案如图1所示:图1-1总体设计方案图本电子钟的所有的软件、参数均存放在AT89C52的Flash ROM和内部RAM 中,减少了芯片的使用数量简化了整体电路也降低了整机的工作电流。
键盘采用动态扫描方式。
利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据,同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。
单片机C语言_电子时钟程序
#include<AT89X52.H>#define uint unsigned int#define uchar unsigned charunsigned char key2;bit ding=1;unsigned char Getkey(void);uchar a,n=0,shi,fen,miao;void delay01s(void);uchar LED[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};uchar LED1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//有小数点的void init(); //函数声明void Delay(unsigned char z);//函数声明void display(); //函数声明//函数声明void main() //函数声明{P1=0xfe;//对P1口赋初值init(); //函数调用while(1){//函数调用key2=Getkey();switch(key2){case 1:shi++;if(shi==24){shi=0;}break;case 2:fen++;if(fen==60){fen=0;}break;case 3:if(fen!=0)fen--;if(fen==24){fen=0;}break;case 4:ding=~ding;default:break;}display(); //函数调用}}void init(){TMOD=0x01; //定时器工作方式选择和赋初值TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //开定时器中断TR0=1; //启动定时器}void timer0() interrupt 1 //中断服务程序{if(ding==1){TH0=(65536-50000)/256;//中断时间50msTL0=(65536-50000)%256; //定时器重新赋初值a++;if(a==10){n=~n;}if(a==20){n=~n;a=0;P1=P1<<1|P1>>7;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}}}}}}void display()//显示程序{P0=LED[shi/10];P2=((P2&0x0f)|0x70); Delay(4);if(n==0){P0=LED[shi%10];}else{P0=LED1[shi%10];}P2=((P2&0x0f)|0xb0);Delay(4);P0=LED[fen/10];P2=((P2&0x0f)|0xd0);Delay(4);P0=LED[fen%10];P2=((P2&0x0f)|0xe0);Delay(4);}/**********获得键值子程序**********************/ unsigned char bool;//bool 是否松键的标志unsigned char Getkey(void){unsigned char temp,key=0;P2=(P2&0xff)|0x0f;if((P2&0xff)!=((P2&0xff)|0x0f)) // 有键按下{//delay01s();if(((P2&0xff)!=((P2&0xff)|0x0f)) &&(bool==0)) // 有键按下{temp=~(P2|0xf0);if(temp==1) key=1;else if(temp==2) key=2;else if(temp==4) key=3;else if(temp==8) key=4;bool=1;}}if(((P2&0xff)==((P2&0xff)|0x0f)) &&(bool==1)){bool=0;}return key; //返回1~16键值}/********延时程序******/void delay01s(void){unsigned char j,k;for(j=5;j>0;j--) //198{for(k=15;k>0;k--)//248{;}}}void Delay(unsigned char z){unsigned char i,j,k; //定义变量for(i=z;i>0;i--)for(j=25;j>0;j--)for(k=20;k>0;k--);}#include<reg52.h>//头文件#define uchar unsigned char//宏定义#define uint unsigned intsbit P31=P3^1;//位声明sbit P32=P3^2;sbit P33=P3^3;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴段码表uint hou1,hou2,min1,min2,sec1,sec2,numhou,nummin,numsec,yue1,yue2,ri1,ri2,numyue,numri; uint num,m,n;void delayms(uint xms)//延时函数{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void p31xd()//按键P31消抖{ delayms(2);while(P31!=1);delayms(2);}void p32xd()//按键P32消抖{ delayms(1);while(P32!=1);delayms(1);}void p33xd()//按键P33消抖{ delayms(1);while(P33!=1);delayms(1);}void displaysj()//显示时间{P2=0x00;P0=table[hou1];//显示时的第一位P2=0X20;delayms(1);P2=0xff;P0=table[hou2]&0x7f;//显示时的第二位与小数点P2=0X10;delayms(1);P2=0xff;P0=table[min1];//显示分的第一位P2=0X08;delayms(1);P2=0xff;P0=table[min2]&0x7f;//显示时的第二位与小数点P2=0X04;delayms(1);P2=0xff;P0=table[sec1];//显示秒的第一位P2=0X02;delayms(1);P2=0xff;P0=table[sec2];//显示秒的第二位P2=0X01;delayms(1);}void displayrq()//显示日期{ P2=0x00;P0=table[yue1];//显示月的第一位P2=0X20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;//显示月的第二位P2=0X10;delayms(1);P2=0x00;P0=table[ri1];//显示日的第一位P2=0X08;delayms(1);P2=0x00;P0=table[ri2];//显示日的第二位P2=0X04;delayms(1);}void houqh()//时针切换函数{hou1=numhou/10;hou2=numhou%10;}void minqh()//分针切换函数{min1=nummin/10;min2=nummin%10;}void secqh()//秒针切换函数{sec1=numsec/10;sec2=numsec%10;}void yueqh()//月切换函数{yue1=numyue/10;yue2=numyue%10;}void riqh()//日切换函数{ri1=numri/10;ri2=numri%10;}void start()//初始化函数{num=0;TMOD=0x01;TH0=(65532-45872)/256;TL0=(65532-45872)%256;EA=1;IT0=0;//电平触发(低电平有效)EX0=1;ET0=1;TR0=1;yueqh(),riqh();//初始化日月切换}void ritiao()//日期的调节函数{ if(P32==0)//日期加一调节键{p32xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31)//如果是大月,日期有31号,等于符号是防止日期大于31号而乱码{numri=1;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=30)//如果是小月,日期有30号{numri=1;}}if(numyue==2){numri+=1;if(numri>=28)//如果是小月,日期有28号{numri=1;}}riqh();//日期调节后切换一下}if(P33==0)//日期减一调节键{p33xd();if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri-=1;if(numri==0){numri=31;}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri-=1;if(numri==0){numri=30;}}if(numyue==2){numri-=1;if(numri==0){numri=28;}}riqh();}}void yuetiao()//月份的调节函数{if(P32==0){p32xd();numyue+=1;if(numyue==13)//月份为12时再加一马上为一月{numyue=1;}yueqh();}if(P33==0){p33xd();numyue-=1;if(numyue==0){numyue=12;}yueqh();}}void int0() interrupt 0{p31xd();while(P31!=0)//第一次按下p31时,进行秒调时{for(m=0;m<40;m++)//此for循环不显示秒,为的是使秒闪烁{P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);if(P32==0)//如果按一下P32,则秒加一{p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0)//如果按一下P33,则秒减一{p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}};for(n=0;n<40;n++)//此循环时分秒全显示,也为的是使秒闪烁{ displaysj();if(P32==0){p32xd();numsec+=1;if(numsec==60){numsec=0;}secqh();}if(P33==0){p33xd();numsec-=1;if(numsec==-1){numsec=59;}secqh();}}};p31xd();while(P31!=0)//第二次按下p31时,进行分调时{for(m=0;m<40;m++){P2=0x00;P0=table[hou1];P2=0X20;delayms(1);P2=0x00;P0=table[hou2]&0x7f;P2=0X10;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){p33xd();nummin-=1;if(nummin==-1){nummin=59;}minqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();nummin+=1;if(nummin==60){nummin=0;}minqh();}if(P33==0){nummin-=1;if(nummin==-1){nummin=59;}minqh();}}};p31xd();while(P31!=0)//第三次按下p31时,进行时调时{for(m=0;m<40;m++){P2=0x00;P0=table[min1];P2=0X08;delayms(1);P2=0x00;P0=table[min2]&0x7f;P2=0X04;delayms(1);P2=0x00;P0=table[sec1];P2=0X02;delayms(1);P2=0x00;P0=table[sec2];P2=0X01;delayms(1);if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}for(n=0;n<40;n++){ displaysj();if(P32==0){p32xd();numhou+=1;if(numhou==24){numhou=0;}houqh();}if(P33==0){p33xd();numhou-=1;if(numhou==-1){numhou=23;}houqh();}}}p31xd();while(P31!=0)//第四次按下p31时,进行日期调节{for(m=0;m<50;m++){ P2=0x00;P0=table[yue1];P2=0x20;delayms(1);P2=0x00;P0=table[yue2]&0x7f;P2=0x10;delayms(1);ritiao();}for(n=0;n<50;n++){ displayrq();ritiao();}}p31xd();while(P31!=0)//第五次按下p31时,进行月调节{for(m=0;m<50;m++){P2=0xff;P0=table[ri1];P2=0xf7;delayms(1);P2=0xff;P0=table[ri2];P2=0xfb;delayms(1);yuetiao();}for(n=0;n<50;n++){ displayrq();yuetiao();}}p31xd();}void yuejia(){ numri=1;numyue+=1;if(numyue==13){numyue=1;}}void timer0() interrupt 1{TH0=(65532-46100)/256;TL0=(65532-46100)%256;num++;if(num==20){num=0;TH0=(65532-46100)/256;TL0=(65532-46100)%256;numsec=numsec+1;if(numsec==60){numsec=0;nummin=nummin+1;if(nummin==60){nummin=0;numhou=numhou+1;if(numhou==24){numhou=0;numri+=1;if((numyue==1)||(numyue==3)||(numyue==5)||(numyue==7)||(numyue==8)||(numyue==10)||( numyue==12)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if((numyue==4)||(numyue==6)||(numyue==9)||(numyue==11)){numri+=1;if(numri>=31){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}if(numyue==2){numri+=1;if(numri>=29){numri=1;numyue+=1;if(numyue==13){numyue=1;}}}}}}}}void main(){numhou=12;//初始化时间设为12点,日期设为1月1日nummin=0;numsec=0;numyue=1;numri=1;start();while(1){if(P32==1)//默认(没有按下p32时)显示时间{houqh(),minqh(),secqh();displaysj();}if(P32==0)//当按下p32键时显示日期{yueqh(),riqh();displayrq();}}}。
单片机基于c语言编写时钟
单片机基于c语言编写时钟#include <REGX51.H>#define uint unsigned int#define uchar unsigned charchar led[10]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xe6};//共阴数码管数字码#define weixuan P0 //P0为数码管的段选sbit sck=P2^7; //移位时钟sbit tck=P2^6; //锁存时钟sbit data1=P2^5; //串行数据输入sbit x1=P1^0;sbit x2=P1^1;sbit x3=P1^2;sbit bee=P3^5;sbit time_change=P1^5; //P3^0为"调时"按键sbit time_choose=P1^6; //P3^1为"选择时分秒"按键sbit time_inc=P1^7; //P3^2为"增加"按键sbit time_ok=P3^3; //P3^3为"完成"按键uint t;uchar sec,min,hour,sec_ge,sec_shi,min_ge,min_shi,hour_ge,hour_shi; //定义秒,分,时,秒的个位,十位,分的个位,十位,时的个位,十位int choose_n; //按下"选择时分秒"按键的次数int flag; //定义"调时"按键的标志位//---------------------------------------------------------------------void init();void display();void delay(int x);void time_modify();void send(uchar data8);void naozhong();//---------------------------------------------------------------------void main(){init();while(1){TR0=1;display();time_modify();}}//---------------------------------------------------------------------void init(){t=choose_n=0;sec_ge,sec_shi,min_ge,min_shi,hour_ge,hour_shi,sec=min=hour=flag=0;TMOD=0x01; //定义定时器0工作与方式1TH0=(65536-60000)/256; //定时器赋初值TL0=(65536-60000)%256;EA=1; //开总中断和T0中断ET0=1;}//---------------------------------------------------------------------void send(uchar data8) // 数据发送{uchar i;//设置循环变量sck=1;tck=1;for(i=0;i<=7;i++){if((data8>>i)&0x01)data1=1;elsedata1=0;sck=0;sck=1;}tck=0;tck=1;}//--------------------------------延时子函数------------------------------------void delay(int x){int i,j;for(i=0;i<=x;i++)for(j=0;j<=100;j++);}//-------------------------------显示子函数---------------------------------------void display(){int i=0;if(TF0==1) //如果定时器溢出{TF0=0; //清中断标志位t++;if(t==18){t=0;sec++; //秒加1if(sec==60) //如果秒为60,则清零,分加1{sec=0;min++;}if(min==60) //如果分为60,则清零,时加1{min=0;hour++;}if(hour==24) //如果时为24,则清零{hour=0;}}}sec_ge=sec%10; //秒的个位和十位sec_shi=sec/10;min_ge=min%10; //分的个位和十位min_shi=min/10;hour_ge=hour%10; //时的个位和十位hour_shi=hour/10;weixuan = 0xff; // p0口为1111 1111send(led[hour_shi]); // 显示第一位时weixuan= 0xfe; // p0口为1111 1110delay(1);weixuan=0xff; // 消影send(led[hour_ge]); // 显示第二位时weixuan= 0xfd; // p0口为1111 1101delay(1);weixuan=0xff; // 消影send(0x02); // 显示第三位weixuan= 0xfb; // p0口为1111 1011delay(1);weixuan=0xff; // 消影send(led[min_shi]); // 显示第四位分weixuan= 0xf7; // p0口为1111 0111delay(1);weixuan=0xff; // 消影send(led[min_ge]); // 显示第5位分weixuan= 0xef; // p0口为1110 1111delay(1);weixuan=0xff; // 消影send(0x02); // 显示第6位weixuan= 0xdf; // p0口为1101 1111delay(1);weixuan=0xff; // 消影send(led[sec_shi]); // 显示第7位秒weixuan= 0xbf; // p0口为1011 1111delay(1);weixuan=0xff; // 消影send(led[sec_ge]); // 显示第8位秒weixuan= 0x7f; // p0口为0111 1111delay(1);weixuan=0xff; // 消影}//----------------------------调时子程序-------------------------------void time_modify(){if(time_change==0) //如果"调时"按键按下{delay(5); //延时去抖if(time_change==0){flag=1; //标志位置1while(flag) //当标志位为1时才能进行时间调整{TR0=0; //定时器停止display(); //显示停止时的时间if(time_ok==0) //如果"完成"按键按下{delay(15); //延时去抖if(time_ok==0){flag=0; //标志位清零x1=1;x2=1;x3=1;}}if(time_choose==0) //如果"时分秒选择"按键按下{delay(30); //延时去抖if(time_choose==0){while(!time_choose);choose_n++; //按下的次数增加if(choose_n==4) //如果次数达到4次{choose_n=1; //次数清零}if(choose_n==1) //如果次数为1,秒指示灯亮{x1=0;x2=1;x3=1;}else if(choose_n==2) //如果次数为2,分指示灯亮{x1=1;x2=0;x3=1;}else if(choose_n==3) //如果次数为3,时指示灯亮{x1=1;x2=1;x3=0;}}}if(time_inc==0) //如果"增加"按键按下{delay(30); //延时去抖if(time_inc==0){switch(choose_n) //分支结构,根据choose_n的值来判断哪一位加1 {case 1: //如果choose_n为1,秒加1,到60清零{while(!time_inc);sec++;if(sec==60)sec=0;break;}case 2: //如果choose_n为2,分加1,到60清零{while(!time_inc);min++;if(min==60)min=0;break;}case 3: //如果choose_n为3,时加1,到24清零{while(!time_inc);hour++;if(hour==24)hour=0;break;}default:break;}}}}}}}。
基于单片机C语言电子时钟完整版(闹钟,整点报时)
《单片机技术》课程设计说明书数字电子钟系、部:电气与信息工程学院学生姓名:指导教师:职称专业:班级:完成时间:2013-06-07摘要电子钟在生活中应用非常广泛,而一种简单方便的数字电子钟则更能受到人们的欢迎。
所以设计一个简易数字电子钟很有必要。
本电子钟采用ATMEL公司的AT89S52单片机为核心,使用12MHz 晶振与单片机AT89S52 相连接,通过软件编程的方法实现以24小时为一个周期,同时8位7段LED数码管(两个四位一体数码管)显示小时、分钟和秒的要求,并在计时过程中具有定时功能,当时间到达提前定好的时间进行蜂鸣报时。
该电子钟设有四个按键KEY1、KEY2、KEY3、KEY4和KEU5键,进行相应的操作就可实现校时、定时、复位功能。
具有时间显示、整点报时、校正等功能。
走时准确、显示直观、运行稳定等优点。
具有极高的推广应用价值。
关键词电子钟;AT89S52;硬件设计;软件设计ABSTRACTClock is widely used in life, and a simple digital clock is more welcomed by people. So to design a simple digital electronic clock is necessary.The system use a single chip AT89S52 of ATMEL’s as its core to control The crystal oscillator clock,using of E-12MHZ is connected with the microcontroller AT89S52, through the software programming method to achieve a 24-hour cycle, and eight 7-segment LED digital tube (two four in one digital tube) displays hours, minutes and seconds requirements, and in the time course of a timing function, when the time arrived ahead of scheduled time to buzz a good timekeeping. The clock has four buttons KEY1, KEY2, KEY3,KEY4 and KEY5 key, and make the appropriate action can be achieved when the school, timing, reset. With a time display, alarm clock settings, timer function, corrective action. Accurate travel time, display and intuitive, precision, stability, and so on. With a high application value.Key words Electronic clock;;AT89S52;Hardware Design;Software Design目录1设计课题任务、功能要求说明及方案介绍 (1)1.1设计课题任务 (1)1.2功能要求说明 (1)1.3设计总体方案介绍及原理说明 (1)2设计课题硬件系统的设计 (2)2.1设计课题硬件系统各模块功能简要介绍 (2)2.2设计课题电路原理图、PCB图、元器件布局图 (2)2.3设计课题元器件清单 (5)3设计课题软件系统的设计 (6)3.1设计课题使用单片机资源的情况 (6)3.2设计课题软件系统各模块功能简要介绍 (6)3.3设计课题软件系统程序流程框图 (6)3.4设计课题软件系统程序清单 (10)4设计结论、仿真结果、误差分析、教学建议 (21)4.1设计课题的设计结论及使用说明 (21)4.2设计课题的仿真结果 (21)4.3设计课题的误差分析 (22)4.4设计体会 (22)4.5教学建议 (22)结束语 (23)参考文献 (24)致谢 (25)附录 (26)1 设计课题任务、功能要求说明及方案介绍1.1 设计课题任务设计一个具有特定功能的电子钟。
单片机c 语言编程时钟及闹钟程序
一·功能1、计时功能,数码管显示数值从00:00:00--23:59:59循环替换,且周期时间与实际时间吻合。
2、定时闹钟功能,按下“定时”键后,可以设定所需要的任意时间,定时完成后,当到达设定时间后,蜂鸣器发声。
3、调整时间功能,根据此项功能可将时钟调至正确的时间。
4、查看定时功能,当设定完成后可以查看上次定时的时间,且能在此基础上进行重新定时。
二·按键说明设定键:按一次开始设定时间,并将设定过程显示在数码管上。
若未按此键,则其他按键无效。
设定过程中,再按一次此键,定时结束,数码管显示返回时钟。
当第一次按下设定键时,显示值为00:00:00,在此基础上调节定时时间。
第一次设定完成后,以后再按设定键,显示初值则为上次定时的时间。
确定键:在定时过程中按下此键,则保留当前设定的时间为定时时间。
若定时过程未按此键,定时无效。
向上键:按下此键,使得当前设定值在现有数值上加一,当加至满位时,当前值变为零。
向下键:按下此键,使得当前设定值在现有数值上减一,当减至零时,当前值变为满位减一。
向左键:按下此键,使得设定值移向左边一位,若已经在最左边,则移至最右边。
向右键:按下此键,使得设定值移向右边一位,若已经在最右边,则移至最左边。
三·具体操作演示(一)·定时及查看定时演示1.仿真开始。
如图:2、按键如图:3、按下设定键,开始设定时间,如图:4、如图所示,当前设定时位。
按向上键,使数值加一。
5、按下向右键,设定位移至分位。
6、按下向下键,使数字减一。
7、按确定键,确定当前设定的时间。
再按设定键,退出定时,开始时钟显示。
8、设定完成后按设定键,显示前次设定值,可在此基础上重新设定,也可直接再按设定键推出。
9、当时钟运行到设定时间时,蜂鸣器发声。
(二)·调整时间演示1、计时开始。
2、按照定时的方法开始设定时间,使其显示20:10:09。
3、调整到正确时间后,按下确定键不放,同时再按一下设定键,将目前设定值送入时钟,使其开始从设定值计时。
51单片机电子时钟(C语言)
#include <reg51.h>#include <intrins.h>#define uchar unsigned char //宏定义#define uint unsigned intuchar sec,min,hour,sec50,jishu,dtp2; //sec、min、hour、为显示单元,sec50为60秒计数单元,jishu为扫描数码管计数单元uchar sec1,min1,hour1; //时间中介单元uchar nzmin,nzhour,nzjishu=0,dispjishu=0; //闹钟分、时定义uchar data nzbit=0; //闹钟标志位,闹钟默认为开启uchar data dispbit=0; //显示标志位,默认显示当前时间uchar data disp[8]; //秒、分、时个位与十位存放数组及‘—’uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数字0-9sbit KEYmin=P3^2; //分加1按钮sbit KEYhour=P3^3; //时加1按钮sbit LABA=P1^0; //闹钟输出I/O口sbit NZdisplay=P3^4; //闹钟显示按钮,按住不放显示闹钟时间,放开则显示当前时间sbit KEYnzmin=P3^5; //闹钟分加1按钮sbit KEYnzhour=P3^6; //闹钟时加1按钮sbit KEYoff=P3^7; //关闭闹钟按钮,按第一次为关闭,第二次为开启void display(); //显示函数声明void keyscan(); //按键扫描函数声明void naozhong(); //闹钟判别函数声明void keynz(); //闹钟按键函数声明void main(){sec=0; //时间初始化为00—00—00min=0;hour=0;sec1=0; //显示单元初始化为00—00—00min1=0;hour1=0;nzmin=01; //闹钟初始时间为01:01nzhour=01;jishu=0;dtp2=0xfe;P0=0xff;TMOD=0x11; //设T0、T1为模式1IE=0x8a;TH0=0xb8; //T0定时20msTL0=0x0;TH1=0xfc; //T1定时1msTL1=0x66;TR0=1;TR1=1;while(1){display(); //调用显示子程序keyscan(); //调用按键子程序keynz(); //调用闹钟按键子程序}}void t0int() interrupt 1 //T0定时中断程序{TH0=0xb8;TL0=0x0;sec50++;if(sec50==50) //对20ms计数50次即1s{sec50=0; //清秒计数器,为下次做准备naozhong(); //调用闹钟判别子程序sec1++; //秒加1}if(sec1==60) //对秒计数60次即1min{sec1=0;min1++; //分加1}if(min1==60) //对分计数60次即1hour{min1=0;hour1++; //时加1}if(hour1==24){hour1=0;}if(dispbit==0) //判断显示标志位是否为0,为0显示当前时间{sec=sec1;min=min1;hour=hour1;}else //显示标志位为1,显示闹钟时间{min=nzmin; //将闹钟时间给显示单元hour=nzhour;}}void t1int() interrupt 3 //T1中断程序{TH1=0xfc;TL1=0x66;P2=0xff; //关闭所有数码管P2=dtp2;dtp2=_crol_(dtp2,1);P0=disp[jishu];jishu++;if(jishu==8) //扫描完8位数码管清0,重新从第一位开始扫描{jishu=0;}}void delay(uint x) //延时函数uchar i;while(x--){for(i=0;i<120;i++);}}void display() //显示子程序{disp[7]=table[sec%10]; //秒个位显示disp[6]=table[sec/10]; //秒十位显示disp[4]=table[min%10]; //分个位显示disp[3]=table[min/10]; //分十位显示disp[1]=table[hour%10]; //时个位显示disp[0]=table[hour/10]; //时十位显示disp[2]=0xbf; //显示‘_’disp[5]=0xbf;}void keyscan() //按键子程序{delay(20); //延时消抖if(KEYmin==0)//时间分加1按钮{min1++; //时间分加1if(min1==60){min1=0;hour1++; //分加到60对时加1}if(hour1==24){hour1=0;}while(!KEYmin); //等待按键放开}delay(20); //延时消抖if(KEYhour==0) //时间时加1按钮{hour1++; //时间时加1if(hour1==24){hour1=0;}while(!KEYhour); //等待按键放开}void naozhong() //闹钟判断{if(nzbit==0) //判断闹钟标志位,0为开启闹钟判断,1为关闭闹钟{if(min1==nzmin) //闹钟与时间分的判别if(hour1==nzhour) //闹钟与时间时的判别LABA=0; //时间分、时与闹钟分、时相等就打开蜂鸣器}elseLABA=1;}void keynz() //闹钟加、减及闹钟关闭、开启按键处理子程序{delay(20); //延时消抖if(KEYnzmin==0) //判别闹钟分加1按键{nzmin++; //闹钟分加1if(nzmin==60){nzmin=0;nzhour++; //闹钟分加到60对闹钟时加1if(nzhour==24)nzhour=0;}while(!KEYnzmin); //等待按键放开}delay(20); //延时消抖if(KEYnzhour==0) //判别闹钟时加1按键{nzhour++; //闹钟时加1if(nzhour==24)nzhour=0;while(!KEYnzhour); //等待按键放开}if(KEYoff==0)//判断关闭闹钟按键是否按下{delay(20); // 延时消抖nzjishu++;if(nzjishu==1) //判断是否为第一次按下{nzbit=1; //第一次按下关闭闹钟if(nzjishu==2) //判断是否为第二次按下{nzjishu=0; //第二次按下清计数单元nzbit=0; // 第二次按下开启闹钟判别}while(!KEYoff); //等待按键放开}if(NZdisplay==0) //判别显示切换闹钟按键是否按下{dispjishu++;if(dispjishu==1) //第一次按下显示闹钟时间{dispbit=1; //第一次按下,把标志位置1,显示切换为闹钟时间}if(dispjishu==2) //第二次按下显示为当前时间{dispjishu=0; //清零,重新计数dispbit=0; //第二次按下清零显示标志位,显示切换为当前时间}while(!NZdisplay); //等待按键放开}}。
超级电子时钟程序(52单片机C语言)
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit lcd_light=P1^0;sbit lcd_rs=P1^1;sbit lcd_rw=P1^2;sbit lcd_en=P1^3;sbit beep=P3^6;sbit DS18B20=P3^7;sbit SCLK=P3^3;sbit SDA=P3^4;sbit RST=P3^5;sbit SW1=P1^4;sbit SW2=P1^5;sbit SW3=P1^6;sbit SW4=P1^7;bitAMPM,music,light,clock_changing=1,clock1=1,clock2=1,clock3=1,forever1=1,forever2=1,forev er3=1,same=1,mode;uchar i,j,num,key,ring=1,timer,tian,light_continue,led,lsd1=0xfe;uchar code table1[]="20 / /";uchar code table2[]="Ring";uchar code table3[]="readyrunstopMode";uchar code table4[]="Good morning,sir";uchar code table5[]="Have a good day!";uchar write_add[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80}; //年、星期、月、日、时、分、秒uchar read_add[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}; //年、星期、月、日、时、分、秒uchar time[]={11,2,4,5,22,23,55}; //年、星期、月、日、时、分、秒uchar clock_time1[]={11,2,4,5,22,23,38}; //年、星期、月、日、时、分、秒uchar clock_time2[]={11,2,4,5,22,23,38}; //年、星期、月、日、时、分、秒uchar clock_time3[]={11,2,4,5,22,23,38}; //年、星期、月、日、时、分、秒uchar s,f,m,dian; //时、分、秒、小数点uchar *ptime[7]; //年、星期、月、日、时、分、秒void delay1(){;;}void delay2(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di(){if(music==0){beep=0;delay2(50);beep=1;}}void running_led1(){P2=lsd1;}void running_led2(){switch(num){case 1:P2=0x00;break;case 25:P2=0xc0;break;case 27:P2=0x60;break;case 29:P2=0x30;break;case 31:P2=0x18;break;case 33:P2=0x0c;break;case 35:P2=0x06;break;case 37:P2=0x03;break;}}void running_led3(){switch(num){case 1:P2=0x7e;break;case 2:P2=0xbd;break;case 3:P2=0xdb;break;case 4:P2=0xe7;if(same==0){if(music==0)di();else{music=0;di();music=1;}} break;case 5:P2=0xe7;if(same==0){if(music==0)di();else{music=0;di();music=1;}} break;case 6:P2=0xdb;break;case 7:P2=0xbd;break;}}uchar how_many_days(uchar year,uchar month){uchar tian;if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==1 2))tian=31;else if(month==2){if(((year+2000)%4==0)&&((year+2000)%100!=0)||((year+2000)%400==0))tian=29;elsetian=28;}elsetian=30;return(tian);}void week_scan(){uchar year,month=1,day=1,week,tian;if(*ptime[0]<10){year=0;week=6;}else if((*ptime[0]>=10)&&(*ptime[0]<20)){year=10;week=5;}else if((*ptime[0]>=20)&&(*ptime[0]<30)){year=20;week=3;}else if((*ptime[0]>=30)&&(*ptime[0]<40)){year=30;week=2;}else if((*ptime[0]>=40)&&(*ptime[0]<50)){year=40;week=7;}else if((*ptime[0]>=50)&&(*ptime[0]<60)){year=50;week=6;}else if((*ptime[0]>=60)&&(*ptime[0]<70)){year=60;week=4;}else if((*ptime[0]>=70)&&(*ptime[0]<80)){year=70;week=3;}else if((*ptime[0]>=80)&&(*ptime[0]<90)){year=80;week=1;}else if(*ptime[0]>=90){year=90;week=7;}while((*ptime[0]!=year)||(*ptime[2]!=month)||(*ptime[3]!=day)) {day++;week++;if(week>=8)week=1;tian=how_many_days(year,month);if(day>tian){day=1;month++;if(month>12){month=1;year++;}}}*ptime[1]=week;}//液晶写命令写数据程序void write_com(uchar com){lcd_rs=0;delay2(1);P0=com;lcd_en=1;delay2(1);lcd_en=0;}void write_dat(uchar dat){lcd_rs=1;delay2(1);P0=dat;lcd_en=1;delay2(1);lcd_en=0;}void init_lcd1602(){uchar i;lcd_rw=0;lcd_en=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80+1);for(i=0;i<8;i++)write_dat(table1[i]);write_com(0x80+0x40+3);write_dat(':');write_com(0x80+0x40+6);write_dat(':'); }//DS1302读写程序void write_DS1302_byte(uchar dat) {uchar i;for(i=0;i<8;i++){SCLK=0;SDA=dat&0x01;SCLK=1;dat=dat>>1;}}void write_DS1302(uchar add,uchar dat) {RST=0;SCLK=0;RST=1;delay1();write_DS1302_byte(add);write_DS1302_byte(dat);RST=0;delay1();RST=1;SCLK=1;}uchar read_DS1302(uchar add){uchar i,dat;RST=0;SCLK=0;delay1();RST=1;delay1();write_DS1302_byte(add);for(i=0;i<8;i++){dat=dat>>1;SCLK=0;if(SDA)dat=dat|0x80;SCLK=1;}RST=0;delay1();RST=1;SCLK=1;return(dat);}void dat_to_BCD(){uchar i,j;for(i=0;i<7;i++){j=time[i]/10;time[i]=time[i]%10;time[i]=time[i]+j*16;}}void BCD_to_dat(){uchar i,j;for(i=0;i<7;i++){j=time[i]/16;time[i]=time[i]%16;time[i]=time[i]+j*10;}}void set_time_to_DS1302(){uchar i;dat_to_BCD();write_DS1302(0x8e,0x00);for(i=0;i<7;i++)write_DS1302(write_add[i],time[i]);write_DS1302(0x8e,0x80);}void get_time_from_Ds1302(){uchar i;for(i=0;i<7;i++)time[i]=read_DS1302(read_add[i]);BCD_to_dat();}void write_nyr(uchar add,uchar dat){uchar shi,ge;shi=dat/10;ge=dat%10;write_com(0x80+add);write_dat(0x30+shi);write_dat(0x30+ge);}void write_sfm(uchar add,uchar dat){uchar shi,ge;shi=dat/10;ge=dat%10;write_com(0x80+0x40+add);write_dat(0x30+shi);write_dat(0x30+ge);}void write_week(){write_com(0x80+13);switch(*ptime[1]){case 1:write_dat('M');write_dat('O');write_dat('N');break;case 2:write_dat('T');write_dat('U');write_dat('E');break;case 3:write_dat('W');write_dat('E');write_dat('D');break;case 4:write_dat('T');write_dat('H');write_dat('U');break;case 5:write_dat('F');write_dat('R');write_dat('I');break;case 6:write_dat('S');write_dat('A');write_dat('T');break;case 7:write_dat('S');write_dat('U');write_dat('N');break;}}//DS18B20读写程序void init_DS18B20(){uint i;DS18B20=1;delay1();DS18B20=0;for(i=0;i<70;i++);//延时563微秒DS18B20=1;for(i=0;i<60;i++);//延时483微秒}bit read_temp_byte(){uint i;bit dat;DS18B20=1;delay1();DS18B20=0;delay1();DS18B20=1;delay1();dat=DS18B20;for(i=0;i<4;i++);//延时35微秒return(dat);}uchar read_temp(){uchar i,j,dat;for(i=0;i<8;i++){j=read_temp_byte();dat=(j<<7)|(dat>>1);}return(dat);}void write_DS18B20(uchar dat){uint i;uchar j;bit byte;for(j=0;j<8;j++){byte=dat&0x01;dat=dat>>1;if(byte){DS18B20=0;i++;i++;i++;i++;//延时16微秒DS18B20=1;for(i=0;i<5;i++);//延时43微秒}else{DS18B20=0;for(i=0;i<7;i++);//延时59微秒DS18B20=1;}}}void temp_change(){init_DS18B20();delay2(1);write_DS18B20(0xcc);//写跳过读ROM指令write_DS18B20(0x44);//写温度转换指令}uint get_temp(){uchar a,b;uint temp;//注意要是无符号整形变量8位float f_temp;init_DS18B20();delay2(1);write_DS18B20(0xcc);write_DS18B20(0xbe);a=read_temp();b=read_temp();temp=b;temp=temp<<8;temp=temp|a;f_temp=temp*0.0625;temp=f_temp*10+0.5;return(temp);}//显示程序void display_temp(){uchar shi,ge,dian;uint t;//注意要是无符号整形变量8位temp_change();t=get_temp();shi=t/100;ge=t%100/10;dian=t%100%10;write_com(0x80+0x40+11);write_dat(0x30+shi);write_dat(0x30+ge);write_dat('.');write_dat(0x30+dian);write_dat('C');}void renew_nyr(){write_nyr(3,*ptime[0]);write_week();write_nyr(6,*ptime[2]);write_nyr(9,*ptime[3]);}void write_xiaoshi(){write_com(0x80+0x40);if(AMPM==0){write_dat(' ');write_sfm(1,*ptime[4]);}else{if(*ptime[4]>=12){write_dat('P');if(*ptime[4]==12)write_sfm(1,12);elsewrite_sfm(1,*ptime[4]-12);}else{write_dat('A');write_sfm(1,*ptime[4]);}}}void renew_sfm(){write_xiaoshi();write_sfm(4,*ptime[5]);write_sfm(7,*ptime[6]);}void renew_time(){renew_nyr();renew_sfm();}void Is_it_time_to_ring(){if(clock1==0){for(i=0;((time[i]==clock_time1[i])&&(i<7));i++);if(i>=7){same=0;led=2;if(forever1==1)clock1=1;else{clock_time1[3]=clock_time1[3]+1;clock_time1[1]=clock_time1[1]+1;if(clock_time1[1]>=8)clock_time1[1]=1;tian=how_many_days(clock_time1[0],clock_time1[2]);if(clock_time1[3]>tian){clock_time1[3]=1;clock_time1[2]=clock_time1[2]+1;if(clock_time1[2]>12){clock_time1[2]=1;clock_time1[0]=clock_time1[0]+1;if(clock_time1[0]==100)clock_time1[0]=0;}}}write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);write_dat('1');}}if(clock2==0){for(i=0;((time[i]==clock_time2[i])&&(i<7));i++);if(i>=7){same=0;led=2;if(forever2==1)clock2=1;else{clock_time2[3]=clock_time2[3]+1;clock_time2[1]=clock_time2[1]+1;if(clock_time2[1]>=8)clock_time2[1]=1;tian=how_many_days(clock_time2[0],clock_time2[2]);if(clock_time2[3]>tian){clock_time2[3]=1;clock_time2[2]=clock_time2[2]+1;if(clock_time2[2]>12){clock_time2[2]=1;clock_time2[0]=clock_time2[0]+1;if(clock_time2[0]==100)clock_time2[0]=0;}}}write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);write_dat('2');}}if(clock3==0){for(i=0;((time[i]==clock_time3[i])&&(i<7));i++);if(i>=7){same=0;led=2;if(forever3==1)clock3=1;else{clock_time3[3]=clock_time3[3]+1;clock_time3[1]=clock_time3[1]+1;if(clock_time3[1]>=8)clock_time3[1]=1;tian=how_many_days(clock_time3[0],clock_time3[2]);if(clock_time3[3]>tian){clock_time3[3]=1;clock_time3[2]=clock_time3[2]+1;if(clock_time3[2]>12){clock_time3[2]=1;clock_time3[0]=clock_time3[0]+1;if(clock_time3[0]==100)clock_time3[0]=0;}}}write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);write_dat('3');}}}void display_time(){if((led!=3)||(light==0)){if((led==0)||((light==0)&&(lcd_light==0))||(clock1==0)||(clock2==0)||(clock3==0)){i=time[6];get_time_from_Ds1302();if(i!=time[6]){if(led==0)lsd1=_cror_(lsd1,1);if((light==0)&&(lcd_light==0)){light_continue++;if(light_continue==5)lcd_light=1;}j++;if(j>=6)j=1;}}switch(led){case 1:num++;if(num>=38)num=1; break;case 2:num++;if(num>=8)num=1; break;}}get_time_from_Ds1302();for(i=0;i<7;i++)ptime[i]=&time[i];if(same==1)renew_time();else delay2(60);}//键盘扫描程序void SW1_scan(){if(SW1==0){if((key==0)&&(clock_changing==1)){delay2(300);if(SW1!=0){di();AMPM=~AMPM;display_time();}elsedelay2(700);}elsedelay2(20);if(SW1==0){di();key++;if(clock_changing==0){switch(ring){case 1:clock1=1;break;case 2:clock2=1;break;case 3:clock3=1;break;}}while(!SW1);}}}void SW4_scan(){uchar i;if(SW4==0){if((key==0)||(clock_changing==0)){delay2(300);if(SW4!=0){di();switch(ring){case 1: for(i=0;i<7;i++)ptime[i]=&clock_time1[i];break;case 2: for(i=0;i<7;i++)ptime[i]=&clock_time2[i];break;case 3: for(i=0;i<7;i++)ptime[i]=&clock_time3[i];break;}clock_changing=~clock_changing;if(clock_changing==0){renew_time();write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);switch(ring){case 1: write_dat('1');case 2: write_dat('2');case 3: write_dat('3');}}else{switch(ring){case 1:clock1=~clock1;if(key==0)forever1=1;break;case 2:clock2=~clock2;if(key==0)forever2=1;break;case 3:clock3=~clock3;if(key==0)forever3=1;break;}if((forever1==1)&&(forever2==1)&&(forever3==1)){write_com(0x80);write_dat(' ');}key=0;}}else{delay2(700);if(SW4==0){if(clock_changing==0){di();key=0;clock_changing=1;write_com(0x01);write_com(0x80);for(i=0;i<16;i++)write_dat(table4[i]);write_com(0x80+0x40);for(i=0;i<16;i++)write_dat(table5[i]);switch(ring){case 1:clock1=0;forever1=0;break;case 2:clock2=0;forever2=0;break;case 3:clock3=0;forever3=0;break;}while(!SW4);init_lcd1602();}else{music=~music;di();write_com(0x80+0x40+11);write_dat(' ');write_dat(' ');write_dat('O');if(music==0){write_dat('N');write_dat(' ');}else{write_dat('F');write_dat('F');}}while(!SW4);}}}if(key!=0){ delay2(20);if(SW4==0){di();key=0;write_com(0x0c);set_time_to_DS1302();display_time();while(!SW4);}}}}void renew_timer_time(){write_sfm(0,s);write_sfm(3,f);write_sfm(6,m);write_sfm(9,dian);}void choose_rings(){uchar i;switch(ring){case 1: for(i=0;i<7;i++)ptime[i]=&clock_time1[i];break;case 2: for(i=0;i<7;i++)ptime[i]=&clock_time2[i];break;case 3: for(i=0;i<7;i++)ptime[i]=&clock_time3[i];break;}renew_time();write_com(0x80+0x40+15);switch(ring){case 1: write_dat('1');case 2: write_dat('2');case 3: write_dat('3');}}void timer_and_led(){uchar i;if(timer==0){delay2(300);if(SW2){di();num=0;led++;if(led==3)P2=0xff;if(led>=4)led=0;}else{delay2(700);if(SW2==0){di();timer++;s=f=m=dian=0;mode=0;write_com(0x01);write_com(0x80);for(i=12;i<16;i++)write_dat(table3[i]);write_dat(':');write_dat('1');write_com(0x80+0x40+2);write_dat(':');write_com(0x80+0x40+5);write_dat(':');write_com(0x80+0x40+8);write_dat('.');write_com(0x80+0x40+11);for(i=0;i<5;i++)write_dat(table3[i]);renew_timer_time();while(!SW2);delay2(10);while(!SW2);}}}else{timer++;if(timer==2){di();write_com(0x80+0x40+11);write_dat(' ');write_dat(' ');for(i=5;i<8;i++)write_dat(table3[i]);while(!SW2);TR0=1;delay2(10);while(!SW2);}if(timer==3){TR0=0;di();if(mode==1)timer=1;write_com(0x80+0x40+11);write_dat(' ');for(i=8;i<12;i++)write_dat(table3[i]);while(!SW2);delay2(10);while(!SW2);}if(timer>=4){i=255;di();while((!SW2)&&(i>0)){i--;delay2(5);}if(i==0){di();timer=0;write_com(0x01);init_lcd1602();display_time();display_temp();while(!SW2);}else{timer=1;s=f=m=dian=0;renew_timer_time();write_com(0x80+0x40+11);for(i=0;i<5;i++)write_dat(table3[i]);}}}}void change_timer(){if(SW4==0){TR0=0;di();mode=~mode;write_com(0x80+5);if(mode==0)write_dat('1');else write_dat('2');timer=1;s=f=m=dian=0;renew_timer_time();write_com(0x80+0x40+11);for(i=0;i<5;i++)write_dat(table3[i]);while(!SW4);delay2(10);while(!SW4);}}void SW2_scan(){if(SW2==0){if(key==0){if(clock_changing==1)timer_and_led();else{delay2(20);if(SW2==0){di();ring++;if(ring>=4)ring=1;choose_rings();}while(!SW2);}}else{delay2(20);if(SW2==0){di();switch(key){case 1: *ptime[0]=*ptime[0]+10;if(*ptime[0]>99)*ptime[0]=0;write_nyr(3,*ptime[0]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 2: *ptime[0]=*ptime[0]+1;if(*ptime[0]>99)*ptime[0]=0;write_nyr(3,*ptime[0]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 3: *ptime[2]=*ptime[2]+10;if(*ptime[2]>12)*ptime[2]=1;write_nyr(6,*ptime[2]);week_scan();write_week(); break;case 4: *ptime[2]=*ptime[2]+1;if(*ptime[2]>12)*ptime[2]=1;write_nyr(6,*ptime[2]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 5: *ptime[3]=*ptime[3]+10;tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian)*ptime[3]=1;write_nyr(9,*ptime[3]);week_scan();write_week(); break;case 6: *ptime[3]=*ptime[3]+1;tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian)*ptime[3]=1;write_nyr(9,*ptime[3]);week_scan();write_week(); break;case 7: *ptime[4]=*ptime[4]+10;if(*ptime[4]>=24)*ptime[4]=0;write_xiaoshi(); break;case 8: *ptime[4]=*ptime[4]+1;if(*ptime[4]>=24)*ptime[4]=0;write_xiaoshi(); break;case 9: *ptime[5]=*ptime[5]+10;if(*ptime[5]>=60)*ptime[5]=0;write_sfm(4,*ptime[5]); break;case 10:*ptime[5]=*ptime[5]+1;if(*ptime[5]>=60)*ptime[5]=0;write_sfm(4,*ptime[5]); break;case 11:*ptime[6]=*ptime[6]+10;if(*ptime[6]>=60)*ptime[6]=0;write_sfm(7,*ptime[6]); break;case 12:*ptime[6]=*ptime[6]+1;if(*ptime[6]>=60)*ptime[6]=0;write_sfm(7,*ptime[6]); break;}while(!SW2);}}}}void normal_or_save(){delay2(300);if(SW3){di();lcd_light=0;light_continue=0;}else{delay2(700);if(SW3==0){di();light=~light;if(light==0)lcd_light=1;elselcd_light=0;while(!SW3);}}}void SW3_scan(){if(SW3==0){if(key==0){if(clock_changing==1)normal_or_save();else{delay2(20);if(SW3==0){di();if(ring==1)ring=3;else ring--;choose_rings();}while(!SW3);}}else{delay2(20);if(SW3==0){di();switch(key){case 1: if(*ptime[0]>=10)*ptime[0]=*ptime[0]-10;else*ptime[0]=99;write_nyr(3,*ptime[0]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 2: if(*ptime[0]>=1)*ptime[0]=*ptime[0]-1;else*ptime[0]=99;write_nyr(3,*ptime[0]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 3: if(*ptime[2]>=11)*ptime[2]=*ptime[2]-10;else*ptime[2]=12;write_nyr(6,*ptime[2]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 4: if(*ptime[2]>=2)*ptime[2]=*ptime[2]-1;else*ptime[2]=12;write_nyr(6,*ptime[2]);if(*ptime[2]==2){tian=how_many_days(*ptime[0],*ptime[2]);if(*ptime[3]>tian){*ptime[3]=tian;write_nyr(9,*ptime[3]);}}week_scan();write_week(); break;case 5: if(*ptime[3]>=11)*ptime[3]=*ptime[3]-10;else{tian=how_many_days(*ptime[0],*ptime[2]);*ptime[3]=tian;}write_nyr(9,*ptime[3]);week_scan();write_week(); break;case 6: if(*ptime[3]>=2)*ptime[3]=*ptime[3]-1;else{tian=how_many_days(*ptime[0],*ptime[2]);*ptime[3]=tian;}write_nyr(9,*ptime[3]);week_scan();write_week(); break;case 7: if(*ptime[4]>=10)*ptime[4]=*ptime[4]-10;else*ptime[4]=23;write_xiaoshi(); break;case 8: if(*ptime[4]>=1)*ptime[4]=*ptime[4]-1;else*ptime[4]=23;write_xiaoshi(); break;case 9: if(*ptime[5]>=10)*ptime[5]=*ptime[5]-10;else*ptime[5]=59;write_sfm(4,*ptime[5]); break;case 10:if(*ptime[5]>=1)*ptime[5]=*ptime[5]-1;else*ptime[5]=59;write_sfm(4,*ptime[5]); break;case 11:if(*ptime[6]>=10)*ptime[6]=*ptime[6]-10;else*ptime[6]=59;write_sfm(7,*ptime[6]); break;case 12:if(*ptime[6]>=1)*ptime[6]=*ptime[6]-1;else*ptime[6]=59;write_sfm(7,*ptime[6]); break;}while(!SW3);}}}}void keyscan(){if(same==1){if(timer==0){SW1_scan();SW4_scan();if(key!=0){switch(key){case 1: write_com(0x80+3);write_com(0x0f); break;case 2: write_com(0x80+4); break;case 3: write_com(0x80+6); break;case 4: write_com(0x80+7); break;case 5: write_com(0x80+9); break;case 6: write_com(0x80+10); break;case 7: write_com(0x80+0x40+1); break;case 8: write_com(0x80+0x40+2); break;case 9: write_com(0x80+0x40+4); break;case 10:write_com(0x80+0x40+5); break;case 11:write_com(0x80+0x40+7); break;case 12:write_com(0x80+0x40+8); break;case 13:if(clock_changing==1){key=0;write_com(0x0c);set_time_to_DS1302();display_time();}else key=1; break;}}}SW2_scan();SW3_scan();if(timer!=0)change_timer();}else{if((SW1==0)||(SW2==0)||(SW3==0)||(SW4==0)){delay2(20);if((SW1==0)||(SW2==0)||(SW3==0)||(SW4==0)){same=1;led=0;while((!SW1)||(!SW2)||(!SW3)||(!SW4));}}}}void main(){init_lcd1602();TMOD=0x01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;//set_time_to_DS1302();while(1){keyscan();if((key==0)&&(clock_changing==1)&&(timer==0)){display_time();if(same==1){write_com(0x80+0x40+11);if((clock1==1)&&(clock2==1)&&(clock3==1))display_temp();else{switch(j){case 1: if(clock1==0){if(forever1==0){write_com(0x80);write_dat('*');}write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);write_dat('1');}else{write_com(0x80);write_dat(' ');display_temp();} break;case 2: if(clock2==0){if(forever2==0){write_com(0x80);write_dat('*');}write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);write_dat('2');}else{write_com(0x80);write_dat(' ');display_temp();} break;case 3: if(clock3==0){if(forever3==0){write_com(0x80);write_dat('*');}write_com(0x80+0x40+11);for(i=0;i<4;i++)write_dat(table2[i]);write_dat('3');}else{write_com(0x80);write_dat(' ');display_temp();} break;case 4: write_com(0x80);write_dat(' ');display_temp();break;case 5: display_temp();break;}}Is_it_time_to_ring();}if(led!=3){switch(led){case 0:running_led1();break;case 1:running_led2();break;case 2:running_led3();break;}}}}}void T0_timer() interrupt 1//中断函数{TR0=0;TH0=(65536-10000)/256;TL0=(65536-10000)%256;TR0=1;dian++;if(dian>=100){dian=0;m++;if(m>=60){m=0;f++;if(f>=60){f=0;s++;if(s>=24)TR0=0;write_sfm(0,s);}write_sfm(3,f);}write_sfm(6,m);}write_sfm(9,dian);}。
基于51单片机的电子钟
#include <reg52.h>#define uchar unsigned charsbit addr0 = P1^4;//系统片选地址线0sbit addr1 = P1^5;//系统片选地址线1sbit addr2 = P1^6;//系统片选地址线2sbit addr3 = P1^7;//系统片选地址线3//行扫描数组uchar code scan[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//row0--row7//数码管显示的段码表uchar code table[18] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,//0,1,2,3,4,50x82,0xf8,0x80,0x90,0x88,0x83,//6,7,8,9,a,b0xc6,0xa1,0x86,0x8e,0xbf,0xff};//c,d,e,f,-,空格uchar dispbuf[8]; //显示缓冲区unsigned char second,minute,hour,count,flag,keybit;//秒,分,时,50ms计数器,数码管刷新标志/******************************延时函数****************************/void delay(unsigned int loop){ unsigned int i ; //loop 为执行空指令的次数,改变它可一改变延时时长for(i=0;i<loop;i++);//循环执行空指令loop次,达到延时目的}/***********************************初始化函数*************************/ void initial(){ uchar j;second=0x00;//秒清零minute=0x00;//分清零hour = 12; //时12count = 20;//50毫秒置初值keybit = 0;//读键延时标志flag = 0x01;//清除刷新标志for(j=0;j<8;j++)dispbuf[j] = 1;//清数码管显示缓冲区TMOD = 0x11;//T0 T1工作于方式1TL1 = 0x00;TH1 = 0x4C;//50ms定时初值ET1 = 1;//允许T1中断PT1 = 1;//T1中断优先级高EA = 1;//开中断TR1 = 1;//T1开始计时}/******************************显示+读键*************************/void ledscan(){ unsigned char i,key,value,keyvalue,dispvalue;for(i=0;i<8;i++){addr3 = 0;addr0 = 0;addr1 = 1;addr2 = 0;//开发板上U4(74HC574)的片选地址P0 = 0xff; //关显示addr3 = 1;addr3 = 0;//在U4的11脚(锁存信号)产生上升沿P2 = scan[i];//取row0--row7行扫描数据addr0 = 0;addr1 = 0;addr2 = 1;//开发板上U6(74HC244)的片选地址addr3 = 1;P0 = 0xff;//准备读取按键if((P0 !=0xff) && keybit==0)//是否有按键和按键标志是否被清除{value = 0;key = ~P0;keybit = 1;//置已按键标志while(key){value++;key = key /2;}keyvalue = 8*i + value;//计算十六进制键值switch(keyvalue)//转按键功能处理{case 4: if(hour==23)hour = 0;elsehour++;//时加1break;case 8: if(hour==0)hour = 23;elsehour--;//时减1break;case 12: if(minute==59)minute = 0;elseminute++;//分加1break;case 16: if(minute==0)minute = 59;elseminute--;//分减1break;case 15: second = 0;//秒清零break;default: break;}}addr3 = 0;//键值读取完成,使U6无效addr3 = 0;addr0 = 0;addr1 = 1;addr2 = 0;//开发板上U4(74HC574)的片选地址dispvalue =table[dispbuf[i]]; //取一行显示数据if(i==5 && flag)dispvalue &= 0x7f;//秒指示闪烁P0 = dispvalue;addr3 = 1;addr3 = 0;//在U4的11脚(锁存信号)产生上升沿delay(50); //延时50us}}/*********************************50ms中断响应****************************/ void int50ms() interrupt 3{TR1=0;//关定时器T0TL1= 0x00;TH1= 0x4C;//赋定时初值TR1=1;//开定时器T0count--;//50ms计数减1if(count == 10)flag = 0;if(count == 0)//1秒定时到{count = 20;//重赋50ms计数值flag = 1;keybit = 0;if(second != 59)second++;//秒加1else{second=0x00;if(minute !=59)minute++;//分加1else{minute=0x00;if(hour != 23)hour++;//时加1elsehour =0x00;}}}}/*************************************填充显示缓冲区****************************/void feedbuffer(){uchar temp;temp = second;dispbuf[7] = temp % 10;//秒个位数码管位选顺序temp = temp / 10; // 0 1 2 3 4 5 6 7dispbuf[6] = temp % 10;//秒十位8 8 8 8 8 8 8 8dispbuf[0] = 17; //不显示temp = minute;dispbuf[5] = temp % 10;//分个位temp = temp / 10;dispbuf[4] = temp % 10;//分十位dispbuf[3] = 16;//显示"-"temp = hour;dispbuf[2] =temp % 10;//时个位temp = temp / 10;dispbuf[1] =temp % 10;//时十位}/*************************************主函数*********************************/main(){initial();//初始化while(1){feedbuffer();//填充显示缓冲区ledscan();//送显示}}/************************************结束**************************************/。
基于单片机的LED点阵电子钟 C程序代码
//------------------------------定义头文件#include <reg51.h>//MCS-51单片机//------------------------------定义缩写字符#define uchar unsigned char#define uint unsigned int//------------------------------定义扬声器接口,低电平使能sbit Bell_Out = P1 ^ 5;//扬声器驱动//------------------------------定义DS18B20音sbit DQ = P1 ^ 6;//ds1820data(单总线)//------------------------------定义DS1302时钟接口sbit clock_clk = P3 ^ 5;//ds1302_clk(时钟线)sbit clock_dat = P3 ^ 6;//ds1302_dat(数据线)sbit clock_Rst = P3 ^ 7;//ds1302_Rst(复位线)//-----------------------------定义数据口#define Led_13 P0 //第1、3屏数据口#define Led_24 P2 //第2、4屏数据口#define Led_E P1 //74HC154的BCD列驱动(P1.0~P1.4)sbit Led_EA = P1 ^ 4;//显示列驱动器(74HC154)使能//-----------------------------独立键盘定义sbit Add_Key = P3 ^ 1;//前位加1键sbit Add2_Key = P3 ^ 0;//后位加1键sbit OK_Key = P3 ^ 2;//确定键sbit int_Key = P3 ^ 3;//中断入口//-----------------------------定义累加器A中的各位sbit a0 = ACC ^ 0;sbit a1 = ACC ^ 1;sbit a2 = ACC ^ 2;sbit a3 = ACC ^ 3;sbit a4 = ACC ^ 4;sbit a5 = ACC ^ 5;sbit a6 = ACC ^ 6;sbit a7 = ACC ^ 7;//------------------------------------定义全局变量bit txx = 0;uchar settime;//定义标志位uchar yy,mo,dd,xq,hh,mm,bn;//定义时间映射全局变量(专用寄存器)static uchar timecount = 0;//定义静态软件计数器变量static uchar pp = 0;//定义静态小时更新用数据变量//------------------------------------函数声明(按字母顺序排列)void Beep(void);void Beep_key(void);void Beep_set(void);void clearRAM (void);uchar clock_in(void);void clock_out(uchar dd);void Delay(int num);void DelayM(uint a);void display (void);void display_s (void);void Init_1302(void);void int1 (void);void putin (uchar u);uchar read_clock(uchar ord);void read_clockS(void);void Set_time(unsigned char sel);void setput (uchar k);void Timer0(void);void Timer0_Init(void);void write_clock(uchar ord, uchar dd);uchar DL (uchar);uchar DSS (void);//-----------------------------定义显示缓冲寄存器(32个字节全局变量)uchar Ledplay [35];////-----------------------------定义字符数据表单(二维数组)uchar code no[][10]={//-----------------------------------数字字符表{0x7E,0xFF,0x81,0x81,0xFF,0x7E,0},//0{0x82,0xFF,0xFF,0x80,0}, //1{0xC6,0xE7,0xB1,0x99,0x8F,0x86,0},//2{0x42,0xC3,0x89,0x89,0xFF,0x76,0},//3{0x30,0x28,0xA6,0xFF,0xFF,0xA0,0},//4{0x4F,0xCF,0x89,0x89,0xF9,0x71,0},//5{0x7E,0xFF,0x89,0x8B,0xFB,0x70,0},//6{0x03,0x03,0xF9,0xFF,0x07,0},//7{0x76,0xFF,0x89,0x89,0xFF,0x76,0},//8{0x0E,0xDF,0xD1,0x91,0xFF,0x7E,0},//9//-----------------------------------星期字符表{0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0},//一10{0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0},//二{0x82,0x92,0x92,0x92,0x92,0x92,0x82,0x80,0},//三{0xFE,0xA2,0x9E,0x82,0x9E,0xA2,0xFE,0},//四{0x80,0x89,0xFF,0x89,0x89,0x89,0xF9,0x80,0},//五{0x88,0x68,0x38,0x0E,0x38,0x68,0x88,0},//六{0xFE,0x92,0x92,0x92,0x92,0xFE,0},//日10+6//-----------------------------------特殊字符表{0x6C,0x6C,0},//“:”17{0x18,0x18,0x18,0x18,0},//“-”18{0x06,0x06,0x78,0xFC,0x84,0x84,0x84,0x80,0},//“oC”19{0x02,0x8E,0xFC,0xFC,0x8E,0x02,0},//“Y”(在调时时表示年)20{0x80,0x7E,0x15,0x15,0x95,0xFF,0},//“月”21{0xFE,0x92,0x92,0x92,0x92,0xFE,0}//“日”22};//-----------------------------------开机画面,显示“DYDIY”uchar code dydiy[]={//显示“DYDIY”0x82,0xFE,0xFE,0x82,0xFE,0x7C,0,0x02,0x8E,0xFC,0xFC,0x8E,0x02,0,0x82,0xFE,0xFE,0x82,0xFE,0x7C,0,0x82,0xFE,0xFE,0x82,0,0x02,0x8E,0xFC,0xFC,0x8E,0x02,0,0x99};//---------------------------------------延时函数2uS/次void Delay(int num){for (;num>0;num--);}//---------------------------------------延时函数1MS/次void DelayM(unsigned int a){unsigned char i;while( --a != 0){for(i = 0; i < 125; i++); //一个; 表示空语句,CPU空转。
51单片机C语言电子时钟程序设计程序
主程序:#include"DS18B20_3.H"#define uint unsigned int#define uchar unsigned charuchar a,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp;#define yh 0x80#define er 0x80+0x40//液晶屏的与C51之间的引脚连接定义sbit rs=P2^0;sbit en=P2^2;sbit rw=P2^1; //如果硬件上rw接地,就不用写这句和后面的rw=0了sbit led=P2^6; //LCD背光开关//DS1302时钟芯片与C51之间的引脚连接定义sbit IO=P1^1;sbit SCLK=P1^0;sbit RST=P1^2;sbit ACC0=ACC^0;sbit ACC7=ACC^7;//校时按键与C51的引脚连接定义sbit key1=P1^5; //设置键sbit key2=P1^6; //加键sbit key3=P1^7; //减键sbit buzzer=P1^3; //蜂鸣器,通过三极管9012驱动,端口低电平响/**************************************************************/uchar code tab1[]={"20 - - "}; //年显示的固定字符uchar code tab2[]={" : : "}; //时间显示的固定字符//延时函数,后面经常调用void delay(uint xms) //延时函数,有参函数{uint x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}/********液晶写入指令函数与写入数据函数,以后可调用**************/write_1602com(uchar com) //****液晶写入指令函数****{rs=0; //数据/指令选择置为指令rw=0; //读写选择置为写P0=com; //送入数据delay(1);en=1; //拉高使能端,为制造有效的下降沿做准备delay(1);en=0; //en由高变低,产生下降沿,液晶执行命令}write_1602dat(uchar dat) //***液晶写入数据函数****{rs=1; //数据/指令选择置为数据rw=0; //读写选择置为写P0=dat; //送入数据delay(1);en=1; //en置高电平,为制造下降沿做准备delay(1);en=0; //en由高变低,产生下降沿,液晶执行命令}lcd_init() //***液晶初始化函数****{write_1602com(0x38); //设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据write_1602com(0x0c); //开显示不显示光标write_1602com(0x06); //整屏不移动,光标自动右移write_1602com(0x01); //清显示write_1602com(yh+1); //日历显示固定符号从第一行第1个位置之后开始显示for(a=0;a<14;a++){write_1602dat(tab1[a]); //向液晶屏写日历显示的固定符号部分//delay(3);}write_1602com(er+2); //时间显示固定符号写入位置,从第2个位置后开始显示for(a=0;a<8;a++){write_1602dat(tab2[a]); //写显示时间固定符号,两个冒号//delay(3);}}/*********************over***********************//***************DS1302有关子函数********************/void write_byte(uchar dat)//写一个字节{ACC=dat;RST=1;for(a=8;a>0;a--){IO=ACC0;SCLK=0;SCLK=1;ACC=ACC>>1;}}uchar read_byte() //读一个字节{RST=1;for(a=8;a>0;a--){ACC7=IO;SCLK=1;SCLK=0;ACC=ACC>>1;}return (ACC);}//----------------------------------------void write_1302(uchar add,uchar dat) //向1302芯片写函数,指定写入地址,数据{RST=0;SCLK=0;RST=1;write_byte(add);write_byte(dat);SCLK=1;RST=0;}uchar read_1302(uchar add) //从1302读数据函数,指定读取数据来源地址{uchar temp;RST=0;SCLK=0;RST=1;write_byte(add);temp=read_byte();SCLK=1;RST=0;return(temp);}uchar BCD_Decimal(uchar bcd) //BCD码转十进制函数,输入BCD,返回十进制{uchar Decimal;Decimal=bcd>>4;return(Decimal=Decimal*10+(bcd&=0x0F));}//--------------------------------------void ds1302_init() //1302芯片初始化子函数(2010-01-07,12:00:00,week4){RST=0;SCLK=0;write_1302(0x8e,0x00); //允许写,禁止写保护//write_1302(0x80,0x00); //向DS1302内写秒寄存器80H写入初始秒数据00//write_1302(0x82,0x00); //向DS1302内写分寄存器82H写入初始分数据00//write_1302(0x84,0x12); //向DS1302内写小时寄存器84H写入初始小时数据12//write_1302(0x8a,0x04); //向DS1302内写周寄存器8aH写入初始周数据4//write_1302(0x86,0x07); //向DS1302内写日期寄存器86H写入初始日期数据07//write_1302(0x88,0x01); //向DS1302内写月份寄存器88H写入初始月份数据01//write_1302(0x8c,0x10); //向DS1302内写年份寄存器8cH写入初始年份数据10write_1302(0x8e,0x80); //打开写保护}//温度显示子函数void write_temp(uchar add,uchar dat) //向LCD写温度数据,并指定显示位置{uchar gw,sw;gw=dat%10; //取得个位数字sw=dat/10; //取得十位数字write_1602com(er+add); //er是头文件规定的值0x80+0x40write_1602dat(0x30+sw); //数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw); //数字+30得到该数字的LCD1602显示码write_1602dat(0xdf); //显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码write_1602dat(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码}//时分秒显示子函数void write_sfm(uchar add,uchar dat) //向LCD写时分秒,有显示位置加、现示数据,两个参数{uchar gw,sw;gw=dat%10; //取得个位数字sw=dat/10; //取得十位数字write_1602com(er+add); //er是头文件规定的值0x80+0x40write_1602dat(0x30+sw); //数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw); //数字+30得到该数字的LCD1602显示码}//年月日显示子函数void write_nyr(uchar add,uchar dat) //向LCD写年月日,有显示位置加数、显示数据,两个参数{uchar gw,sw;gw=dat%10; //取得个位数字sw=dat/10; //取得十位数字write_1602com(yh+add); //设定显示位置为第一个位置+addwrite_1602dat(0x30+sw); //数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw); //数字+30得到该数字的LCD1602显示码}void write_week(uchar week) //写星期函数{write_1602com(yh+0x0c); //星期字符的显示位置switch(week){case 1:write_1602dat('M'); //星期数为1时,显示write_1602dat('O');write_1602dat('N');break;case 2:write_1602dat('T'); //星期数据为2时显示write_1602dat('U');write_1602dat('E');break;case 3:write_1602dat('W'); //星期数据为3时显示write_1602dat('E');write_1602dat('D');break;case 4:write_1602dat('T'); //星期数据为4是显示write_1602dat('H');write_1602dat('U');break;case 5:write_1602dat('F'); //星期数据为5时显示write_1602dat('R');write_1602dat('I');break;case 6:write_1602dat('S'); //星期数据为6时显示write_1602dat('T');write_1602dat('A');break;case 7:write_1602dat('S'); //星期数据为7时显示write_1602dat('U');write_1602dat('N');break;}}//****************键盘扫描有关函数**********************void keyscan(){if(key1==0) //key1为功能键(设置键){delay(9); //延时,用于消抖动if(key1==0) //延时后再次确认按键按下{buzzer=0; //蜂鸣器短响一次delay(20);buzzer=1;while(!key1);key1n++;if(key1n==9)key1n=1; //设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环switch(key1n){case 1: TR0=0; //关闭定时器//TR1=0;write_1602com(er+0x09); //设置按键按动一次,秒位置显示光标write_1602com(0x0f); //设置光标为闪烁temp=(miao)/10*16+(miao)%10; //秒数据写入DS1302write_1302(0x8e,0x00);write_1302(0x80,0x80|temp);//miaowrite_1302(0x8e,0x80);break;case 2: write_1602com(er+6); //按2次fen位置显示光标//write_1602com(0x0f);break;case 3: write_1602com(er+3); //按动3次,shi//write_1602com(0x0f);break;case 4: write_1602com(yh+0x0e); //按动4次,week//write_1602com(0x0f);break;case 5: write_1602com(yh+0x0a); //按动5次,ri//write_1602com(0x0f);break;case 6: write_1602com(yh+0x07); //按动6次,yue//write_1602com(0x0f);break;case 7: write_1602com(yh+0x04); //按动7次,nian//write_1602com(0x0f);break;case 8:write_1602com(0x0c); //按动到第8次,设置光标不闪烁TR0=1;//打开定时器temp=(miao)/10*16+(miao)%10;write_1302(0x8e,0x00);write_1302(0x80,0x00|temp);//miao数据写入DS1302write_1302(0x8e,0x80);break;}}}//------------------------------加键key2----------------------------if(key1n!=0) //当key1按下以下。
基于c语言单片机电子时钟课程设计
课程设计报告课程名称:单片机程序设计报告题目:电子时钟学生姓名:所在学院:信息科学与工程学院专业班级:学生学号:指导教师:2013年12月25日课程设计任务书摘要单片计算机即单片微型计算机。
由RAM、ROM、CPU构成。
定时,计数和多种接口于一体的微控制器。
它体积小,成本低,功能强,广泛应用于智能产业和工业自动化上。
而51系列单片机是各单片机中最为典型和最有代表性的一种。
这次课程设计通过对它的学习,应用,从而达到学习、设计、开发软、硬的能力。
本设计主要设计了一个基于AT89C51单片机的电子时钟。
并在数码管上显示相应的时间。
并通过一个控制键用来实现时间的调节和是否进入省电模式的转换。
应用Proteus的ISIS软件实现了单片机电子时钟系统的设计与仿真。
该方法仿真效果真实、准确,节省了硬件资源。
关键词:单片机;子时钟;键控制目录一、概述 (5)1.1电子时钟简介 (5)1.2电子时钟的基本特点 (5)1.3电子时钟的原理 (5)二、方案设计选择 (5)2.1计时方案 (5)2.2显示方案 (5)三、硬件设计 (6)3.1单片机型号选择 (6)3.2数码管显示工作原理 (6)3.3键盘电路设计 (7)3.4电路原理图 (7)四、软件设计 (7)五、结论与心得 (15)六、参考文献 (16)一、概述1.1 电子时钟简介1957年,Ventura发明了世界上第一个电子表,从而奠定了电子时钟的基础,电子时钟开始迅速发展起来。
现代的电子时钟是基于单片机的一种计时工具,采用延时程序产生一定的时间中断用于一秒的定义,通过计数方式进行满六十秒分钟进一,满六十分小时进一,满二十四小时小时清零。
从而达到计时的功能,是人民日常生活补课缺少的工具。
1.2 电子时钟的基本特点现在高精度的计时工具大多数都使用了石英晶体振荡器,由于电子钟、石英钟、石英表都采用了石英技术,因此走时精度高,稳定性好,使用方便,不需要经常调试,数字式电子钟用集成电路计时时,译码代替机械式传动,用LED 显示器代替指针显示进而显示时间,减小了计时误差,这种表具有时、分、秒显示时间的功能,还可以进行时和分的校对,片选的灵活性好。
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);。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于 5 1 单片机的电子钟 C 语言程序
#include<reg51.h>
#include<absacc.h>
#defineucharunsignedchar
#defineuintunsignedint
/* 七段共阴管显示定义*/
ucharcodedispcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, 0xBF,0x86,0xCB,0xCF,0xEF,0xED,0xFD,0x87,0xFF,0xDF};
/* 定义并初始化变量*/
ucharseconde=0;
ucharminite=0;
ucharhour=12;
ucharmstcnt=0;
sbitP1_0=PM0;//seco nd 调整定义
sbitP1_ 仁P1A1;//mi nite 调整定义
sbitP1_2=P1A2;//hour 调整定义
/* 函数声明*/
voiddelay(uintk);// 延时子程序
voiddelay1(ucharh);
voidtime_pro();// 时间处理子程序
voiddisplay();// 显示子程序
voidkeyscan();// 键盘扫描子程序
/*****************************/
/* 延时子程序*/ voiddelay1(ucharh)
{
ucharj;
while((h--)!=0)
{ for(j=0;j<125;j++) {;}
}
}
voiddelay(uintk)
{
uinta,b,c;
for(c=k;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--);
} /************************* /* 时间处理子程序*/
*/
voidtime_pro(void)
{
if(seconde==60)// 秒钟设为60 进制
{seconde=0;
minite++;
if(minite==60)// 分钟设为60 进制
{minite=0;
hour++;
if(hour==24)// 时钟设为24 进制
{hour=0;}
}
}
}
/*****************************/
/* 显示子程序*/ voiddisplay(void)
{
P2=0xfe;
P0=dispcode[hour/10];// 显示小时的十位delay1(4);
P2=0xfd;
P0=(dispcode[(hour%10)])|0X80;// 显示小时的个位delay1(4); P2=0xfb;
P0=dispcode[minite/10];// 显示分的十位delay1(4);
P2=0xf7;
P0=(dispcode[minite%10])|0X80;// 显示分的个位delay1(4); P2=0xef;
P0=dispcode[seconde/10];// 显示秒的十位delay1(4);
P2=0xdf;
P0=dispcode[seconde%10];// 显示秒的个位delay1(4);
}
/*******************************/
/* 键盘扫描子程序*/
/*******************************/ voidkeyscan(void)
{
if(P1_0==0)// 按键 1 秒的调整
{
delay(2);
if(P1_0==0)
//delay(300);
{
seconde++;
if(seconde==60)
{seconde=0;}
}
}
if(P1_1==0)// 按键 2 分的调整
{
delay(2);
if(P1_1==0)
// delay(300);
{
minite++;
if(minite==60)
{minite=0;}
}
}
if(P1_2==0)// 按键 3 小时的调整
{
delay(2);
if(P1_2==0)
//delay(300);
{
hour++;
if(hour==24)
{hour=0;}
}
}
}
voidtimerO(void)interruptlusingO〃定时器0方式1, 50ms中断一次
{
TH0=0x3c;
TMOD=0x11;
mstcnt++;
if(mstcnt==20)
{
seconde++;
mstcnt=0;// 注意点。
对计数单元的清零十分的重要,本次调试中就是
}// 因为忽略了这一点,给我早成了很大的被动。
}
/**************************/
/* 主函数*/
/**************************/ voidmain(void) {P1=0xff;// 初始化p1 口,全设为 1 TMOD=0x11;//time0 为定时器,方式 1 TH0=0x3c;// 预置计数初值
TL0=0xb0;
EA=1;
ET0=1;
TR0=1;
while(1)
{
keyscan();// 按键扫描time_pro();// 时间处理display();// 显示时间
}
}。