大学方案单片机智能数字闹钟程序代码
- 格式:doc
- 大小:62.50 KB
- 文档页数:30
单片机电子闹钟程序(亲自编写-可用)————————————————————————————————作者:————————————————————————————————日期:学校电子钟,有闹钟功能,按键可调时间,可调打铃时间,打铃时间长短显示,每个模块有功能注释。
其中正常时间显示和闹钟时间显示可用一个开关来调整。
芯片选择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();}}电路图:分四部分显示:如果在学习这个程序过程中有什么问题,可以发邮件到询问。
数字钟、万年历制作(基于单片机)电路原理图:程序://********************20131206****数字钟程序#pragma SMALL#include <reg51.h>#include <absacc.h>#include <intrins.h>//********************************************************* *********编译预处理void display(unsigned char *p); //显示函数,P为显示数据首地址unsigned char keytest(); //按键检测函数unsigned char search(); //按键识别函数void alarm(); //闹钟判断启动函数void ftion0(); //始终修改函数void ftion1(); //闹钟修改函数void ftion3(); //日期修改函数void cum(); //加1修改函数void minus(); //减1修改函数void jinzhi(); //进制修改函数void riqi(); //日期void stopwatch(); //秒表函数//********************************************************* *******函数声明sbit P2_7=P2^7;//********************************************************* *******端口定义unsigned char clockbuf[3]={0,0,0};unsigned char bellbuf[3]={0,0,0};unsigned char date[3]={1,1,1}; //日期存放数组unsigned char stop[3]={0,0,0};unsigned char msec1,msec2;unsigned char timdata,rtimdata,dtimdata;unsigned char count;unsigned char *dis_p;unsigned char or; //12进制控制标志unsigned char ri; //日期显示控制标志位unsigned char mb; //秒表控制标志位bit arm,rtim,rhour,rmin,hour,min,sec,day,mon,year; //定义位变量//********************************************************* *****全局变量定义void main(){unsigned char a;or=0; //12进制修改标志清零ri=0;mb=0;P2_7=0;arm=0;msec1=0;msec2=0;timdata=0;rtimdata=0;count=0;TMOD=0x12;TL0=0x06;TH0=0x06;TH1=(65536-10000)/256;TL1=(65536-10000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=0;dis_p=clockbuf;while(1){a=keytest();if(a==0x78) //判断是否有键按下{display(dis_p);if(arm==1) alarm();}else{display(dis_p);a=keytest();if(a!=0x78){a=search();switch(a){case 0x00:ftion0();break;case 0x01:ftion1();break;case 0x02:cum();break;case 0x06:jinzhi();break;case 0x03:riqi();break;case 0x04:ftion3();break;case 0x05:minus();break;case 0x07:stopwatch();break;case 0x09:TR1=1;break;case 0x0a:TR1=0;break;case 0x0b:stop[0]=0;stop[1]=0;stop[2]=0;break;default:break;}}}}}//********************************************主函数【完】void display(unsigned char *p){unsigned char buffer[]={0,0,0,0,0,0};unsigned char k,i,j,m,temp;unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};buffer[0]=p[0]/10;buffer[1]=p[0]%10;buffer[2]=p[1]/10;buffer[3]=p[1]%10;buffer[4]=p[2]/10;buffer[5]=p[2]%10;if((sec==0)&&(min==0)&&(hour==0)&&(rmin==0)&&(rhour==0)&&( day==0)&&(mon==0)&&(year==0)) //没有修改标志,正常显示{for(k=0;k<3;k++){temp=0x01;for(i=0;i<6;i++){P0=0x00; //段选端口j=buffer[i];P0=led[j];P1=~temp; //位选端口temp<<=1;for(m=0;m<200;m++);}}}else //若有修改标志,则按以下标志分别显示{if(sec==1||day==1){P1=0x1f;i=buffer[5];P0=led[i];for(m=0;m<200;m++);P1=0x2f;j=buffer[4];P0=led[j];for(m=0;m<200;m++);}if(min==1||rmin==1||mon==1){P1=0x3b;i=buffer[2];P0=led[i];for(m=0;m<200;m++);P1=0x37;j=buffer[3];P0=led[j];for(m=0;m<200;m++);}if(hour==1||rhour==1||year==1) {P1=0x3e;i=buffer[0];P0=led[i];for(m=0;m<200;m++);P1=0x3d;j=buffer[1];P0=led[j];for(m=0;m<200;m++);}}}//**********************************LED显示函数【完】unsigned char keytest(){unsigned char c;P2=0x78; //检测是否有键按下c=P2;c=c&0x78;return(c);}//******************************************键盘检测函数【完】unsigned char search(){unsigned char a,b,c,d,e;c=0x3f;a=0; //行号while(1){P2=c;d=P2;d=d&0x07;if(d==0x03){b=0;break;} //列号else if(d==0x05){b=1;break;}else if(d==0x06){b=2;break;}a++;c>>=1;if(a==5){a=0;c=0x3f;}}e=a*3+b;do{display(dis_p);}while((d=keytest())!=0x78);return(e);}//***********************************************查键值函数【完】void alarm(){if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])){P2_7=1;rtim=1;if(count==10){count=0;P2_7=0;arm=0;rtim=0;}}}//****************************************闹钟判断启动函数【完】void ftion0(){TR0=0;rhour=0;rmin=0;dis_p=clockbuf;rtimdata=0;timdata++;switch(timdata){case 0x01:sec=1;break;case 0x02:sec=0;min=1;break;case 0x03:min=0;hour=1;break;case 0x04:timdata=0;hour=0;TR0=1;break;default:break;}}//*********************************************时钟设置函数【完】void ftion1(){if(TR0==0) TR0=1;sec=0;min=0;hour=0;dis_p=bellbuf;timdata=0;rtimdata++;switch(rtimdata){case 0x01:rmin=1;break;case 0x02:rmin=0;rhour=1;break;case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;default:break;}}//*********************************************闹钟设置函数【完】void ftion3(){if(TR0==0) TR0=1;day=0;mon=0;year=0;dis_p=date;timdata=0;rtimdata=0;dtimdata++;switch(dtimdata){case 0x01:day=1;break;case 0x02:day=0;mon=1;break;case 0x03:mon=0;year=1;break;case 0x04:dtimdata=0;year=0;dis_p=clockbuf;break;default:break;}}//*************************************************日期修改函数【完】void minus(){if(sec==1){if(0==clockbuf[2]) clockbuf[2]=59;else clockbuf[2]--;}else if(min==1){if(0==clockbuf[1]) clockbuf[1]=59;else clockbuf[1]--;}else if(hour==1){if(or==0) //判断进制{if(0==clockbuf[0]) clockbuf[0]=23;else clockbuf[0]--;}if(or==1){if(1==clockbuf[0]) clockbuf[0]=12;else clockbuf[0]--;}}else if(rmin==1){if(bellbuf[1]==0) bellbuf[1]=59;else bellbuf[1]--;}else if(rhour==1){if(or==0){if(bellbuf[0]==0) bellbuf[0]=23;else bellbuf[0]--;}if(or==1){if(bellbuf[0]==1) bellbuf[0]=12;else bellbuf[0]--;}}else if(day==1){if(date[2]==1) date[2]=31;else date[2]--;}else if(mon==1){if(date[1]==1) date[1]=12;else date[1]--;}else if(year==1){if(date[0]==1) date[0]=99;else date[0]--;}}//*************************************减1修改功能函数【完】void cum(){if(sec==1){if(59==clockbuf[2]) clockbuf[2]=0;else clockbuf[2]++;}else if(min==1){if(59==clockbuf[1]) clockbuf[1]=0;else clockbuf[1]++;}else if(hour==1){if(or==0) //判断进制{if(23==clockbuf[0]) clockbuf[0]=0;else clockbuf[0]++;}if(or==1){if(12==clockbuf[0]) clockbuf[0]=1;else clockbuf[0]++;}}else if(rmin==1){if(bellbuf[1]==59) bellbuf[1]=0;else bellbuf[1]++;}else if(rhour==1){if(or==0){if(bellbuf[0]==23) bellbuf[0]=0;else bellbuf[0]++;}if(or==1){if(bellbuf[0]==12) bellbuf[0]=1;else bellbuf[0]++;}}else if(day==1){if(date[2]==31) date[2]=1;else date[2]++;}else if(mon==1){if(date[1]==12) date[1]=1;else date[1]++;}else if(year==1){if(date[0]==99) date[0]=0;else date[0]++;}}//*************************************加1修改功能函数【完】void jinzhi(){if(or==0) or=1;else or=0;}//***********************************进制修改控制函数【完】void riqi(){if(ri==0){dis_p=date;}if(ri==1){dis_p=clockbuf;}ri++;if(ri==2) ri=0;}//********************************日期控显示函数【完】void stopwatch(){if(mb==0){dis_p=stop;mb=1;}else{mb=0;dis_p=clockbuf;}}//************秒表**********秒表**********秒表函数【完】void clock() interrupt 1{EA=0;if(msec1!=0x14) msec1++; //6MHz晶振定时10mselse{msec1=0;if(msec2!=100) msec2++; //定时1selse{if(rtim==1) count++; //闹钟启动标志计时10smsec2=0;if(clockbuf[2]!=59) clockbuf[2]++;else{clockbuf[2]=0;if(clockbuf[1]!=59) clockbuf[1]++;else{clockbuf[1]=0;if(or==0){if(clockbuf[0]!=23) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}if(or==1){if(clockbuf[0]!=12) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}}}}}EA=1;}//*******************************定时器0中断函数【完】void miaobiao() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(stop[2]!=99) stop[2]++;else{stop[2]=0;if(stop[1]!=59) stop[1]++;else{stop[1]=0;if(stop[0]!=59) stop[0]++;else stop[0]=0;}}}//***********************************定时器1中断函数【完】。
#include <pic.h>__CONFIG (0x20F1);__CONFIG (0x3FFF); //调试用#define LCD_E RD6 //LCD E 读写使能控制#define LCD_RW RD5 //LCD 读(1)/写(0)控制线#define LCD_RS RD4 //LCD 寄存器选择数据(1)指令(0)//RD4-RD7分别接DB4-DB7,RD7为忙标志#define COM 0 //在LCD_WRITE()中的第2参数为0表示写命令#define DAT 1 //在LCD_WRITE()中的第2参数为1表示写数据#define mod RB3//模式选择(时间、闹钟、温度、秒表)#define set RB0//选择按键#define add RB1//加按键#define miu RB2//减按键#define RTR 0b00000000 //TC74的读温度命令#define TC74_ADD 0b1001101 //TC74的7位地址#define LINE1 0b10000000#define LINE2 0b11000000signed char hourt,mint,sect;//闹钟设置位int f;//闹钟显示清零判断char flag=0;//按键标志位char WW,QW,BW,SW,GW,M;char table[]="Mon Tue Wed Thu Fri Sat Sun ";//星期signed char year,month,day,week,hour,min,sec,a,T;bank1 char DD[16]; //一行LCD显示数据暂存char A[7];//DS1307读数//====LCD程序void CSH(void); //初始化void LCD_CSH(void); //LCD初始化void LCD_BUSY(void); //检测LCD是否忙char LCD_READ(void); //读LCD,忙检测用void LCD_WRITE(char,char); //LCD写1字节,命令或数据void LCD_WRITE_4(char,char); //LCD写半字节void DISP_C(char); //在指定行中显示字符,字符在数组DD中void DISP_MENU(const char *); //由常数数组显示整屏字符void DELAY_US(char);void DELAY(unsigned int);void delaynms(unsigned int);//===DS1307void IIC_SEND(char);void IIC_CSH(void);void READ_DS1307(char addr,char n);void write_DS1307(char addr,char data);void DS1307_CSH(void);//DS1307初始化void MENU_DS1307(void);//==温度void DISP_T(signed char R1); //温度在R1 signed char READ_T(void);void clock();//闹钟void set_time(void);//按键void bcd_dec(char adr,char R);char dec_bcd(char dec);void BCD(unsigned int R1);void guangbiao(void);//光标//========主程序void main(){CSH();READ_DS1307(0,7);//读DS1307if(A[0]&0x80)DS1307_CSH();//判断是否初始化while(1){clock();set_time();//按键检测delaynms(50);if(flag==0){ READ_DS1307(0,7);//读DS1307MENU_DS1307();//显示DS1307T=READ_T();//读温度DISP_T(T);//显示温度}}}//========初始化端口void CSH(void){TRISD=0b00000000; //控制LCD1604,全为输出RD7=1; //背光TRISB=0x0FF;RBPU=0;WPUB=0x0FF;ANSELH=0;PORTB=0x00;//===PWM设置TRISC1=0; //RC1为输出RC1=0;PR2=124; //周期为1msCCPR2L=0x32;CCP2CON=0b00000000;//关闭PWMT2CON=0b00000110; //TMR2预分频1:16,开始工IIC_CSH();LCD_CSH();}//LCD模块初始化void LCD_CSH(void){ DELAY(20); //延时20msLCD_WRITE_4(0b0011,COM); //发送控制序列DELAY_US(10); //延时100usLCD_WRITE_4(0b0011,COM); //发送控制序列DELAY_US(10); //延时100usLCD_WRITE_4(0b0011,COM); //发送控制序列DELAY_US(10); //延时100usLCD_WRITE_4(0b0010,COM); //4位数据格式LCD_BUSY(); //LCD忙检测LCD_WRITE(0b00101000,COM); //4位数据格式,2行,5×7点阵LCD_WRITE(0b00001100,COM); //D(d2)=1:打开显示,C(d1)=1:光标打开,B(d0)=1:光标不闪烁LCD_WRITE(0b00000001,COM); //清除显示DELAY(2); //延时2msLCD_WRITE(0b00000110,COM); //输入模式,I/D(d1)=1:地址加1,S(d0)=1:显示移位关闭}//========读LCD状态char LCD_READ(void){ unsigned char R1;TRISD|=0X0F; //LCD数据线为输入LCD_RS=0; //寄存器选择LCD_RW=1;NOP(); //读为1LCD_E=1;NOP(); //使能R1=0; //短延时R1=(PORTD<<4 )& 0xF0; //读数据的高4位给R1高四位LCD_E=0;NOP(); //读数据结束LCD_E=1;NOP(); //使能R1 |= (PORTD & 0x0F); //读PORTD的低4位,R1的高4位不变!LCD_E=0;NOP(); //读数据结束LCD_RW=0;return (R1);}//写一字节数R1,FLAG为写命令或数据选择,0为写命令,1为写数据//写之前先检查是否忙,写完后延时100us,分二次写4位数据/命令void LCD_WRITE(char R1,char FLAG){ char R2;TRISD&=0XF0;LCD_BUSY();R2=R1 & 0xF0; //低4位清0R2=R2>>4; //取高4位LCD_WRITE_4(R2,FLAG); //先写高4位R2=(R1 & 0x0F); //高4位清0,取低4位LCD_WRITE_4(R2,FLAG); //再送低4位DELAY_US(10); //延时100us}//写R1的低4位,FLAG为寄存器选择,1为命令,0为数据void LCD_WRITE_4(char R1,char FLAG){ TRISD&=0XF0;LCD_RW=0;NOP(); //写模式LCD_RS=FLAG;NOP(); //寄存器选择PORTD &= 0xF0;NOP(); //RD低4位先清0LCD_E=1;NOP(); //使能R1=(R1&0x0F); //R1低4位送至低4位PORTD |=R1;NOP(); //送4位LCD_E=0;NOP(); //数据送入有效,下降沿送入LCD_RS=0;NOP();PORTD &= 0xF0; //RD低4位清0}//========检测LCD是否忙void LCD_BUSY(void){ unsigned char R1;while(1){ R1=LCD_READ(); //读寄存器if ((R1 & 0x80)==0x00) //最高位为忙标志位break;};}//======延时(n)msvoid DELAY(unsigned int n){unsigned int j;char k;for (j=0;j<n;j++)for (k=246;k>0;k--) NOP();}//======延时(n)msvoid delaynms(unsigned int n){unsigned int j;char k;for (j=0;j<n;j++)for (k=246;k>0;k--) NOP();}//======延时(n×10)usvoid DELAY_US(char n){ char j;for (j=0;j<n;j++){NOP();NOP();}}//=======DS1307有关子程序//===DS1307初始化void DS1307_CSH(){write_DS1307(0x00,0X00);//秒钟设置write_DS1307(0x01,0x01);//分钟设置write_DS1307(0x02,0x01);//小时设置write_DS1307(0x03,0X01);//星期天设置write_DS1307(0x04,0x01);//日月设置write_DS1307(0x05,0x05);//月设置write_DS1307(0x06,0x12);//年设置write_DS1307(0x07,0x70);//7脚方波允许,输出1HZ}//==IIC初始化void IIC_CSH(){ TRISC =0b00011000; //SDA,SCL设置为输入SSPCON=0b00101000; //同步串口使能(SSPEN),主控方式SMP=0; //使能高速模式(400 kHz) 的压摆率控制SSPADD=4; //主控模式为波特率值,每位时间T=(SSPADD+1)/Tcy=5us }//发送数R并等待发送完成,收到从机的应答信号void IIC_SEND(char R){ SSPBUF=R; //发送while (RW==1); //在主动模式下,判断发送是否完成while (SSPIF==0); //等待发送完成while (ACKSTA T==1); //等待从机发送应答信号NOP();}//====读写DS1307程序void write_DS1307(char addr,char data){SEN=1; //发送起始位while(SEN==1); //检测起始位完成IIC_SEND(0b11010000); //送DS1307的七位地址和写功能IIC_SEND(addr); //发送要写入的地址IIC_SEND(data); //发送要写入的数PEN=1; //发送停止位while (PEN==1); //检查停止位结束}//===读DS1307void READ_DS1307(char addr,char n){char i;SEN=1; //产生起始位while (SEN==1); //检测起始位完成IIC_SEND(0b11010000); //送DS1307的7位地址IIC_SEND(addr); //此值为DS1307要读的地址PEN=1; //发送停止位while (PEN==1);//检查停止位结束NOP();RSEN=1; //发送重新启始位while(RSEN==1); //检测重新起始位完成IIC_SEND(0b11010001); //读数据for (i=0;i<n;i++) //读字节个数{ RCEN=1;while (RCEN==1);A[i]=SSPBUF; //读1字节if (i<n-1){ ACKDT=0;ACKEN=1;while (ACKEN==1);}else{ ACKDT=1;ACKEN=1;while (ACKEN==1);} //最后一字节不应答}PEN=1;while (PEN==1);}//=====显示DS1307void MENU_DS1307(void){ LCD_WRITE(0b00001100,COM); //D(d2)=1:打开显示,C(d1)=1:光标打开,B(d0)=1:光标不闪烁char i;LCD_WRITE(LINE1,COM); //DDRAM地址,第1行的第1个字符LCD_WRITE(' ',DAT);LCD_WRITE('2',DAT);LCD_WRITE('0',DAT);LCD_WRITE((A[6]>>4)+0x30,DA T);LCD_WRITE((A[6]&0x0F)+0x30,DA T);LCD_WRITE('-',DAT);LCD_WRITE((A[5]>>4)+'0',DA T);LCD_WRITE((A[5]&0x0F)+'0',DAT);LCD_WRITE('-',DAT);LCD_WRITE((A[4]>>4)+'0',DA T);LCD_WRITE((A[4]&0x0F)+'0',DAT);LCD_WRITE(' ',DAT);i=A[3]&0x07;LCD_WRITE(table[(i-1)*4],DA T);LCD_WRITE(table[(i-1)*4+1],DAT);LCD_WRITE(table[(i-1)*4+2],DAT);LCD_WRITE(table[(i-1)*4+3],DAT);//LCD_WRITE(' ',DAT);LCD_WRITE(LINE2,COM); //DDRAM地址,第2行的第1个字符LCD_WRITE(' ',DAT);LCD_WRITE((A[2]>>4)+'0',DA T);LCD_WRITE((A[2]&0x0F)+'0',DAT);LCD_WRITE(0x3A,DA T);LCD_WRITE((A[1]>>4)+'0',DA T);LCD_WRITE((A[1]&0x0F)+'0',DAT);LCD_WRITE(0x3A,DA T);LCD_WRITE((A[0]>>4)+'0',DA T);LCD_WRITE((A[0]&0x0F)+'0',DAT);LCD_WRITE(' ',DAT);}char dec_bcd(char dec){char bcd;bcd= 0;while(dec >= 10){dec -= 10;bcd++;}bcd <<= 4;bcd |= dec;return (bcd);}void bcd_dec(char adr,char R) {SW=A[adr]>>4;GW=A[adr]&0x0F;while(SW>0){R=R+10;SW--;}R+=GW;}//====按键程序void set_time(){if(mod==0){delaynms(30);if(mod==0){while(!mod);//等待M++;if(M==3){ M=0;flag=0;f=0;a=0;}}}if(M==1)//设置时间{if(set==0){delaynms(30);if(set==0){while(!set);a++;if(a==8)a=0;}}guangbiao();//光标定位,闪烁if(a==1){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(0,sec);sec++;if(sec==60)sec=0;write_DS1307(0,dec_bcd(sec));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(0,sec);sec--;if(sec==-1)sec=59;write_DS1307(0,dec_bcd(sec));}}}if(a==2){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(1,min);min++;if(min==60)min=0;write_DS1307(1,dec_bcd(min));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(1,min);min--;if(min==-1)min=59;write_DS1307(1,dec_bcd(min));}}}if(a==3){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(2,hour);hour++;if(hour==24)hour=0;write_DS1307(2,dec_bcd(hour));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(2,hour);hour--;if(hour==-1)hour=23;write_DS1307(2,dec_bcd(hour));}}}if(a==4){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(3,week);week++;if(week==8)week=1;write_DS1307(3,dec_bcd(week));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(3,week);week--;if(week==0)week=7;write_DS1307(3,dec_bcd(week));}}}if(a==5){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(4,day);day++;if(day==32)day=1;write_DS1307(4,dec_bcd(day));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(4,day);day--;if(day==0)day=31;write_DS1307(4,dec_bcd(day));}}}if(a==6){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(5,month);month++;if(month==13)month=1;write_DS1307(5,dec_bcd(month));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);bcd_dec(5,month);month--;if(month==0)month=12;write_DS1307(5,dec_bcd(month));}}}if(a==7){if(add==0){delaynms(30);if(add==0){while(!add);bcd_dec(6,year);year++;if(year==99)year=0;write_DS1307(6,dec_bcd(year));}}if(miu==0){delaynms(30);if(miu==0){while(!miu);year--;if(year==-1)year=99;bcd_dec(6,year);write_DS1307(6,dec_bcd(year));}}}READ_DS1307(0,7);//读DS1307}//====闹钟按键设置else if(M==2){f++;flag=1;if(f==1){a=0;LCD_WRITE(LINE2+1,COM);//显示上次闹铃时间BCD(hourt);LCD_WRITE(SW+'0',DAT);LCD_WRITE(GW+'0',DAT);LCD_WRITE(LINE2+4,COM);BCD(mint);LCD_WRITE(SW+'0',DAT);LCD_WRITE(GW+'0',DAT);LCD_WRITE(LINE2+7,COM);BCD(sect);LCD_WRITE(SW+'0',DAT);LCD_WRITE(GW+'0',DAT);}if(set==0) //设置时间{delaynms(30);if(set==0){while(!set);a++;if(a==4)a=0;}}guangbiao();//光标定位,闪烁if(a==1){if(add==0){delaynms(30);if(add==0){while(!add);sect++;if(sect==60)sect=0;BCD(sect);LCD_WRITE(LINE2+7,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}if(miu==0){delaynms(30);if(miu==0){while(!miu);sect--;if(sect==-1)sect=59;BCD(sect);LCD_WRITE(LINE2+7,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}}if(a==2){if(add==0){delaynms(30);if(add==0){while(!add);mint++;if(mint==60)mint=0;BCD(mint);LCD_WRITE(LINE2+4,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}if(miu==0){delaynms(30);if(miu==0){while(!miu);mint--;if(mint==-1)mint=59;BCD(mint);LCD_WRITE(LINE2+4,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}}if(a==3){if(add==0){delaynms(30);if(add==0){while(!add);hourt++;if(hourt==24)hour=0;BCD(hourt);LCD_WRITE(LINE2+1,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}if(miu==0){delaynms(30);if(miu==0){while(!miu);hourt--;if(hourt==-1)hourt=23;BCD(hourt);LCD_WRITE(LINE2+1,COM);LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位}}}}}//====光标定位void guangbiao(void){switch(a){case(1):LCD_WRITE(0b11001000,COM);LCD_WRITE(0b00001111,COM);break;//定位秒,光标打开,B(d0)=1:光标闪烁case(2):LCD_WRITE(0b11000101,COM);LCD_WRITE(0b00001111,COM);break;//定位分,光标打开,B(d0)=1:光标闪烁case(3):LCD_WRITE(0b11000010,COM);LCD_WRITE(0b00001111,COM);break;//定位时,光标打开,B(d0)=1:光标闪烁case(4):LCD_WRITE(0b10001110,COM);LCD_WRITE(0b00001111,COM);break;//定位星期,光标打开,B(d0)=1:光标闪烁case(5):LCD_WRITE(0b10001010,COM);LCD_WRITE(0b00001111,COM);break;//定位日,光标打开,B(d0)=1:光标闪烁case(6):LCD_WRITE(0b10000111,COM);LCD_WRITE(0b00001111,COM);break;//定位月,光标打开,B(d0)=1:光标闪烁case(7):LCD_WRITE(0b10000100,COM);LCD_WRITE(0b00001111,COM);break;//定位秒,光标打开,B(d0)=1:光标闪烁case(8):LCD_WRITE(0b10000010,COM);LCD_WRITE(0b00001111,COM);break;//定位秒,光标打开,B(d0)=1:光标闪烁}}//=====读TC74的温度值signed char READ_T(void){ signed char R1;SEN=1; //开始条件while (SEN==1); //检测开始条件是否完成?IIC_SEND(TC74_ADD<<1); //送TC74地址(写)IIC_SEND(RTR); //写RTR命令(写)RSEN=1; //重新开始条件while (RSEN==1); //等待重新开始条件结束IIC_SEND((TC74_ADD<<1)+1);//发送TC74地址(读)RCEN=1; //接收使能while (RCEN==1); //等待接收完成R1=SSPBUF; //接收数据存入R1PEN=1; //停止位while(PEN==0);return(R1);}//从R1双字节数转换为十进制数万位-个位:WW,QW,BW,SW,GW void BCD(unsigned int R1){ WW=0;QW=0;BW=0;SW=0;GW=0;while(R1>=10000){R1-=10000;WW++;}while(R1>=1000){R1-=1000;QW++;}while(R1>=100){R1-=100;BW++;}while(R1>=10){R1-=10; SW++;}GW=R1;}//===温度显示void DISP_T(signed char R1) //温度在R1{ char R2;if (R1>=0)BCD(R1);else{ R2=~(R1)+1;BCD(R2);}if (R1<0){LCD_WRITE(LINE2+10,COM); //DDRAM地址,第1行的第5个字符LCD_WRITE('-',DAT);}if (R1>=0) //只在温度为正时才显示百位LCD_WRITE(BW+0x30,DAT); //显示百位,数字加上0x30即为相应的ASCII码,下同LCD_WRITE(SW+0x30,DAT); //显示十位LCD_WRITE(GW+0x30,DAT); //显示个位LCD_WRITE(0xDF,DA T); //°LCD_WRITE('C',DAT);LCD_WRITE(' ',DAT);}//====闹钟void clock(){ if(!mod||!set||!add||!miu){delaynms(30);if(!mod||!set||!add||!miu);CCP2CON=0b00000000; //关PWM模式}BCD(sect);if(SW==(A[0]>>4)&&GW==(A[0]&0x0F)){BCD(mint);if(SW==(A[1]>>4)&&GW==(A[1]&0x0F)){BCD(hourt);if(SW==(A[2]>>4)&&GW==(A[2]&0x0F))CCP2CON=0b00001100; //开PWM模式}}}。
摘要本设计是定时闹钟的设计,由单片机AT89C51芯片和LED数码管为核心,辅以必要的电路,构成的一个单片机电子定时闹钟。
电子钟设计可采用数字电路实现,也可以采用单片机来完成。
数字电子钟是用数字集成电路构成的,用数码管显示“时”,“分”,“秒”的现代计时装置。
若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。
若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,那么就降低了硬件电路的复杂性,而且其成本也有所降低,所以在该设计中采用单片机利用AT89C51,它是低功耗、高性能的CMOS型8位单片机。
片内带有4KB的Flash存储器,且允许在系统内改写或用编程器编程。
另外, AT89C51的指令系统和引脚与8051完全兼容,片内有128B 的RAM、32条I/O口线、2个16位定时计数器、5个中断源、一个全双工串行口等。
AT89C51单片机结合七段显示器设计的简易定时闹铃时钟,可以设置现在的时间及显示闹铃设置时间,若时间到则发出一阵声响,进—步可以扩充控制电器的启停。
设计内容包括了秒信号发生器、时间显示电路、按键电路、供电电源以及闹铃指示电路等几部分的设计。
采用四个开关来控制定时闹钟的工作状态,分别为:K1、设置时间和闹钟的小时;K2、设置小时以及设置闹钟的开关;K3、设置分钟和闹钟的分钟;K4、设置完成退出。
课设准备中我根据具体的要求,查找资料,然后按要求根据已学过的时钟程序编写定时闹钟的程序,依据程序利用proteus软件进行了仿真试验,对出现的问题进行分析和反复修改源程序,最终得到正确并符合要求的结果。
设计完成的定时闹钟达到课程设计的要求,在到达定时的时间便立即发出蜂鸣声音,持续一分钟。
显示采用的六位数码管电路,如果亮度感觉不够,可以通过提升电阻来调节,控制程序中延迟时间的长短,可以获得不同的效果。
单片机课程设计报告基于单片机的数字时钟姓名:班级:学号:一、前言利用实验板上的4个LED数码管,设计带有闹铃、秒表功能的数字时钟。
功能要求:a)计时并显示(LED)。
由于实验板上只有4位数码管,可设计成显示“时分”和显示“分秒”并可切换。
b)时间调整功能。
利用4个独立按钮,实现时钟调整功能。
这4个按钮的功能为工作模式切换按钮(MODE),数字加(INC),数字减(DEC)和数字移位(SHITF)。
c)定闹功能。
利用4个独立按钮设定闹钟时间,时间到以蜂鸣器响、继电器动作作为闹铃。
d)秒表功能。
最小时间单位0.01秒。
二、硬件原理分析1.电源部分电源部份采用两种输入接口(如上图)。
a)外电源供电,采用2.1电源座,可接入电源DC5V,经单向保护D1接入开关S1。
b)USB供电,USB供电口输入电源也经D1单向保护,送到开关S1。
注:两路电源输入是并连的,因此只选择一路就可以了,以免出问题。
S1为板子工作电源开关,按下后接通电源,提供VCC给板子各功能电路。
电路采用两个滤波电容,给板子一个更加稳定的工作电源。
LED为电源的指示灯,通电后LED灯亮。
2.蜂鸣器蜂鸣器分为有源和无源两种,有源即两引脚有一个直流电源就可以长鸣,无源则需要一个1K左右的脉冲才可以蜂鸣,因此对于按键的提示音及报警蜂鸣使用有源来得方便。
有源也可以当无源使用,而无源则不能当有源使用,当然用有源蜂鸣器作音乐发声会失真厉害。
如上图:单片机P15输出高低电平经R21连接三极管B极,控制三极管的导通与截止,从而控制蜂鸣器的工作。
低电平时三极管导通,蜂鸣器得电蜂鸣,高电平时三极管截止,蜂鸣器失电关闭蜂鸣。
电路使用一个四位共阳型数码管,四个公共阳级由三极管放大电流来驱动,三极管由P10-P13控制开与关。
数码管的阴级由P0口经过电阻限流连接。
例如,要十位的数码管工作,P12输出0,使三极管Q12导通,8脚得电,当P0口相应位有输出0时,点亮相应的LED灯组合各种字符数字。
实时电子闹钟功能:可以在液晶上显示时间星期日期,并按秒实时更新,具有闹钟设定及到时闹钟报警提示功能,闹钟响铃时按任意键可以取消响铃,拓展了四个按键,用于功能选择,数值增大或减小及闹钟查看,每次按键均会有短“滴”声,断电时间不停,再次上电仍将准确显示在液晶上照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟照片描述:用开发板及自己焊接的部分电路板做的实时电子闹钟实时电子闹钟程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int//按键sbit s1=P3^4; //设置sbit s2=P3^5; //减sbit s3=P3^6; //增sbit s4=P3^7; //闹钟sbit beep=P2^4; //蜂鸣器//1602位声明(实验板)sbit rs1602=P2^5;sbit rw1602=P2^6;sbit en1602=P2^7;/*uchar code table0[9]={"2010-4-13"};uchar code table1[8]={"11:03:05"};*///定义全局变量uchar shi,fen,miao,nian,yue,ri,week,s1num,num,flag,flag_di,flag1,amiao,afen,ashi;//延时x*1msvoid delay(uint x){uint a,b;for(a=0;a<x;a++)for(b=0;b<63;b++);}//转换函数uchar Convert(uchar In_Date){uchar i,Out_Date=0,temp=0;for(i=0;i<8;i++){temp=(In_Date>>i)&0x01;Out_Date|=(temp<<(7-i));}return Out_Date;}//1602写操作//写指令void write1602com(uchar com){rs1602=0;rw1602=0;en1602=0;P0=0xff;P0=Convert(com);delay(2);en1602=1;delay(2);en1602=0;delay(2);rs1602=1;}//写数据void write1602data(uchar adata) {rs1602=1;rw1602=0;en1602=0;P0=0xff;P0=Convert(adata);delay(2);en1602=1;delay(2);en1602=0;delay(2);rs1602=0;}//1602初始化设置void init_1602(){rs1602=0;rw1602=0;en1602=0;write1602com(0x38);write1602com(0x0c);write1602com(0x06);write1602com(0x01);write1602com(0x80);//外部中断EA=1;EX0=1;IT0=1;//闹钟标志位flag1=0;flag=0;flag_di=1;s1num=0;}//在1602中显示时分秒void lcd_sfm(uchar add,uchar adata){uchar shiwei,gewei;shiwei=adata/10;gewei=adata%10;write1602com(0x80+0x40+add); //在高位停留// delay(10);write1602data(shiwei+0x30);write1602data(gewei+0x30);}//在1602中显示年月日void lcd_nyr(uchar add,uchar adata){uchar shiwei,gewei;shiwei=adata/10;gewei=adata%10;write1602com(0x80+add); //在高位停留// delay(10);write1602data(shiwei+0x30);write1602data(gewei+0x30);}//1602时钟横杠等字符的显示void lcd1602showsign(){lcd_nyr(0,20);write1602com(0x80+4);write1602data('-');write1602com(0x80+7);write1602data('-');write1602com(0x80+0x40+2);write1602data(':');write1602com(0x80+0x40+5);write1602data(':');}//DS12887部分程序//位申明sbit ds12887_ds=P2^3;sbit ds12887_rw=P2^2;sbit ds12887_as=P2^1;sbit ds12887_cs=P2^0;sbit ds12887_irq=P3^2;//ds12887写数据及指令操作void ds12887_write(uchar add,uchar adata) {ds12887_as=0;ds12887_ds=1;ds12887_rw=1;ds12887_cs=0;ds12887_as=1;P1=add;ds12887_as=0;ds12887_rw=0;P1=adata;ds12887_rw=1;ds12887_as=1;}//ds12887读数据操作uchar ds12887_read(uchar add){uchar k;ds12887_ds=1;ds12887_rw=1;ds12887_as=1;ds12887_cs=0;P1=add;ds12887_as=0;ds12887_ds=0;P1=0xff;k=P1;ds12887_ds=1;ds12887_cs=1;ds12887_as=1;return k;}//设置ds12887初始时间void set_time(){ds12887_write(0x00,50); //secondds12887_write(0x02,59); //minuteds12887_write(0x04,23); //hourds12887_write(0x06,3); //dayds12887_write(0x07,16); //dateds12887_write(0x08,4); //monthds12887_write(0x09,10); //year}//闹钟滴滴响声void didi(){beep=0;delay(100);beep=1;delay(100);beep=0;delay(100);beep=1;}//ds12887初始化void init_ds12887(){ds12887_write(0x0a,0x20);ds12887_write(0x0B,0x26);//SET置1还是置0??set_time();}//闹钟设定void set_alarm(uchar hour,uchar minute,uchar second) {ds12887_write(1,second);ds12887_write(3,minute);ds12887_write(5,hour);}//读取闹钟数据void read_alarm(){amiao=ds12887_read(1);afen=ds12887_read(3);ashi=ds12887_read(5);}//显示星期void show_week(){switch(week){case 1:write1602com(0x80+11);write1602data('M');write1602data('O');write1602data('N');break;case 2:write1602com(0x80+11);write1602data('T');write1602data('U');write1602data('S');break;case 3:write1602com(0x80+11);write1602data('W');write1602data('E');write1602data('N');break;case 4:write1602com(0x80+11);write1602data('T');write1602data('H');write1602data('U');break;case 5:write1602com(0x80+11);write1602data('F');write1602data('R');write1602data('I');break;case 6:write1602com(0x80+11);write1602data('S');write1602data('A');write1602data('T');break;case 7:write1602com(0x80+11);write1602data('S');write1602data('U');write1602data('N');break;}}//清除设置星期时的数字型显示void clearnumofweek(){write1602com(0x80+14);write1602data(' ');write1602data(' ');}//按键扫描void keyscan(){if(flag_di==0){if((s1==0)||(s2==0)||(s3==0)||(s4==0)) {delay(5);if((s1==0)||(s2==0)||(s3==0)||(s4==0)) {while(!(s1&&s2&&s3&&s4));didi();flag_di=1;}}// flag_di=1;}if(s1==0){delay(10);if(s1==0){s1num++;if(flag1==1){if(s1num==4){s1num=1;// write1602com(0x80+0x40+7);// write1602com(0x0f);}}// s1num++;flag=1;while(!s1);beep=0;delay(50);beep=1;switch(s1num){case 1:write1602com(0x80+0x40+7);write1602com(0x0f);break;case 2:write1602com(0x80+0x40+4);write1602com(0x0f);break;case 3:write1602com(0x80+0x40+1);write1602com(0x0f);break;case 4:write1602com(0x80+15);write1602com(0x0f);break;case 5:write1602com(0x80+9);write1602com(0x0f);break;case 6:write1602com(0x80+6);write1602com(0x0f);break;case 7:write1602com(0x80+3);write1602com(0x0f);break;case 8:ds12887_write(0x00,miao); //secondds12887_write(0x02,fen); //minuteds12887_write(0x04,shi); //hourds12887_write(0x06,week); //dayds12887_write(0x07,ri); //dateds12887_write(0x08,yue); //monthds12887_write(0x09,nian); //year// delay(100);flag=0;s1num=0;break;}}if(s1num!=0){if(s2==0){delay(5);if(s2==0){while(!s2);beep=0;delay(50);beep=1;switch(s1num){case 1:miao++;if(miao==60)miao=0;lcd_sfm(6,miao);write1602com(0 x80+0x40+7);break;case 2:fen++;if(fen==60)fen=0;lcd_sfm(3,fen);write1602com(0 x80+0x40+4);break;case 3:shi++;if(shi==24)shi=0;lcd_sfm(0,shi);write1602com(0 x80+0x40+1);break;case 4:week++;if(week==8)week=1;lcd_nyr(14,week);write1602com(0 x80+15);break;case 5:ri++;if(ri==32)ri=1;lcd_nyr(8,ri);write1602com(0break;case 6:yue++;if(yue==13)yue=1;lcd_nyr(5,yue);write1602com(0 x80+6);break;case 7:nian++;if(nian==100)nian=0;lcd_nyr(2,nian);write1602com(0 x80+3);break;}}}if(s3==0){delay(5);if(s3==0){while(!s3);beep=0;delay(50);beep=1;switch(s1num){case 1:miao--;if(miao==-1)miao=59;lcd_sfm(6,miao);write1602com(0 x80+0x40+7);break;case 2:fen--;if(fen==-1)fen=59;lcd_sfm(3,fen);write1602com(0 x80+0x40+4);break;case 3:shi--;if(shi==-1)shi=23;lcd_sfm(0,shi);write1602com(0 x80+0x40+1);break;case 4:week--;if(week==0)week=7;lcd_nyr(14,week);write1602com(0 x80+15);break;case 5:ri--;if(ri==0)ri=31;lcd_nyr(8,ri);write1602com(0 x80+9);break;case 6:yue--;if(yue==0)yue=12;lcd_nyr(5,yue);write1602com(0 x80+6);break;case 7:nian--;if(nian==-1)nian=99;lcd_nyr(2,nian);write1602com(0 x80+3);break;}}}if(s4==0){delay(5);if(s4==0){// while(!s4);beep=0;delay(50);beep=1;num++;while(!s4);beep=0;delay(50);beep=1;// flag1=1;// flag1=~flag1;if(num==1)// if(flag1==1) //设置闹钟{flag1=1;write1602com(0x80+0x40+7);write1602com(0x0f);read_alarm();miao=amiao;fen=afen;shi=ashi;write1602com(0x80+0x40+9);write1602data('D');write1602data('i');// write1602com(0x80+0x40+7);// write1602com(0x0f);lcd_sfm(0,ashi);lcd_sfm(3,afen);lcd_sfm(6,amiao);}// else //退出闹钟设置,并把设置的时间输入进DS12C887中if(num==2){// delay(50);num=0;s1num=0;write1602com(0x80+0x40+9);write1602data(' ');write1602data(' ');// write1602com(0x0c);// ds12887_write(1,miao);// ds12887_write(3,fen);// ds12887_write(5,shi);set_alarm(shi,fen,miao);flag1=0;flag=0;}}}}}void main(){/*uchar i;init_1602();for(i=0;i<9;i++){write1602data(table0[i]);delay(5);}delay(10);write1602com(0x80+0x40);for(i=0;i<8;i++){write1602data(table1[i]);delay(5);}while(1);*/init_1602();lcd1602showsign();init_ds12887();while(1){keyscan();if(flag_di==0){// delay(100);didi();// delay(200);// flag_di=1;}// delay(10);if((flag==0)&&(flag1==0)){keyscan();// delay(10);shi=ds12887_read(0x04);fen=ds12887_read(0x02);miao=ds12887_read(0x00);nian=ds12887_read(0x09);yue =ds12887_read(0x08);ri =ds12887_read(0x07);week=ds12887_read(0x06);lcd_sfm(0,shi);lcd_sfm(3,fen);lcd_sfm(6,miao);lcd_nyr(2,nian);lcd_nyr(5,yue);lcd_nyr(8,ri);// lcd_nyr(14,week);show_week();clearnumofweek();}}}void exter0() interrupt 0{uchar c;flag_di=0;c=ds12887_read(0x0c);}。
基于单片机智能音乐闹钟源代码#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code font[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0 xbf}; //uchar code tab[]={0xc40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06, 0x0e};uint code note_value[][14]={{0,63628,63835,64021,64103,64260,64400,64524,63731,63928,0,64185,64331,64463}, //低音1,2,3,4,5,6,7,#1,#2,0(#3在此程序中无需设),#4,#5,#6 相对应的定时器初值{0,64580,64684,64777,64820,64898,64968,65030,64633,64732,0,64860,64934,64994}, //中音1,2,3,4,5,6,7,#1,#2,0(#3在此程序中无需设),#4,#5,#6 相对应的定时器初值{0,65058,65110,65157,65178,65217,65252,65283,65085,65134,0,65198,65235,65268}//高音1,2,3,4,5,6,7,#1,#2,0(#3在此程序中无需设),#4,#5,#6 相对应的定时器初值};uint code song[][67]={/* 0 嘀~(按键时的嘀嗒声)*/ {0x2701,0x0},/* 1 茉莉花*/ {0x1304,0x1302,0x1502,0x1602,0x2102,0x2102,0x1602,0x1504,0x1502,0x1602,0x1507,0x1001, /*0x1304,0x1302,0x1502,0x1602,0x2102,0x2102,0x1602,0x1504,0x1502,0x1602,0x1507,0x1001,* / 0x1504,0x1504,0x1504,0x1302,0x1502,0x1604,0x1604,0x1507,0x1001, 0x1304,0x1202,0x1302,0x1504,0x1302,0x1202,0x1104,0x1102,0x1202,0x1107,0x1001,0x1302,0x1202,0x1102,0x1302,0x1204,0x1002,0x1302,0x1504,0x1602,0x2102,0x1507,0x1001, 0x1202,0x1302,0x1502,0x1202,0x1302,0x1102,0x0602,0x0507,0x1001,0x0604,0x0602,0x1102,0 x1206,0x1302,0x1102,0x1202,0x1102,0x0602,0x050d,0x0},/* 2 莫斯科郊外的晚上*/{0x0602,0x1102,0x1302,0x1102,0x1204,0x1102,0x0702,0x1304,0x1204,0x0607,0x1001,0x1102,0x1302,0x1502,0x1502,0x1604,0x1502,0x1402,0x1307,0x1001,0x1414,0x1514,0x1702,0x1602,0x1304, 0x1002,0x0704,0x0602,0x1302,0x1202,0x1404, 0x1004,0x1502,0x1402,0x1304,0x1202,0x1102,0x1304,0x1204,0x060c, 0x0},/* 3 祝你生日快乐*/ {0x0502,0x0502,0x0604,0x0504,0x1104,0x0708,0x0502,0x0502,0x0604,0x0504,0x1204,0x 1108,0x0502,0x0502,0x1504,0x1304,0x1104,0x0704,0x0604,0x1402,0x1402,0x1304,0x1104,0x1 204,0x1108,0x0},/* 4 铃儿响叮当*/ {0x1302,0x1302,0x1303,0x1001, 0x1302,0x1303,0x1001, 0x1302,0x1502,0x1102,0x1202,0x1307,0x1001,0x1402,0x1402,0x1402,0x1402,0x1402,0x1302,0x1302,0x1302,0x1302,0x1202,0x1202,0x1302,0 x1204,0x1503,0x1001, 0x1302,0x1302,0x1303,0x1001, 0x1302,0x1303,0x1001, 0x1302,0x1502,0x1102,0x1202,0x1307,0x1001,0x1402,0x1402,0x1402,0x1402,0x1402,0x1302,0x1302,0x1302,0x1502,0x1502,0x1402,0x1202,0 x1108,0x0},/* 5 喀秋莎*/ {0x0606,0x0702,0x1106,0x0602,0x1102,0x1102,0x0702,0x0602,0x0704,0x1002,0x0706,0x1102,0x1206,0x0702,0x1202,0x1202,0x1102,0x0702,0x0607,0x1001,0x1304,0x1604,0x1504,0x1602,0x1502,0x1402,0x1402,0x1302,0x1202,0x1304,0x0604,0x1002,0x1404,0x1202,0x1306,0x1102,0x0702,0x0302,0x1102,0x0702,0x0608,0x0},/* 6 欢乐颂*/ {0x1304,0x1304,0x1404,0x1504,0x1504,0x1404,0x1304,0x1204,0x1104,0x1104,0x1204,0x 1304,0x1306,0x1202,0x1207,0x1001,0x1304,0x1304,0x1404,0x1504,0x1504,0x1404,0x1304,0x1204,0x1104,0x1104,0x1204,0x1304,0 x1206,0x1102,0x1107,0x1001, 0x0},/* 7 四季歌*/ {0x1304,0x1302,0x1202,0x1104,0x1102,0x0702,0x0604,0x0604,0x0607,0x1001,0x1404,0x1402,0x1302,0x1202,0x1102,0x1202,0x1402,0x130f,0x1001,0x1404,0x1402,0x1302,0x1204,0x1202,0x1402,0x1304,0x1302,0x1102,0x0604,0x0604,0x0704,0 x1304,0x1302,0x1102,0x0702,0x1102,0x060f,0x0},/* 8 月亮代表我的心*/ {0x150a,0x1302,0x1202,0x1102,0x130f,0x160a,0x1402,0x1202,0x1102,0x070c,0x1002,0x0502, 0x1106,0x1302,0x1506,0x1102,0x0706,0x1302,0x1504,0x1002,0x1502,0x1606,0x1702,0x2106,0 x1604,0x150a,0x1302,0x1202,0x1106,0x1102,0x1104,0x1302,0x1202,0x1106,0x1102,0x1104,0x 1202,0x1302,0x1206,0x1102,0x0606,0x1201,0x1301,0x120c,0x1002,0x0502,0x1106,0x1302,0x1 506,0x1102,0x0706,0x1302,0x1504,0x1002,0x1502,0x1606,0x1702,0x2106,0x1604,0x150a,0x13 02,0x1202,0x1106,0x1102,0x1104,0x1302,0x0},//0x1202,0x1106,0x1102,0x1104,0x1202,0x1302 ,0x1206,0x0602,0x0704,0x1102,011202,0x110c,0x1302,0x1502,0x1306,0x1202,0x1104,0x1504,0 x070c,0x0602,0x0702,0x0606,0x0702,0x0604,0x0504,0x130c,0x1504,0x1306,0x1202,0x1104,0x 1504,0x070c,0x0602,0x0702,0x1106,0x1102,0x1104,0x1202,0x1302,0x120c,0x1002,0x0502,0x1 106,0x1302,0x1506,0x1102,0x0706,0x1302,0x1504,0x1002,0x1502,0x1606,0x1702,0x2106,0x16 04,0x150a,0x1302,0x1202,0x1106,0x1102,0x1104,0x1302,0x1202,0x1106,0x1102,0x1104,0x120 2,0x1302,0x1206,0x0602,0x0704,0x1102,0x1202,0x1104,0x1502,0x1402,0x1304,0x1202,0x1102 ,0x1104,0x0702,0x0602,0x0518,0x050f,0x0},/* 9 献给爱丽丝*/ {0x2302,0x2212,0x2302,0x2212,0x2302,0x1702,0x2202,0x2102,0x1604,0x1002,0x1102,0x1302,0x1602,0x1704, 0x1002,0x1302,0x1512,0x1702,0x2104, 0x1002,0x1302,0x2302,0x2212,0x2302,0x2212,0x2302,0x1702,0x2202,0x2102,0x1604,0x1002,0x1102,0x1302,0x1602,0x1704, 0x1002,0x1202,0x2102,0x1702,0x1604, 0x1002,0x1702,0x2102,0x2202,0x2305,0x1001, 0x1502,0x2402,0x2302,0x2205,0x1001, 0x1402,0x2302,0x2202,0x2105,0x1001, 0x1302,0x2202,0x2102,0x1704, 0x1002,0x1302,0x2302,0x1002, 0x0},// 0x2212,0x2302, 0x1002,0x1002,0x2212,0x2302,0x2212,0x2302,0x2212,0x2302,0x1702,0x2202,0x2102,0x1604, 0x1002,0x1102,0x1302,0x1602,0x1704, 0x1002,0x1302,0x1512,0x1702,0x2104,0x1002,0x1302,0x2302,0x2212,0x2302,0x2212,0x2302,0x1702,0x2202,0x2102,0x1604,0x1002,0x1102,0x1302,0x1602,0x1704,0x1002,0x1202,0x2102,0x1702,0x1604,0x1004,0x0},/* 10 小星星,亮晶晶*/{0x1104,0x1104,0x1504,0x1504,0x1604,0x1604,0x1507,0x1001,0x1404,0x1404,0x1304,0x1304,0x1204,0x1204,0x1107,0x1001,0x1504,0x1504,0x1404,0x1404,0x1304,0x1304,0x1207,0x1001,0x1504,0x1504,0x1404,0x1404,0x1304,0x1304,0x1207,0x1001,0x1104,0x1104,0x1504,0x1504,0x1604,0x1604,0x1507,0x1001,0x1404,0x1404,0x1304,0x1304,0x1204,0x1204,0x1107,0x1001, 0x0},/* 11 Nokia经典铃声*/ {0x2502,0x2402,0x1604,0x1704,0x2302,0x2202,0x1404,0x1504,0x2202,0x2102,0x1304,0x1504, 0x210c,0x2502,0x2402,0x1604,0x1704,0x2302,0x2202,0x1404,0x1504,0x2202,0x2102,0x1304,0x1504,0 x210c,0x0}/* 12 两只老虎*/ {0x1104,0x1204,0x1304,0x1104,0x1104,0x1204,0x1304,0x1104,0x1304,0x1404,0x1508,0x 1304,0x1404,0x1508,0x1502,0x1602,0x1502,0x1402,0x1304,0x1104,0x1502,0x1602,0x1502,0x1 402,0x1304,0x1104,0x1304,0x0504,0x1108,0x1304,0x0504,0x1108,0x0}};sbit key_select=P1^0; //功能键sbit key_inc=P1^1; // 增大建sbit key_dec=P1^2; // 减小键&强行关闹钟和歌曲键sbit key_alarm_or_song=P1^3; //调闹钟键&点歌键sbit buzzer=P0^0;bit music_break=0;uchar week=1,hour=12,minute=0,second=0, alarm_num,display[]={1,2,0,0,0,0},n=0,bit_code=0xfb,alarm_break=1,flag_display=0,flag_a larm=0; //定义数组display[6]作为显示缓冲区,n为数组下标,flag_display用于设置时间或闹钟时的闪烁显示标志,flag_alarm用于闹钟键按下的标志uchardisplay_music[6]={0x10,0x10,0,0,0x10,0x10},display_alarm[6]={0,0,0,0,0,0},alarm[][3]={{12}, {12,1},{12,3},{12,5},{1},{2},{3},{4},{5},{6}},alarm_num=0,song_num=0;uint initial_value,count_display=0,count=0; //count_display用于设置时间或闹钟时的闪烁显示记时变量void delay_ms(uint t) //延时1ms{uint i,j;for(i=t;i>0;i--)for(j=110;j>0;j--);}void di() //按键发声函数{buzzer=0;delay_ms(100);buzzer=1;}void music(uchar song_number){uchar i,section,basic_note,changed_note,pitch,duration,note_num=0; //分别定义i,音区,基本音级,变化音级,音高,时值,所选歌曲的音符的编号uint note; //定义音符变量ET1=1;music_break=1;note=song[song_number][note_num];while(note!=0&&music_break){section=note/0x1000;basic_note=note/0x100%0x10;changed_note=note/0x10%0x10;duration=note%0x10;if(changed_note==1)pitch=basic_note+7;pitch=basic_note;initial_value=note_value[section][pitch];if(initial_value!=0){TH1=initial_value/256;TL1=initial_value%256;TR1=1;}elseTR1=0;if(key_alarm_or_song==0){delay_ms(10);if(key_alarm_or_song==0)break;}for(i=duration;i>0;i--) //音符延时函数delay_ms(125);note_num++;note=song[song_number][note_num];if(key_dec==0) //强行关闭闹钟{delay_ms(10);if(key_dec==0){while(!key_dec);break;}}}music_break=0;TR1=0;}void alarm_(){for(alarm_num=1;alarm_num<10;alarm_num++) //添加闹钟时需要修改的地方!!!!!!!!!!if(hour==alarm[alarm_num][0]&&minute==alarm[alarm_num][1]&&second==alarm[alarm_ num][2]){display_alarm[0]=alarm[alarm_num][0]/10;display_alarm[1]=alarm[alarm_num][0]%10;display_alarm[2]=alarm[alarm_num][1]/10;display_alarm[3]=alarm[alarm_num][1]%10;display_alarm[4]=0x10;display_alarm[5]=alarm_num;music(alarm_num);}}/*void alarm_ () //闹钟发声函数{if(hour==alarm[0]&&minute==alarm[1]&&second==alarm[2]){uint k;for(k=10;k>0;k--){buzzer=0;delay_ms(100);buzzer=1;}}}*/void scan_key() //按键扫描函数{bit flag_break=0; //flag_break作为跳出按键扫描循环程序的标志位if(key_select==0){delay_ms(10);if(key_select==0) // 确认功能键被按下{while(!key_select); //释放确认di();while(1) //时按键处理{flag_display=1;if(flag_break==1){alarm_num=0;break;}if(key_alarm_or_song==0){delay_ms(10);if(key_alarm_or_song==0){flag_alarm=1;if(flag_break==1){alarm_num=0;break;}alarm_num++;if(alarm_num==10) //添加闹钟时需要修改的地方!!!!!!!!!!alarm_num=1;display_alarm[0]=alarm[alarm_num][0]/10;display_alarm[1]=alarm[alarm_num][0]%10;display_alarm[2]=alarm[alarm_num][1]/10;display_alarm[3]=alarm[alarm_num][1]%10;display_alarm[4]=0x10;display_alarm[5]=alarm_num%10;while(!key_alarm_or_song);di();}}if(key_select==0){delay_ms(10);if(key_select==0) //确认功能键改时被按下{while(!key_select); //释放确认di();while(1) //分按键处理{flag_display=2;if(flag_break==1)break;if(key_select==0){delay_ms(10);if(key_select==0) //确认功能键改分被按下{while(!key_select); //释放确认di();while(1) //秒按键处理{flag_display=3;if(key_select==0){delay_ms(10);if(key_select==0)//确认功能键改秒被按下{while(!key_select);//此处等待按键释放非常重要!!!di();flag_alarm=0;flag_break=1;break;}}if(key_inc==0&&flag_alarm==0){delay_ms(10);if(key_inc==0){if(flag_alarm==0){second++;if(second==60)second=0;display[4]=second/10;display[5]=second%10;while(!key_inc);}else{alarm[alarm_num][2]++;if(alarm[alarm_num][2]==60)alarm[alarm_num][2]=0;display_alarm[4]=0x10;display_alarm[5]=alarm_num;while(!key_inc);}di();}}if(key_dec==0){delay_ms(10);if(key_dec==0){if(flag_alarm==0){second--;if(second==255)second=59;display[4]=second/10;display[5]=second%10;while(!key_dec);}else{alarm[alarm_num][2]--;if(alarm[alarm_num][2]==255)alarm[alarm_num][2]=59;display_alarm[4]=0x10;display_alarm[5]=alarm_num;while(!key_dec);}di();}}}}}if(key_inc==0){delay_ms(10);if(key_inc==0){if(flag_alarm==0){minute++;if(minute==60)minute=0;display[2]=minute/10;display[3]=minute%10;while(!key_inc);}else{alarm[alarm_num][1]++;if(alarm[alarm_num][1]==60)alarm[alarm_num][1]=0; display_alarm[2]=alarm[alarm_num][1]/10;display_alarm[3]=alarm[alarm_num][1]%10;while(!key_inc);}di();}}if(key_dec==0){delay_ms(10);if(key_dec==0){if(flag_alarm==0){minute--;if(minute==255)minute=59;display[2]=minute/10;display[3]=minute%10;while(!key_dec);}else{alarm[alarm_num][1]--;if(alarm[alarm_num][1]==255)alarm[alarm_num][1]=59; display_alarm[2]=alarm[alarm_num][1]/10;display_alarm[3]=alarm[alarm_num][1]%10;while(!key_dec);}di();}}}}}if(key_inc==0){delay_ms(10);if(key_inc==0){if(flag_alarm==0){hour++;if(hour==24)hour=0;display[0]=hour/10;display[1]=hour%10;while(!key_inc);}else{alarm[alarm_num][0]++;if(alarm[alarm_num][0]==24)alarm[alarm_num][0]=0;display_alarm[0]=alarm[alarm_num][0]/10;display_alarm[1]=alarm[alarm_num][0]%10;while(!key_inc);}di();}}if(key_dec==0){delay_ms(10);if(key_dec==0){if(flag_alarm==0){hour--;if(hour==255)hour=23;display[0]=hour/10;display[1]=hour%10;while(!key_dec);}else{alarm[alarm_num][0]--;if(alarm[alarm_num][0]==255)alarm[alarm_num][0]=23;display_alarm[0]=alarm[alarm_num][0]/10;display_alarm[1]=alarm[alarm_num][0]%10;while(!key_dec);}di();}}}}}flag_display=0;if(key_alarm_or_song==0){delay_ms(10);if(key_alarm_or_song==0){while(!key_alarm_or_song);song_num++;if(song_num==12)song_num=1; //添加歌曲时需要修改的地方!!!!!!!!!!display_music[2]=song_num/10;display_music[3]=song_num%10;music(song_num);}}}void main(){TMOD=0x11;EA=1;ET0=1;ET1=1;TH0=0xf6; //定时50ms 初值TL0=0x3c;TR0=1;PT1=1;PT0=0;while(1){ buzzer=1;alarm_num=0;scan_key();alarm_();}}void timer_0() interrupt 1{TH0=0xf6;TL0=0x3c;count++;if(count==400){count=0;second++;display[4]=second/10;display[5]=second%10;if(second==60){second=0;display[4]=second/10;display[5]=second%10;minute++;display[2]=minute/10;display[3]=minute%10;if(minute==60){minute=0;display[2]=minute/10;display[3]=minute%10;hour++;if(hour==24)hour=0;display[0]=hour/10;display[1]=hour%10;}}}if(flag_alarm==0){if(music_break==1&&alarm_num==0)P3=font[display_music[n]];else{if(music_break==1&&alarm_num!=0){if(n==1)P3=font[display_alarm[n]]&0x7f;elseP3=font[display_alarm[n]];}else{if(n==1||n==3)P3=font[display[n]]&0x7f;elseP3=font[display[n]];}}}elseif(n==1)P3=font[display_alarm[n]]&0x7f;elseP3=font[display_alarm[n]];n++;if(n==6)n=0;switch(flag_display) //调时、调闹钟闪烁部分{case 0: {P2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;} break;case 1: {count_display++;if(count_display<=200){P2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}if(count_display>200&&count_display<=400){if(count_display==400)count_display=0;if(bit_code==0xfb||bit_code==0xf7)P2=0xff;elseP2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}} break;case 2: {count_display++;if(count_display<=200){P2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}if(count_display>200&&count_display<=400){if(count_display==400)count_display=0;if(bit_code==0xef||bit_code==0xdf)P2=0xff;elseP2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}} break;case 3: {if(flag_alarm==0){count_display++;if(count_display<=200){P2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}if(count_display>200&&count_display<=400){if(count_display==400)count_display=0;if(bit_code==0xbf||bit_code==0x7f)P2=0xff;elseP2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}}else{P2=bit_code;bit_code=_crol_(bit_code,1);if(bit_code==0xfe)bit_code=0xfb;}} break;default : break;}}void timer_1() interrupt 3{TH1=initial_value/256;TL1=initial_value%256;buzzer=~buzzer;}。
单片机闹钟程序设计这个是在之前的电子时钟上功能的扩展,主要加入闹钟模块。
即到达预定时间响铃一分钟,一分钟后自动停止,也可以按下已设定的键实现手动停止。
数码管方面的学习就到此为此吧,下一步是对液晶显示的学习。
单片机闹钟程序设计如下:#i nclude;#define uchar unsigned charunsigned char codetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管数字编码uchari,j,k,second,tcount,minute,hour,tminute,thour,rin g;sbit beep=P2^6;sbitS2=P3^4;//---------------------------------------------------延时子程序,大约延时 n MSdelay(uchar n){for(j=n;j>;0;j--)for(k=125;k>;0;k--);}//---------------------------------------------------中断子程序void timer0() interrupt 1 using 0{TH0=(65536-50000)/256;//中断设置初始化TL0=(65536-50000)%256;tcount++;if(tcount==20)//满1秒{tcount=0;second++;beep=0;//秒数加1 if(second==60)//满1分{second=0;minute++;//分数加1,秒数归零if(minute==60)//满1小时{minute=0;hour++;//小时数加1,分数归零if(hour==24){hour=0;}}} }}void timer1() interrupt 3 using 1{TH1=0x3c; //中断设置初始化TL1=0xb0;if(minute==tminute & hour==thour & ring==1) {beep=0;}//到预设时间自动响铃,持续一分钟后自己关闭if(S2==0){ring=0;//铃声中断}}//---------------------------------------------------void main(){tminute=1;thour=0;//预置响铃时间second=55;minute=0;hour=0;//给电子时钟赋初值,即启动时显示的时间ring=1; //启动响铃功能TH0=(65536-50000)/256;//中断设置初始化TL0=(65536-50000)%256;EA=1;ET0=1;TMOD=0x21;TR0=1;//开中断总开关,计数器0允许中断,设置中断模式,启动计数器0ET1=1;TR1=1;while(1)//死循环,进入显示,主要是动态显示原理{ P0=table[(second%10)]; P2=0xdf; delay(5);P0=table[(second/10)]; P2=0xef; delay(5);P0=table[(minute%10)]; P2=0xf7; delay(5);P0=table[(minute/10)]; P2=0xfb; delay(5);P0=table[(hour%10)]; P2=0xfd; delay(5);P0=table[(hour/10)]; P2=0xfe; delay(5); }}。
#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define LED P0 // 数码管的段选#define LIGHT P1 // 时分秒位的指示灯#define WS P2 // 数码管的位选sbit key1=P3^0; // 时间暂停/开始sbit key2=P3^1; // 时间/闹钟设置sbit key3=P3^2; // 增加sbit key4=P3^3; // 减少sbit alarm=P3^6; // 闹铃uchar tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 0-9 uchar tab_dp[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; // 0.-9.(带小数点)uchar data1[]={0,0,0,0,0,0};uchar data2[]={0,0,0,0,0,0};uint t,k,kk,k1,flag;uint bbh,bbm,bbs,bbh1,bbm1,bbs1;uint sec,min,hour,sec1,min1,hour1; // 定义秒,分,时void init();void display();void display_bb();void delay( uint );void keyscan();void main(){init();while(1){keyscan();if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if((bbh==hour)&&(bbm==min)&&data1[4]==0&&data1[5]==5) // 5s报时{alarm=~alarm;delay(1);}if((bbs==sec)&&(bbm==min)&&(bbh==hour)) // 可调报时{alarm=~alarm;delay(1);}}}void init(){WS=LIGHT=flag=0;sec=min=hour=0; // 将0赋给时分秒TMOD=0x01; // 方式1 P129(见课本)TH0=0x3c; // 65536-50000=15536=0x3cb0(50ms) P128(见课本)TL0=0xb0;EA=1; // 开总中断 P161(见课本)TR0=1; // 定时/计数器0开启ET0=1; // 定时器/计数器0溢出中断启动 P161(见课本)}void delay( unsigned int t) // 延时函数{unsigned int i;while(t--)for(i=0;i<125;i++);}void display() // 显示时间函数{if(TF0==1) // 定时器/计数器溢出 P130(见课本){TF0=0; // 清中断标志位t++;if(t==20) // (50ms*20=1s){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;}}}data1[5]=sec%10;data1[4]=sec/10;data1[3]=min%10;data1[2]=min/10;data1[1]=hour%10;data1[0]=hour/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data1[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data1[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data1[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data1[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data1[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data1[0]];delay(1);}void display_bb() // 显示闹钟函数{data2[5]=bbs%10;data2[4]=bbs/10;data2[3]=bbm%10;data2[2]=bbm/10;data2[1]=bbh%10;data2[0]=bbh/10;WS=0xdf; // 1101 1111 ,低电平显示LED=tab[data2[5]];delay(1);WS=0xef; // 1110 1111LED=tab[data2[4]];delay(1);WS=0xf7; // 1111 0111LED=tab_dp[data2[3]];delay(1);WS=0xfb; // 1111 1011LED=tab[data2[2]];delay(1);WS=0xfd; // 1111 1101LED=tab_dp[data2[1]];delay(1);WS=0xfe; // 1111 1110LED=tab[data2[0]];delay(1);}void keyscan() // 键盘扫描{if(key1==0) // 暂停/开始{++kk;while(!key1){display();if(kk==1){TR0=0;if(k1==0||k1==1||k1==2||k1==3) // 显示调节时间{display();}if(k1==4||k1==5||k1==6) // 显示调节闹钟{display_bb();}if(key2==0) // 模式选择(调节时间/闹钟){k1++;while(!key2){if(k1==1) // 第1次按下{sec1=sec; // 保存秒的数值sec=88; // 显示88,表示可以调节秒的数值了display(); // 显示88sec=sec1; // 恢复前一刻秒的数值}if(k1==2){min1=min;min=88;display();delay(1);min=min1;}if(k1==3){hour1=hour;hour=88;display();delay(1);hour=hour1;}if(k1==4){sec1=bbs; // 保存秒的数值bbs=66; // 显示66,表示可以调节秒的数值了display_bb(); // 显示66bbs=sec1; // 恢复前一刻秒的数值}if(k1==5){min1=bbm;bbm=66;display_bb();delay(10);bbm=min1;}if(k1==6){hour1=bbh;bbh=66;display_bb();delay(10);bbh=hour1;}if(k1==7){k1=0;display();}}}if(key3==0) // 时间/闹钟增加设置{while(!key3){if(k1==1){sec++; // 秒加1delay(60);if(sec==60)sec=0;display();}if(k1==2){min++;delay(60);if(min==60)min=0;display();}if(k1==3){hour++;delay(60);if(hour==24)hour=0;display();}if(k1==4){bbs++; // 秒加1delay(60);if(bbs==60)bbs=0;display_bb();}if(k1==5){bbm++;delay(60);if(bbm==60)bbm=0;display_bb();}if(k1==6){bbh++;delay(60);if(bbh==24)display_bb();}if(k1==7){k1=0;display();}}}if(key4==0) // 时间/闹钟减少设置 {while(!key4){if(k1==1){sec--; // 秒加1delay(60);if(sec==0)sec=60;display();}if(k1==2){min--;delay(60);if(min==0)min=60;display();}if(k1==3){hour--;delay(60);if(hour==0)hour=24;display();}if(k1==4){bbs--; // 秒减1delay(60);if(bbs==0)display_bb();}if(k1==5){bbm--;delay(60);if(bbm==0)bbm=60;display_bb();}if(k1==6){bbh--;delay(60);if(bbh==0)bbh=24;display_bb();}if(k1==7){k1=0;display();}}}}}if(kk==2){kk=0;k1=0;TR0=1;}}}。
51单片机24小时闹钟时钟可调简单程序#includeunsigned char seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char con[6]={0x1,0x2,0x4,0x8,0x10,0x20};unsigned char mm=0;unsigned char ss=0;unsigned char hh=0;unsigned char count=100;unsigned char TH=01,TM=00,m;sbit S1=P3^3;sbit S2=P3^4;sbit S3=P3^5;sbit S4=P3^6;sbit S5=P3^7;sbit S6=P3^2;sbit bell=P3^0;main(){TMOD=1;TH0=-10000>>8;TL0=-10000; //10毫秒间隔EA=1;ET0=1;TR0=1;while(1);}void isr_time0() interrupt 1 //24小时{unsigned int i=0,j;unsigned char time[6];TH0=-10000>>8;TL0=-10000;count--;if(count==0){count=100;ss++;if(ss==60){ss=0;mm++;if(mm==60){mm=0;hh++;if(hh==24)hh=0;}}if(S5==0){TH++;} //闹钟调时if(S6==0){TM++;} //闹钟调分if(hh==TH){ unsigned int a,b,y;if(mm>=01){m=0;}if(mm==TM&&ss<10){if(m<10){do{m++;ss++; //ss确保闹钟时间继续for(a=0;a<1250;a++){bell=!bell;for(b=0;b<15;b++);} //取反for(y=0;y<1250;y++){bell=!bell;for(b=0;b<33;b++);}for(a=0;a<1250;a++){bell=!bell;for(b=0;b<15;b++);}for(a=0;a<1250;a++){bell=!bell;for(b=0;b<33;b++);}}while(m<10);}}}if(S1==0){hh++; //时钟加if(hh==24){hh=0;}}if(S2==0){mm++; //分钟加if(mm==60){ mm=0;hh++;}}if(S3==0&&hh>0){hh--; //时钟减if(hh==0){hh=23;}}if(S4==0&&mm>0){mm--; //分钟减if(mm==0){ mm=59;}}}time[3]=hh/10;time[2]=hh%10; //显示位time[1]=mm/10;time[0]=mm%10;for(i=0;i<6;i++){P2=con[i];if(i==1||i==2) //小数点P1=seg[time[i]]&0x7f;else P1=seg[time[i]];for(j=100;j>0;j--);}}。
姚辉虎的毕业设计--基于单片机的智能数字闹钟程序代码程序代码main.c#include <reg51.h>#include <intrins.h>#include <yf.h>unsigned char clock_data[4]。
sbit speaker = P2^4。
// 蜂鸣器sbit bell = P2^2。
//铃响bit bell_on=0。
bit key_ok=0。
unsigned char bell_time=0x20。
uchar week_clock_set。
#define FIRST_ADDR 0//定义全局变量unsigned char yy,mo,dd,xq,hh,mm,ss。
// 定义时间映射全局变量<专用寄存器)uchar j。
/****************************************************************************///函数声明extern unsigned char read_clock(unsigned char ord>。
extern void lcdwc(unsigned char cmdcode>。
extern void hzkdis(unsigned char code *s>。
extern void hzkdis2(unsigned char *s>。
extern char Read_One_Byte(unsigned char addr>。
extern void Write_One_Byte(unsigned char addr,unsigned char thedata>。
void lcm_w_ss(void>。
extern void lcdreset(void>。
extern void Init_DS18B20(void>。
extern char gotkey(>。
extern void Init_1302(void>。
extern unsigned int ReadTemperature(void>。
extern void write_clock(unsigned char ord, unsigned char dd>。
extern void disp_hz(uchar x,uchar *c_str,uchar w>。
extern void delay(unsigned int t>。
void new_time(void>。
void read_clockss(x>。
//void lcm_w_temp(void> 。
void read_clockS(void>{ss = read_clock(0x81>。
//读取秒数据mm = read_clock(0x83>。
//读取分钟数据hh = read_clock(0x85>。
//小时dd = read_clock(0x87>。
//日mo = read_clock(0x89>。
//月xq = read_clock(0x8b>。
//星期yy = read_clock(0x8d>。
//年}/*void Set_time(unsigned char sel>{ //根据选择调整的相应工程加1并写入DS1302 signed char address,item。
signed char max,mini。
if(sel==7> {address=0x80。
max=0。
mini=0。
} //秒if(sel==6> {address=0x82。
max=59。
mini=0。
} //分钟if(sel==5> {address=0x84。
max=23。
mini=0。
} //小时if(sel==3> {address=0x86。
max=31。
mini=1。
} //日if(sel==2> {address=0x88。
max=12。
mini=1。
} //月if(sel==1> {address=0x8c。
max=99。
mini=0。
} //年if(sel==4> {address=0x8a。
max=7。
mini=1。
} //星期//读取1302某地址上的数值转换成10进制赋给itemitem=((read_clock(address+1>>/16>*10 + (read_clock(address+1>>%16。
if(KEY_Y == 0>{item++。
//数加 1}if(KEY_N== 0>{item--。
//数减 1}if(item>max> item=mini。
//查看数值有效范围if(item<mini> item=max。
write_clock(0x8e,0x00>。
//允许写操作write_clock(address,(item/10>*16+item%10>。
//转换成16进制写入1302 write_clock(0x8e,0x80>。
//写保护,禁止写操作// updata (>。
//刷新数据// lcm_w_mm(>。
//刷新分}*/void DelayM(unsigned int a>{//延时函数 1MS/次unsigned char i。
while( --a != 0>{for(i = 0。
i < 125。
i++>。
//一个。
表示空语句,CPU空转。
} //i 从0加到125,CPU大概就耗时1毫秒}/*****************************************************************************///向LCM中填写年数据void lcm_w_yy(void>{ // if (read_clock(0x8d> != yy> {unsigned char str[2]。
str[2]=0。
yy = read_clock(0x8d>。
lcdwc(0x83+FIRST_ADDR>。
hzkdis("20">。
lcdwc(0x84+FIRST_ADDR>。
str[0]=(yy/16+0x30>。
str[1]=(yy%16+0x30>。
hzkdis2(str>。
hzkdis2("年">。
}/*****************************************************************************///向LCM中填写月数据void lcm_w_mo(void>{// if(read_clock(0x89> != mo>{unsigned char str[2]。
str[2]=0。
// lcm_w_test(0,0x90>。
lcdwc(0x90+FIRST_ADDR> 。
if(mo/16 != 0>{str[0]=mo/16+0x30。
} //十位消隐else{str[0]=0x20 。
}//同上str[1]=mo%16+0x30。
hzkdis2(str>。
lcdwc(0x91+FIRST_ADDR>。
hzkdis("月">。
}/*****************************************************************************///星期处理并送入LCM的指定区域void lcm_w_xq(void>{unsigned char sel。
unsigned char str[2]。
str[2]=0。
//if(read_clock(0x8b> != xq>{//xq = read_clock(0x8b>。
sel = (read_clock(0x8b>>%16。
//字节低4位的BCD码放入sellcdwc(0x97+FIRST_ADDR>。
//写入指定区域<97H 第二行第8个字)if(sel==7> {hzkdis("日">。
} //if(sel==6> {hzkdis("六">。
} //if(sel==5> {hzkdis("五">。
} //if(sel==4> {hzkdis("四">。
} //if(sel==3> {str[0]=0xc8。
str[1]=0xfd。
hzkdis2(str>/*lcm_w_test(1,0xc8>。
lcm_w_test(1,0xfd>*/。
} //此指令等于lcm_w_word("三">。
因为“三”的内码失效。
if(sel==2> {hzkdis("二">。
} //if(sel==1> {hzkdis("一">。
} //星期一lcdwc(0x95+FIRST_ADDR>。
hzkdis("星期"> 。
//}}/*****************************************************************************///向LCM中填写日数据void lcm_w_dd(void>{unsigned char str[2] 。
str[2]=0。
// if(read_clock(0x87> != dd>{dd = read_clock(0x87>。
lcdwc(0x92+FIRST_ADDR>。
if(dd/16 != 0>{str[0]=(dd/16>+0x30。
} //十位消隐else{str[0]=0x20。
}//同上str[1]=dd%16+0x30。
hzkdis2(str>。
lcdwc(0x93+FIRST_ADDR>。
hzkdis("日">。
} //}/*****************************************************************************/ //向LCM中填写小时数据void lcm_w_hh(void>{unsigned char str[2] 。