1602显示时钟

合集下载

LCD1602_显示时间_温度

LCD1602_显示时间_温度

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define LCDIO P2sbit DQ=P1^3;//ds18b20与单片机连接口sbit rs=P1^0;sbit rd=P1^1;sbit lcden=P1^2;sbit acc0=ACC^0; //移位时的第0位sbit acc7=ACC^7; //移位时用的第7位uchar second,minute,hour,day,month,year,week,count=0; uchar ReadValue,num,time;uint tvalue;//温度值uchar tflag;uchar code table[]={" 2010-11-29 MON"};uchar code table1[]={" 15:45:00 000.0C"};uchar code table2[]= "THUFRISATSUNMONTUEWES";uchar data disdata[5];sbit DATA=P0^1; //时钟数据接口sbit RST=P0^2;sbit SCLK=P0^0;sbit menu=P3^5; //菜单sbit add=P3^6; //加一sbit dec=P3^7; //减一void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }void delay1(uint z){for(;z>0;z--);}void write_com(uchar com) {rs=0;rd=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date) {rs=1;lcden=0;P2=date;delay(5);lcden=1;delay(5);lcden=0;}void init(){uchar num;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);delay(5);write_com(0x80);for(num=0;num<15;num++){write_date(table[num]);delay(5);write_com(0x80+0x40);for(num=0;num<15;num++){write_date(table1[num]);delay(5);}}void Write1302(uchar dat){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delay1(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302delay(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delay1(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 }}void WriteSet1302(uchar Cmd,uchar dat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delay1(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递}uchar Read1302(void){uchar i,dat;delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位 if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delay1(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delay1(2); //稍微等待}return dat; //将读出的数据返回}uchar ReadSet1302(uchar Cmd){uchar dat;RST=0; //拉低RSTSCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}void Init_DS1302(void){WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值 WriteSet1302(0x82,((45/10)<<4|(45%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((15/10)<<4|(15%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((29/10)<<4|(29%10))); //根据写日寄存器命令字,写入日的初始值 WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值 WriteSet1302(0x8c,((10/10)<<4|(10%10))); //nianWriteSet1302(0x8a,((4/10)<<4|(4%10)));}void DisplaySecond(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0xc7);write_date(0x30+i);write_date(0x30+j);}void DisplayMinute(uchar x){uchar i,j;i=x/10;j=x%10;write_com(0xc4);write_date(0x30+i);write_date(0x30+j);}void DisplayHour(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0xc1);write_date(0x30+i);write_date(0x30+j); }void DisplayDay(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x89);write_date(0x30+i);write_date(0x30+j); }void DisplayMonth(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x86);write_date(0x30+i);write_date(0x30+j); }void DisplayYear(uchar x) {uchar i,j;i=x/10;j=x%10;write_com(0x83);write_date(0x30+i);write_date(0x30+j); }void DisplayWeek(uchar x) { uchar i;x=x*3;write_com(0x8c);for(i=0;i<3;i++){write_date(table2[x]);x++;}}void read_date(void){ReadValue = ReadSet1302(0x81);second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x83);minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x85);hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x87);day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x89);month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue = ReadSet1302(0x8d);year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);ReadValue=ReadSet1302(0x8b); //读星期 week=ReadValue&0x07;DisplaySecond(second);DisplayMinute(minute);DisplayHour(hour);DisplayDay(day);DisplayMonth(month);DisplayYear(year);DisplayWeek(week);}void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num){newval=ReadSet1302(newaddr); //读取当前时间newval=((newval&0x70)>>4)*10+(newval&0x0f); //将bcd码转换成十进制if(flag) //判断是加一还是减一{newval++;switch(s1num){ case 1: if(newval>99) newval=0;DisplayYear(newval);break;case 2: if(newval>12) newval=1;DisplayMonth(newval);break;case 3: if(newval>31) newval=1;DisplayDay(newval);break;case 4: if(newval>6) newval=0;DisplayWeek(newval);break;case 5: if(newval>23) newval=0;DisplayHour(newval);case 6: if(newval>59) newval=0;DisplayMinute(newval);break;case 7: if(newval>59) newval=0;DisplaySecond(newval);break;default:break;}}else{newval--;switch(s1num){ case 1: if(newval==0) newval=99;DisplayYear(newval);break;case 2: if(newval==0) newval=12;DisplayMonth(newval);break;case 3: if(newval==0) newval=31;DisplayDay(newval);break;case 4: if(newval<0) newval=6;DisplayWeek(newval);case 5: if(newval<0) newval=23;DisplayHour(newval);break;case 6: if(newval<0) newval=59;DisplayMinute(newval);break;case 7: if(newval<0) newval=59;DisplaySecond(newval);break;default:break;}}WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10)); //将新数据写入寄存器}//键盘扫描程序//*******************************************void key_scan(void){ uchar miao,s1num=0;if(menu==0){delay(5);if(menu==0){while(!menu);s1num++;while(1){if(menu==0){delay(5);if(menu==0){while(!menu);s1num++;}}rd=0;miao=ReadSet1302(0x81);second=miao;WriteSet1302(0x80,miao|0x80);write_com(0x0f);//光标闪射if(s1num==1){ year=ReadSet1302(0x8d);write_com(0x80+4); //年光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(year,1,0x8d,1);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(year,0,0x8d,1);}}}if(s1num==2){month=ReadSet1302(0x89);write_com(0x80+7); //月光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(month,1,0x89,2); }}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(month,0,0x89,2); }}}if(s1num==3){ day=ReadSet1302(0x87);write_com(0x80+10);//日光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(day,1,0x87,3);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(day,0,0x87,3); //写入日寄存器 }}}if(s1num==4){ week=ReadSet1302(0x8b);write_com(0x80+14); //星期光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(week,1,0x8b,4);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(week,0,0x8b,4);}}}if(s1num==5){ hour=ReadSet1302(0x85);write_com(0x80+0x40+2); //时光标if(add==0){delay(3);if(add==0){ while(!add);turn_val(hour,1,0x85,5);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(hour,0,0x85,5);}}}if(s1num==6)//调时间分{ minute=ReadSet1302(0x83);write_com(0x80+0x40+5);if(add==0){delay(5);if(add==0){ while(!add);turn_val(minute,1,0x83,6); //写入分寄存器 }}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(minute,0,0x83,6); //写入分寄存器 }}}if(s1num==7)//调时间秒{ second=ReadSet1302(0x81);write_com(0x80+0x40+8);//秒光标if(add==0){delay(3);if(add==0){ while(!add);if(second==0x60)second=0x00;turn_val(second,1,0x81,7);}}if(dec==0){delay(3);if(dec==0){ while(!dec);turn_val(second,0,0x81,7);}}}if(s1num==8){ miao=ReadSet1302(0x81);second=miao;WriteSet1302(0x80,second&0x7f);s1num=0;//s1num清零//write_com(0x0c);//光标不闪烁//break;}}}}}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd();b=ds1820rd();tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数return(tvalue);}void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}write_com(0xc9);write_date(flagdat);//显示符号位write_com(0xca);write_date(disdata[0]);//显示百位write_com(0xcb);write_date(disdata[1]);//显示十位write_com(0xcc);write_date(disdata[2]);//显示个位write_com(0xcd);write_date(0x2e);//显示小数点write_com(0xce);write_date(disdata[3]);//显示小数位write_com(0xcf);write_date('C');}void main(){init();Init_DS1302(); //将1302初始化read_temp();//读取温度ds1820disp();//显示while(1){read_date();key_scan();read_temp();//读取温度ds1820disp();//显示}}完。

51单片机c语言编写的1602液晶显示闹钟

51单片机c语言编写的1602液晶显示闹钟

#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]=" 2012-08-17 MON"; //设定开始显示的时间uchar code table1[]=" 12:30:00";uchar code table2[7][3]= {{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};//定义二维字符数组sbit wr=P3^6; // 1602液晶的读/写端sbit dula=P2^6; // 数码管段选sbit wela=P2^7; // 数码管位选sbit lcden=P3^4; // 1602液晶使能端sbit lcdrs=P3^5; // 1602液晶命令/数据端sbit key1=P3^0; // 声明s4按键sbit key2=P3^1; // 声明s8按键sbit key3=P3^2; // 声明s12按键sbit key4=P3^3; // 声明s16按键sbit beep=P2^3; // 声明蜂鸣器sbit rd=P3^7; // 声明4个按键的公共端uchar num1,shi=12,fen=30,miao,yue=8,ri=17,shi1,fen1,miao1,keynum1,week; //定义时分秒变量uint nian=2012; //定义年变量void delayms(uint x){uint i,j;for(i=x;i>0;i--) //定义带参数延时函数for(j=110;j>0;j--);}void write_com(uchar com) //1602液晶写指令函数{ wr=0;lcdrs=0;P0=com;delayms(1);lcden=1;delayms(1);lcden=0;}void write_date(uchar date) //1602液晶写数据函数{ wr=0;lcdrs=1;P0=date;delayms(1);lcden=1;delayms(1);lcden=0;}void write_addate1(uchar add,uint date) //定义显示年的函数{ uint qian;uchar bai,shi,ge;qian=date/1000;bai=date%1000/100;shi=date%1000%100/10;ge=date%10;write_com(add+0x80);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);}void write_addate2(uchar add,uchar date) //定义显示月、日、时、分、秒函数{uchar shi,ge;shi=date/10;ge=date%10;write_com(add+0x80);write_date(0x30+shi);write_date(0x30+ge);}void write_rq(uchar i) //定义显示星期的函数{ uchar x;for(x=0;x<3;x++){ write_date(table2[i][x]);delayms(1);}}void init () //定义初始化函数{dula=0; // 关闭数码管段、位选端wela=0;TMOD=0x01; // 定时器0工作方式为16位TH0=(65536-45872)/256; // 装初值TL0=(65536-45872)%256;EA=1; // 开总中断ET0=1; // 开定时器0中断write_com(0x38); // 设置16*2显示,5*7点阵,8位数据口write_com(0x06); // 写一个字符后地址指针加1write_com(0x0c); // 设置开显示,不显示光标write_com(0x01); // 显示清0,数据清0write_com(0x80); // 使指针指向第1行第1列}void keyscan() // 定义按键函数{uchar keynum;rd=0; //4个按键公共端为低电平if(key1==0) //s4按键被按下{ delayms(3); //去抖延时if(key1==0) //确认s4按键被按下,进入调时间模式{keynum++;while(!key1); //松手检测}if(keynum==1) //s4按下一次{ TR0=0; //关闭定时器0write_com(0x81); //指针指向第1行2列write_com(0x0f); //开启光标显示,光标闪烁}if(keynum==2){write_com(0x86); //光标跳到月份}if(keynum==3){write_com(0x89); //光标跳到日}if(keynum==4){write_com(0x8c); //光标跳到星期}if(keynum==5){write_com(0xc4); //光标跳到时}if(keynum==6){write_com(0xc7); //光标跳到分}if(keynum==7){write_com(0xca); //光标跳到秒}if(keynum==8){ keynum=0; //退出调时间模式TR0=1; //开启定时器0write_com(0x0c); //关闭光标显示}}if(keynum) //当进入调时间模式时{if(key2==0) //s8按键按下{delayms(3); //去抖延时if(key2==0){if(keynum==1){nian++; //s8每按下一次年份加1if(nian==10000) // 加满清0nian=0;write_addate1(1,nian); // 显示年份write_com(0x81); //写完数据指针指向年份原来位置}if(keynum==2){yue++; //s8每按下一次月份加1if(yue==13)yue=0; //加满清0write_addate2(6,yue); //显示月份write_com(0x86); //写完数据指针指向月份原来位置}if(keynum==3){ ri++;if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12) //1,3,5,7,8,10,12月有31天if(ri==32)//加满还原ri=1;if(yue==4||yue==6||yue==9||yue==11) //4,6,9,11月有30天if(ri==31)ri=1;if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0)) //闰年2月有30天if(ri==30)ri=1;if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0)) //非闰年2月有31天if(ri==29)ri=1;write_addate2(9,ri); //显示日write_com(0x89); //写完数据指针指向日原来位置}if(keynum==4){week++;//s8每按下一次星期加1if(week==7)//加满还原week=0;write_rq(week); //显示星期write_com(0x8c); //写完数据指针指向星期原来位置}if(keynum==5){shi++;//s8每按下一次时加1if(shi==24)shi=0;//加满还原write_addate2(0x44,shi); //显示时write_com(0xc4); //写完数据指针指向时原来位置}if(keynum==6){fen++;//s8每按下一次分加1if(fen==60)fen=0;//加满还原write_addate2(0x47,fen); //显示分write_com(0xc7);//写完数据指针指向分原来位置}if(keynum==7){miao++;//s8每按下一次秒加1if(miao==60)miao=0;//加满还原write_addate2(0x4a,miao);//显示秒write_com(0xca);//写完数据指针指向秒原来位置}while(!key2); //松手检测}}if(key3==0){delayms(3);if(key3==0){ //s12按下时减1if(keynum==1){nian--;if(nian==-1)nian=9999;write_addate1(1,nian);write_com(0x81);}if(keynum==2){ yue--;if(yue==-1)yue=12;write_addate2(6,yue);write_com(0x86);}if(keynum==3){ri--;if(ri==0){if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)ri=31;if(yue==4||yue==6||yue==9||yue==11)ri=30;if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))ri=29;if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))ri=28;}write_addate2(9,ri);write_com(0x89);}if(keynum==4){week--;if(week==-1)week=6;write_rq(week);write_com(0x8c);}if(keynum==5){shi--;if(shi==-1)shi=23;write_addate2(0x44,shi);write_com(0xc4);}if(keynum==6){fen--;if(fen==-1)fen=59;write_addate2(0x47,fen);write_com(0xc7);}if(keynum==7){miao--;if(miao==-1)miao=59;write_addate2(0x4a,miao);write_com(0xca);}while(!key3); //松手检测}}}if(key4==0) //s16被按下进入调闹钟模式{ delayms(3);if(key4==0){keynum1++;while(!key4);}if(keynum1==1){ write_com(0x01); //清屏,指针清0write_com(0xc6); //在时分之间显示“:”write_date(':');write_com(0xc9); //在分秒之间显示“:”write_date(':');write_com(0x0f); //开启光标write_com(0xc4); //光标指向时}if(keynum1==2){write_com(0xc7);//光标指向分}if(keynum1==3){write_com(0xca); //光标指向秒}if(keynum1==4){ keynum1=0;write_com(0x0c); //关闭光标}}if(keynum1){if(key2==0) //s8按下加1{delayms(3);if(key2==0){if(keynum1==1){shi1++;if(shi1==24)shi1=0;write_addate2(0x44,shi1);write_com(0xc4);}if(keynum1==2){fen1++;if(fen1==60)fen1=0;write_addate2(0x47,fen1);write_com(0xc7);}if(keynum1==3){miao1++;if(miao1==60)miao1=0;write_addate2(0x4a,miao1);write_com(0xca);}while(!key2);}}if(key3==0) //s12每按一次减1{delayms(3);if(key3==0){if(keynum1==1){shi1--;if(shi1==-1)shi1=23;write_addate2(0x44,shi1);write_com(0xc4);}if(keynum1==2){fen1--;if(fen1==-1)fen1=59;write_addate2(0x47,fen1);write_com(0xc7);}if(keynum1==3){miao1--;if(miao1==-1)miao1=59;write_addate2(0x4a,miao1);write_com(0xca);}while(!key3);//松手检测}}}}void main(){ uchar num;init();for(num=0;num<15;num++){ write_date(table[num]);delayms(5);} //显示初始时间write_com(0xc0);for(num=0;num<12;num++){ write_date(table1[num]);delayms(5);}TR0=1; //开启定时器0while(1){ if(shi==shi1&&fen==fen1&&miao==miao1) //闹钟到了蜂鸣器响beep=0;keyscan(); //扫描键盘}}void time() interrupt 1 //中断函数{TH0=(65536-45872)/256;TL0=(65536-45872)%256; //进入中断装初值num1++;if(num1==20) //一秒到了{ num1=0; //清0miao++;if(miao==60) //一分到了{ miao=0; fen++; }if(!keynum1) write_addate2(0x4a,miao); //当调闹钟模式按下时不显示当前时间if(fen==60){ fen=0;shi++;}if(!keynum1) write_addate2(0x47,fen); //当调闹钟模式按下时不显示当前时间if(shi==24){shi=0;ri++;week++;}if(!keynum1) write_addate2(0x44,shi); //当调闹钟模式按下时不显示当前时间if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)if(ri==32){ ri=1; y ue++; }if(yue==4||yue==6||yue==9||yue==11)if(ri==31){ ri=1; yue++; }if(yue==2&&((nian%4==0&&nian%100!=0)||nian%400==0))if(ri==30){ ri=1; yue++; }if(yue==2&&(nian%4!=0)||(nian%100==0&&nian%400!=0))if(ri==29){ ri=1; yue++; }if(!keynum1) write_addate2(9,ri);//当调闹钟模式按下时不显示当前时间if(week==7)week=0;if(!keynum1)//当调闹钟模式按下时不显示当前时间{ write_com(0x8c);write_rq(week);}if(yue==13){ yue=0;nian++;}if(!keynum1)//当调闹钟模式按下时不显示当前时间{write_addate2(6,yue);write_com(0x88);write_date('-');}if(nian==10000)nian=0;if(!keynum1){ write_addate1(1,nian);//当调闹钟模式按下时不显示当前时间write_com(0x85);write_date('-');}}}。

1602时钟

1602时钟

1602显示,5个按键使用,时间调节,设置闹钟#include<reg52.h>#define uchar unsigned charuchar table[]="2011 0808 Sunday";uchar table1[]=" 00:00:00 ";sbit lcden=P3^4;sbit lcdrs=P3^3;sbit key0=P1^0;sbit key1=P1^1;sbit key2=P1^2;sbit key3=P1^3;sbit key4=P1^4;sbit buzzer=P3^0;void shizhong(uchar add,char date);void keyscan();ucharnum,flag,flag1,flag2,flag3,flag4,flag5,flag6,flag7,flag8,flag9,date,hour,gewei,minute,shiwei,secon d;uchar aa,bb,cc,dd,ee,ff,mm,gg;void delay(uchar x){uchar i,j;for(i=0;i<x;i++)for(j=0;j<110;j++);}void writecom(uchar com){lcdrs=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void writedate(uchar date){lcdrs=1;P2=date;delay(5);lcden=1;delay(5);lcden=0;}void init(){lcden=0;writecom(0x38); // 显示设置writecom(0x0c); // 开显示,不显示光标,光标不闪烁writecom(0x06); // 当读一个字符,光标向后移动一位writecom(0x01); // 显示清0writecom(0x80);for(num=0;num<17;num++){writedate(table[num]);delay(5);}writecom(0x80+0x40);for(num=0;num<10;num++){writedate(table1[num]);delay(5);}}void init1(){EA=1;TMOD=0x01;TH0=(65535-50000)/256;TL0=(65535-50000)%256;ET0=1;// TR0=1;}main(){ init();init1();while(1){keyscan();if(((second==cc)&(minute==bb)&(hour==aa)&mm&&gg)==1) {buzzer=0;}}}void keyscan(){if(key0==0)delay(10);if(key0==0){flag1++;if(flag1==2)flag1=0;while(!key0);// TR0=1;}}if(flag1==0){TR0=0;}if(flag1==1){TR0=1;gg=1;}if(key3==0){delay(10);if(key3==0){hour=minute=second=0;}}if(key4==0){delay(10);if(key4==0){while(!key4);flag9++;if(flag9==2)flag9=0;}}if(flag9==0){if(key1==0){delay(10);if(key1==0){while(!key1);flag2++;if(flag2==7)flag2=1;}}if(flag2==1){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x42);flag3++;if(flag3==10)flag3=0;writedate(0x30+flag3);hour=10*flag3+flag4;hour=0;}}}if(flag2==2){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x43);flag4++;if(flag4==10)flag4=0;writedate(0x30+flag4);hour=10*flag3+flag4;hour=0;}}}if(flag2==3){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x45);flag5++;if(flag5==10)flag5=0;writedate(0x30+flag5);minute=10*flag5+flag6;minute=0;}}}if(flag2==4){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x46);flag6++;if(flag6==10)flag6=0;writedate(0x30+flag6);minute=10*flag5+flag6;minute=0;}}}if(flag2==5){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x48);flag7++;if(flag7==10)flag7=0;writedate(0x30+flag7);second=10*flag7+flag8;second=0;}}}if(flag2==6){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x49);flag8++;if(flag8==10)flag8=0;writedate(0x30+flag8);second=10*flag7+flag8;second=0;}}}}if(flag9==1){mm=1;if(key1==0){delay(10);if(key1==0){while(!key1);flag2++;if(flag2==7)flag2=1;}}if(flag2==1){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x42);flag3++;if(flag3==10)flag3=0;writedate(0x30+flag3);hour=10*flag3+flag4;aa=hour;}}}if(flag2==2){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x43);flag4++;if(flag4==10)flag4=0;writedate(0x30+flag4);hour=10*flag3+flag4;aa=hour;}}}if(flag2==3){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x45);flag5++;if(flag5==10)flag5=0;writedate(0x30+flag5);minute=10*flag5+flag6;bb=minute;}}}if(flag2==4){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x46);flag6++;if(flag6==10)flag6=0;writedate(0x30+flag6);minute=10*flag5+flag6;bb=minute;}}}if(flag2==5){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x48);flag7++;if(flag7==10)flag7=0;writedate(0x30+flag7);second=10*flag7+flag8;cc=second;}}}if(flag2==6){if(key2==0){delay(10);if(key2==0){while(!key2);writecom(0x80+0x49);flag8++;if(flag8==10)flag8=0;writedate(0x30+flag8);second=10*flag7+flag8;cc=second;}}}}//}void Time0() interrupt 1{TH0=(65535-50000)/256;TL0=(65535-50000)%256;flag++;if(flag==20){flag=0;second++;if(second==60){second=0;minute++;if(minute==60){minute=0;hour++;if(hour==24){hour=0;}shizhong(2,hour);}shizhong(5,minute);}shizhong(8,second);}}void shizhong(uchar add,char date){writecom(0x80+0x40+add);shiwei=date/10;gewei=date%10;writedate(0x30+shiwei);writedate(0x30+gewei);}。

1602电子时钟电路_原理图_PCB图

1602电子时钟电路_原理图_PCB图

1602电子时钟电路_原理图_PCB图一、引言电子时钟作为现代生活中常见的时间显示设备,广泛应用于各个领域。

本篇文章将着重介绍1602电子时钟的电路原理图和PCB设计图,旨在让读者了解该电子时钟的工作原理和实现方法。

二、电路原理图1602电子时钟的电路主要由以下几个模块组成:时钟源、微处理器、液晶显示屏和按键控制模块。

下面将对每个模块进行详细的介绍。

1. 时钟源模块时钟源模块是电子时钟的核心,用于提供准确的时间信号。

常见的时钟源模块有晶振和RTC(实时时钟)芯片。

晶振通常使用32.768kHz的石英晶体,通过振荡脉冲产生稳定的时间基准。

而RTC芯片则内部集成了时钟电路,能够提供准确的时间信号。

2. 微处理器模块微处理器模块负责控制整个电子时钟的运行。

常用的微处理器有单片机和微控制器。

单片机通常具有丰富的外设接口和可编程功能,适用于复杂的时钟控制需求。

而微控制器则在单芯片上集成了微处理器核心、存储器和外设接口,更加简易和紧凑。

3. 液晶显示屏模块液晶显示屏模块用于将时间信息以数字形式显示出来。

1602液晶显示屏是基于字符型液晶显示技术,具有两行十六个字符的显示能力。

其工作原理是通过外部电压的作用,控制液晶分子的排列来实现显示效果。

4. 按键控制模块按键控制模块允许用户通过按键来设定和调整电子时钟的功能和显示参数。

它通常包括多个按键、键盘扫描接口和按键控制电路。

三、PCB图设计PCB图是电子时钟电路的物理实现图,能够直观地显示所有元器件之间的连接和布局关系。

本节将介绍1602电子时钟的PCB图设计过程。

1. 元器件布局在PCB设计之前,需要对各个元器件进行布局。

首先,将时钟源模块与微处理器模块放置在一起,以便于时钟信号的输入和处理。

其次,根据液晶显示屏的位置要求,将其与微处理器模块相连接。

最后,将按键控制模块与微处理器模块相连,并设置按键的位置。

2. 连接导线通过导线将各个元器件进行连接。

导线的设计应考虑信号的传输距离、屏蔽和抗干扰等因素,以保证电子时钟的稳定性和可靠性。

1602显示简易电子时钟,可按键调整时间

1602显示简易电子时钟,可按键调整时间

#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit RS=P2^6;sbit RW=P2^5;sbit lcden=P2^7;sbit s1=P1^1; //功能键sbit s2=P1^2; //加一键sbit s3=P1^3; //减一键sbit a=P1^4;sbit c1=P2^0; //功能键sbit c2=P2^1; //加一键sbit c3=P2^2; //减一键uchar count,s1num,c1num,i,j;char nian,yue,ri,shi,fen,miao;uchar code table[]=" 2011-08-18 THU";uchar code table1[]=" 23:59:53";uchar code week1[]="MON";uchar code week2[]="TUE";uchar code week3[]="WED";uchar code week4[]="THU";uchar code week5[]="FRI";uchar code week6[]="SAT";uchar code week7[]="SUN";/*****************************************************************************/ void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=250;y>0;y--);}/*****************************************************************************/ void write_com(uchar com) //写指令{RS=0;RW=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}/*****************************************************************************/void write_date(uchar date) //写数据{RS=1;RW=0;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}/*****************************************************************************/ void init(){uchar num;lcden=0;write_com(0x38); //显示模式设置write_com(0x0c); //显示开关write_com(0x06); //显示光标设置write_com(0x01); //显示清零write_com(0x80);for(num=0;num<16;num++){write_date(table[num]);delay(20);}write_com(0x80+0x40);for(num=0;num<13;num++){write_date(table1[num]);delay(20);}TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}/*****************************************************************************/ void write_sfm(uchar add,uchar date) //秒,分,时计算{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}/*****************************************************************************/ void write_nyr(uchar add,uchar date) //月,日计算{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}/*****************************************************************************/ /*void write_nian(uchar add,uchar date) //千位计算{uchar shi,ge;// bai=date%1000/100;shi=date%100/10;ge=date%10;write_com(0x80+add);// write_date(0x30+qian);// write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);} *//*****************************************************************************/ void keyscan() //判断按键函数{a=0;if(s1==0) //判断功能键是否被按下{delay(5); //消抖if(s1==0){s1num++;while(!s1); //松手检测if(s1num==1) //功能键被按下一次{TR0=0; //时间停止write_com(0x80+0x40+12); //光标向前移一位write_com(0x0f); //光标闪烁}if(s1num==2) //功能键被按下两次{write_com(0x80+0x40+9);}if(s1num==3) //功能键被按下三次{write_com(0x80+0x40+6);}if(s1num==4) //功能键被按下四次{s1num=0;write_com(0x0c); //让光标不在闪烁TR0=1;}}}if(s1num!=0) //判断功能键是否被按下{if(s2==0) //判断加一键是否被按下{delay(5);if(s2==0) //确认加一键被按下{while(!s2);if(s1num==1) //判断指针指向“秒"{miao++;if(miao==60)miao=0;write_sfm(11,miao);write_com(0x80+0x40+11);}if(s1num==2) //判断指针指向“分"{fen++;if(fen==60)fen=0;write_sfm(8,fen);write_com(0x80+0x40+8);}if(s1num==3) //判断指针指向“时"{shi++;if(shi==24)shi=0;write_sfm(5,shi);write_com(0x80+0x40+5);}}}if(s3==0) //判断减一键是否被按下{delay(5);if(s3==0){while(!s3);if(s1num==1) //判断指针指向“秒"{miao--;if(miao==-1)miao=59;write_sfm(11,miao);write_com(0x80+0x40+11);}if(s1num==2) //判断指针指向“分"{fen--;if(fen==-1)fen=59;write_sfm(8,fen);write_com(0x80+0x40+8);}if(s1num==3) //判断指针指向“时"{shi--;if(shi==-1)shi=23;write_sfm(5,shi);write_com(0x80+0x40+5);}}}}}/*****************************************************************************/ void keyscan1() //调整日期{if(c1==0){delay(5);if(c1==0){c1num++;while(!c1);if(c1num==1) //指向”星期“{TR0=0; //时间停止write_com(0x80+15); //光标向前移一位write_com(0x0f); //光标闪烁}if(c1num==2) //指向”日“{write_com(0x80+11);}if(c1num==3) //指向”月“{write_com(0x80+8);}if(c1num==4) //指向”年“{write_com(0x80+5);}if(c1num==5){c1num=0;write_com(0x0c); //让光标不在闪烁TR0=1;}}}if(c1num!=0) //判断功能键是否被按下{if(c2==0) //判断加一键是否被按下{delay(5);if(c2==0) //防抖{while(!c2); //松手检测if(c1num==1) //指向“星期”{i++;if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}if(c1num==2) //指向”日“{ri++;if(ri==32)ri=1;write_nyr(10,ri);write_com(0x80+10);}if(c1num==3) //指向”月“{yue++;if(yue==13)yue=1;write_nyr(7,yue);write_com(0x80+7);}if(c1num==4) //指向”年“{nian++;write_nyr(4,nian);write_com(0x80+4);}}}if(c3==0) //减一功能键按{delay(5);if(c3==0){while(!c3);if(c1num==1) //指向“星”{i++;if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}if(c1num==2) //指向“日”{ri--;if(ri==0)ri=31;write_nyr(10,ri);write_com(0x80+10);}if(c1num==3) //指向“月”{yue--;if(yue==0)yue=12;write_nyr(7,yue);write_com(0x80+7);}if(c1num==4) //指向“年”{nian--;write_nyr(4,nian);write_com(0x80+4);}}}}}/*****************************************************************************/ void main(){init();while(1){keyscan();keyscan1();if(count==20) //定时1秒{count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;ri++;i++;if(ri==32){ri=1;yue++;if(yue==13){yue=1;nian++;write_nyr(3,nian);}write_nyr(7,yue);}write_nyr(10,ri);if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}write_sfm(5,shi);}write_sfm(8,fen);}write_sfm(11,miao);}}}/*****************************************************************************/ void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;}。

单片机LCD1602显示年月日时钟带星期和闹钟

单片机LCD1602显示年月日时钟带星期和闹钟

单片机LCD1602显示年月日时钟带星期和闹钟长春工业大学测控技术与仪器专业单片机LCD1602显示年月日时钟带星期和闹钟,可识别闰年下载文档即可完全复制#include#define uchar unsigned char#define uint unsigned intsbit lcdrs = P0^7; //液晶引脚定义sbit led_cs = P0^6;sbit lcden = P0^5;sbit boom = P3^6;sbit key1 = P3^5;sbit key2 = P3^4;sbit key3 = P3^3;sbit keyE = P3^2;ucharnum,key1num,key2num,count,hour,min,sec,day,mon,year,shi ,fe n,miao,week;char ye1,ye2;uchar code cg_1602[]={ 0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02, 0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00,0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,};//"年月日"/*延时函数*/void delay(uint xms){uint i,j;for(i=xms;i>0;i--)for(j=114;j>0;j--);}/*1602液晶*/void write_com(uchar com)//写命令{ lcdrs=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date)//写数据{ lcdrs=1;lcden=0;P2=date;delay(5);lcden=1;delay(5);lcden=0;}void write_by_xy(uchar x,uchar y)//坐标定位{uchar address;if(y==0)address=0x80+x;//y=0,写第一行elseaddress=0xc0+x;//y=1,写第二行write_com(address);}/*void write_char(uchar x,uchar y,uchar date)//坐标定位显示{ write_by_xy(x,y);//先定位write_data(date);//后写数}*/void write_string(uchar x,uchar y,uchar *s)//写字符串{write_by_xy(x,y);//设定显示位置while(*s)//write character{P2=*s;s++;}}void write_sfm(uchar add,uchar date)//写时分秒函数{uchar hour,ge;hour=date/10;//分解一个2位数的十位和个位ge=date%10;write_com(0x80+add);//设置显示位置write_data(0x30+hour);//送去液晶显示十位write_data(0x30+ge); //送去液晶显示个位}void write_cg()//写入固定汉字和符号{write_com(0x40); //设定CGRAM地址for(num=0;num<24;num++) //将自定义字型码写入CGRAM 中{write_data(cg_1602[num]);}write_com(0xc4);//年{}write_com(0xc7);//月{write_data(1);}write_com(0xca);//日{write_data(2);}write_string(2,0,":");write_string(5,0,":");write_string(0x0a,0,":");write_string(0x0d,0,":");write_string(0x0c,1,"W");write_string(0x0d,1,"K");}void init_1602()//初始化{led_cs=0;hour=23;min=59;sec=55;key1num=0;count=0;day=28;mon =2;ye1=20;ye2=13;year=ye1*100+ye2;boom=0;shi=0;fen=0;miao=0; wee。

1602液晶显示电子钟时间C程序

1602液晶显示电子钟时间C程序

#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit key1=P2^3;sbit key2=P2^4;sbit key3=P2^5;void delay(void);void init(void);void wc51r(uchar i);void wc51ddr(uchar i);void fbusy(void);void LCD_xianshi(void);void delay_zs(uint z);void tiaoshi(void);uchar hour,hour1,min,min1,sec,sec1,aa,bb,num1,num2,num3,flag;uchar year1,year2,year3,year4,month,month1,month2,day,day1,day2; unsigned int year;uchar tab[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};void main(){init();while(1){LCD_xianshi();}}void init(){// key1=1;key2=1;key3=1;num1=12;year=2010;month=11;day=15;// wc51r(0x01);wc51r(0x38);wc51r(0x0c);wc51r(0x06);TMOD=0x01; //工作方式1TH0=(65536-5000)/256; //定时器高位装初值计数溢出一次为50ms TL0=(65536-5000)%256; //定时器低位装初值EA=1; //CPU开中断ET0=1; //允许T0中断// ET1=1;TR0=1; //启动T0工作// TR1=1;}void fbusy(){RW=1;RS=0;E=1;while(!P1&0x80);E=0;delay();}void wc51r(uchar j){fbusy();E=0;RS=0;RW=0;E=1;P1=j;E=0;delay();}void wc51ddr(uchar j){fbusy();E=0;RS=1;RW=0;E=1;P1=j;E=0;delay();}void delay(){uchar i,j;for(j=0;j<10;j++)for(i=0;i<10;i++);}/*void delay_zs(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}*/void LCD_xianshi(){year1=year/1000;year2=year/100%10;year3=year%100/10;year4=year%10;month1=month/10;month2=month%10;day1=day/10;day2=day%10;hour=num1/10;hour1=num1%10;min=num2/10;min1=num2%10;sec=num3/10;sec1=num3%10;wc51r(0x84); //起始地址为第1行第1列,0x85为第1行第6列;0xc0为第2行第1列wc51ddr(tab[hour]); //显示1wc51ddr(tab[hour1]); //显示2wc51ddr(0x3a); //显示:wc51ddr(tab[min]); //显示0wc51ddr(tab[min1]); //显示0wc51ddr(0x3a); //显示:wc51ddr(tab[sec]);wc51ddr(tab[sec1]);wc51r(0xc3);wc51ddr(tab[year1]);wc51ddr(tab[year2]);wc51ddr(tab[year3]);wc51ddr(tab[year4]);wc51ddr('-');wc51ddr(tab[month1]);wc51ddr(tab[month2]);wc51ddr('-');wc51ddr(tab[day1]);wc51ddr(tab[day2]);}/*void tiaoshi(void){while(key1){TR0=0;if(key2==0){LCD_xianshi;num3++;if(num3==60){num3=0;num2++;}}else if(key3==0)num2++;}// while(key1);// if(key1==0){ET0=1;TR0=1;flag=0;}}*///************************定时器中断程序**************************// void timer0() interrupt 1{TH0=(65536-50000)/256; //重装计数初值TL0=(65536-50000)%256;aa++;if(aa==20) //计数20次后恰为20x50ms==1s{aa=0;num3++; //秒加1if(num3==60) //秒计数到60后清零{num3=0;num2++;if(num2==60){num2=0;num1++;if(num1==24){num1=0;day++;if(month%2==0){if(day==31){day=0;month++;if(month==13){month=0;year++;}}}else if(month%2==1){if(day==32){day=0;month++;if(month==13){month=0;year++;}}}}}}}}//************************定时器中断程序**************************// /*void timer1() interrupt 3{TH1=(65536-50000)/256; //重装计数初值TL1=(65536-50000)%256;bb++;if(bb%20==0){if(key1==0){ET0=0;TR0=0;flag=1;}}}*/#include <msp430g2452.h>unsigned char table[] ={"0123456789"};unsigned char hanzi1[8]={0x04,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02};//年 unsigned char hanzi2[8]={0x0f,0x09,0x0f,0x09,0x0f,0x09,0x13,0x11};//月 unsigned char hanzi3[8]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00};//日unsigned char num;void delay_1ms(void){unsigned int i;for (i=0;i<1140;i++);}void delay_nms(unsigned int n){unsigned int i=0;for (i=0;i<n;i++)delay_1ms();}void write_com(unsigned int com){//lcdrs = 0;P2OUT&= 0xfd; P1OUT = com; delay_nms(5); //lcden = 1;P2OUT|= 0x01; delay_nms(5); P2OUT&= 0xfe; }void write_dat(unsigned int dat) {//lcdrs = 1;P2OUT |= 0x02; P1OUT = dat; delay_nms(5); //lcden=1;P2OUT|= 0x01; delay_nms(5); // lcden=0;P2OUT&= 0xfe; }void init() {write_com(0x38);// write_com(0x0f);// write_com(0x01);// write_com(0x06);// // write_com(0x07);//整屏移动 delay_nms(10); }void CGRAM_LCD(unsigned char *hz,unsigned char temp) {unsigned char s; for(s=0;s<8;s++) {write_com(temp+s);write_dat(*(hz+s)); } }void main(void) {WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= 0xff; // P1.2 output P2DIR |= 0xff; init();CGRAM_LCD(hanzi1,0x40); CGRAM_LCD(hanzi2,0x48); CGRAM_LCD(ha nzi3,0x50);write_com(0x80); write_dat(table[2]); delay_nms(100);write_com(0x80+0x01); write_dat(table[0]); delay_nms(100);write_com(0x80+0x02); write_dat(table[1]); delay_nms(100);write_com(0x80+0x03); write_dat(table[2]);delay_nms(100);write_com(0x80+0x04); write_dat(0); delay_nms(100);write_com(0x80+0x06); write_dat(table[6]); delay_nms(100);write_com(0x80+0x07); write_dat(1); delay_nms(100);write_com(0x80+0x09); write_dat(table[2]); delay_nms(100);write_com(0x80+0x0a); write_dat(2); while(1); }。

可调时钟1602显示且附带智能闹钟且附带日期

可调时钟1602显示且附带智能闹钟且附带日期
typedef unsigned char u8;
typedef unsigned int u16;
sbit LCD_RS=P3^5;
sbit LCD_WR=P3^6;
sbit LCD_EN=P3^4;
sbit spk=P1^7;
sbit DRX=P3^0;
while(!adj);//直到按键抬起
}
}
}
void dis_time()
{
u8 i;
while(LCD_BUSY()); //读忙
WRITE_COM(0x80); //设置初始操作地址
while(LCD_BUSY());
{for(i=0;i<5;i++)
beep();
}
}
void adj_scan()
{
if(!adj)
{
delay(10);//消抖
if(!adj)
{
beep();
flag++;
if(flag==1)//第一次按调时
}
void alarm_scan()
{
if(!alarm)
{
delay(10);
if(!alarm)
{
alarm_flag=1;
beep();
TR0=0;
sav_hour=hour;sav_min=min;sav_sec=sec;//暂存设定闹钟前的时间
TR1=1;//用于存储设置时钟过程损耗时长的T2定时器启动
flag++;
if(flag==1)//第一次按调时

lcd1602液晶显示数字钟

lcd1602液晶显示数字钟

{
time[1]=0;//超过,分清零
time[0]++;//小时加1
if(time[0]>23)//是否超过23
{
time[0]=0; //小时清零
•}

}
时间计算
• void main(void)
•{

uchar i;


while(1)

{
• 计时
for(i=0;i<250;i++)//循环调用显示程序250次,实现1秒
display_code[]={0x3f,0x60,0x5b,0x4 f,0x66,0x5d,0x7d,0x07,0x7f,0x6f,0x 40}; • uchar time[4]={0,0,0,0}; //时间初 值全为0
• void delay(void);//延时0.5毫秒 •{
定时1秒
• uchar i;
• for(i=250;i>0;i--);
•}
• void display()
/*程序用于P0口接数码管的断码,P2接数码管的位码*/
•{

uchar i,k;

k=0x80;
//k初始化,指向第一位数码管

for(i=0;i<8;i++) //循环8次,i值为0~7

{

P2=0;
//关闭显示

P0=display_code[time[i]/10]; //输出十位数的断码


{

display();//调用动态显示,动态显示一次约4毫秒

}

单片机LCD1602显示年月日时钟带星期和闹钟

单片机LCD1602显示年月日时钟带星期和闹钟

长春工业大学测控技术与仪器专业单片机LCD1602显示年月日时钟带星期和闹钟,可识别闰年下载文档即可完全复制#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit lcdrs = P0^7; //液晶引脚定义sbit led_cs = P0^6;sbit lcden = P0^5;sbit boom = P3^6;sbit key1 = P3^5;sbit key2 = P3^4;sbit key3 = P3^3;sbit keyE = P3^2;ucharnum,key1num,key2num,count,hour,min,sec,day,mon,year,shi,f en,miao,week;char ye1,ye2;uchar code cg_1602[]={ 0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00,0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,};//"年月日"/*延时函数*/void delay(uint xms){uint i,j;for(i=xms;i>0;i--)for(j=114;j>0;j--);}/*1602液晶*/void write_com(uchar com)//写命令{lcdrs=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date)//写数据{lcdrs=1;lcden=0;P2=date;delay(5);lcden=1;delay(5);lcden=0;}void write_by_xy(uchar x,uchar y)//坐标定位{uchar address;if(y==0)address=0x80+x;//y=0,写第一行elseaddress=0xc0+x;//y=1,写第二行write_com(address);}/*void write_char(uchar x,uchar y,uchar date)//坐标定位显示{write_by_xy(x,y);//先定位write_data(date);//后写数}*/void write_string(uchar x,uchar y,uchar *s)//写字符串{write_by_xy(x,y);//设定显示位置while(*s)//write character{P2=*s;write_data(*s);s++;}}void write_sfm(uchar add,uchar date)//写时分秒函数{uchar hour,ge;hour=date/10;//分解一个2位数的十位和个位ge=date%10;write_com(0x80+add);//设置显示位置write_data(0x30+hour);//送去液晶显示十位write_data(0x30+ge); //送去液晶显示个位}void write_cg()//写入固定汉字和符号{write_com(0x40); //设定CGRAM地址for(num=0;num<24;num++) //将自定义字型码写入CGRAM 中{write_data(cg_1602[num]);}write_com(0xc4);//年{write_data(0);}write_com(0xc7);//月{write_data(1);}write_com(0xca);//日{write_data(2);}write_string(2,0,":");write_string(5,0,":");write_string(0x0a,0,":");write_string(0x0d,0,":");write_string(0x0c,1,"W");write_string(0x0d,1,"K");}void init_1602()//初始化{led_cs=0;hour=23;min=59;sec=55;key1num=0;count=0;day=28;mon =2;ye1=20;ye2=13;year=ye1*100+ye2;boom=0;shi=0;fen=0;m iao=0;week=7;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_string(0,1,"2013");write_string(5,1,"02");write_string(8,1,"28");write_sfm(8,shi);write_sfm(0x0b,fen);write_sfm(0x0e,miao);write_sfm(0,hour);write_sfm(3,min);write_sfm(6,sec);write_sfm(0x48,day);write_sfm(0x45,mon);write_sfm(0x40,ye1);write_sfm(0x42,ye2);write_sfm(0x4e,week);write_cg();TMOD=0x01;//设置定时器0工作模式1 TH0=(65536-50000)/256;//定时器装初值TL0=(65536-50000)%256;EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; //启动定时器0}/*键盘扫描函数*/void keyscan()//按键扫描函数{//keyE =0;if(key1==0){delay(5);if(key1==0)//确认功能键被按下{key1num++;//功能键按下次数记录while(!key1);//释放确认if(key1num==1)//第一次被按下时TR0=0; //关闭定时器write_com(0x80+7);//光标定位到秒位置write_com(0x0f); //光标开始闪烁}if(key1num==2)//第二次按下光标闪烁定位到分钟位置{write_com(0x80+4);}if(key1num==3)//第三次按下光标闪烁定位到小时位置{write_com(0x80+1);}if(key1num==4)//第四次按下光标闪烁定位到日位置{write_com(0x80+0x49);}if(key1num==5)//第五次按下光标闪烁定位到月位置{write_com(0x80+0x46);}if(key1num==6)//第六次按下光标闪烁定位到年2位置write_com(0x80+0x43);}if(key1num==7)//第七次按下光标闪烁定位到年1位置{write_com(0x80+0x41);}if(key1num==8)//第八次按下光标闪烁定位到星期位置{write_com(0x80+0x4f);}if(key1num==9)//第九次按下{key1num=0;//记录按键数清零write_com(0x0c);//取消光标闪烁TR0=1; //启动定时器使时钟开始走}}}if(key1num!=0)//只有功能键被按下后,增加和减小键才有效{if(key2==0){delay(5);if(key2==0)//增加键确认被按下{while(!key2);//按键释放if(key1num==1)//若功能键第一次按下{sec++; //则调整秒加1if(sec==60)//若满60后将清零sec=0;write_sfm(6,sec);//每调节一次送液晶显示一下write_com(0x80+7);//显示位置重新回到调节处}if(key1num==2)//若功能键第二次按下{min++;//则调整分钟加1if(min==60)//若满60后将清零min=0;write_sfm(3,min);//每调节一次送液晶显示一下write_com(0x80+4);//显示位置重新回到调节处}if(key1num==3)//若功能键第三次按下{hour++;//则调整小时加1if(hour==24)//若满24后将清零hour=0;write_sfm(0,hour);;//每调节一次送液晶显示一下write_com(0x80+1);//显示位置重新回到调节处}if(key1num==4)//若功能键第四次按下{day++;//则调整日加1if(day>31)//若大于31后将置一day=1;write_sfm(0x48,day);//每调节一次送液晶显示一下write_com(0x80+0x48);//显示位置重新回到调节处}if(key1num==5)//若功能键第五次按下{mon++;//则调整月加1if(mon>12)//若大于12后将置一mon=1;下write_com(0x80+0x45);//显示位置重新回到调节处}if(key1num==6)//若功能键第六次按下{ye2++;//则调整年加1if(ye2==0x0a)//若满99后将清零ye2=0;year=ye1*100+ye2;write_sfm(0x42,ye2);//每调节一次送液晶显示一下write_com(0x80+0x42);//显示位置重新回到调节处}if(key1num==7)//若功能键第七次按下{ye1++;//则调整年加100if(ye1==0x0a)//若满99后将清零ye1=0;year=ye1*100+ye2;下write_com(0x80+0x40);//显示位置重新回到调节处}if(key1num==8)//若功能键第八次按下{week++;//则调整周加一if(week>7)//若大于7后置一week=1;write_sfm(0x4f,week);//每调节一次送液晶显示一下write_com(0x80+0x4f);//显示位置重新回到调节处}}}if(key3==0){delay(5);if(key3==0)//确认减小键被按下{while(!key3);//按键释放if(key1num==1)//若功能键第一次按下{sec--;//则调整秒减1if(sec==-1)//若减到负数则将其重新设置为59 sec=59;write_sfm(6,sec);//每调节一次送液晶显示一下write_com(0x80+7);//显示位置重新回到调节处}if(key1num==2)//若功能键第二次按下{min--;//则调整分钟减1if(min==-1)//若减到负数则将其重新设置为59 min=59;write_sfm(3,min);//每调节一次送液晶显示一下write_com(0x80+4);//显示位置重新回到调节处}if(key1num==3)//若功能键第三次按下{hour--;//则调整小时减1if(hour==-1)//若减到负数则将其重新设置为23 hour=23;write_sfm(0,hour);//每调节一次送液晶显示一下write_com(0x80+1);//显示位置重新回到调节处}if(key1num==4)//若功能键第四次按下{day--;//则调整日减1if(day==0)//若日为零时将置一day=31;write_sfm(0x48,day);//每调节一次送液晶显示一下write_com(0x80+0x49);//显示位置重新回到调节处}if(key1num==5)//若功能键第五次按下{mon--;//则调整月减1if(mon==0)//若月为零将置一mon=12;write_sfm(0x45,mon);//每调节一次送液晶显示一下write_com(0x80+0x45);//显示位置重新回到调节处if(key1num==6)//若功能键第六次按下{ye2--;//则调整年减1if(ye2<0)//若小于零后将设置为99ye2=99;year=ye1*100+ye2;write_sfm(0x42,ye2);//每调节一次送液晶显示一下write_com(0x80+0x42);//显示位置重新回到调节处}if(key1num==7)//若功能键第七次按下{ye1--;//则调整年减100if(ye1<0)//若小于零后将设置为99ye1=99;year=ye1*100+ye2;write_sfm(0x40,ye1);//每调节一次送液晶显示一下write_com(0x80+0x40);//显示位置重新回到调节处if(key1num==8)//若功能键第八次按下{week--;//则调整周减一if(week==0)//若等于0后将置7week=7;write_sfm(0x4f,week);//每调节一次送液晶显示一下write_com(0x80+0x4f);//显示位置重新回到调节处}}}}if(keyE==0){delay(5);if(keyE==0)//确认功能键被按下{key2num++;//功能键按下次数记录while(!keyE);//释放确认if(key2num==1)//第一次被按下时{TR0=0; //关闭定时器write_com(0x80+0x0f);//光标定位到秒位置write_com(0x0f); //光标开始闪烁}if(key2num==2)//第二次按下光标闪烁定位到分钟位置{write_com(0x80+0x0c);}if(key2num==3)//第三次按下光标闪烁定位到小时位置{write_com(0x80+9);}if(key2num==4)//第八次按下{key2num=0;//记录按键数清零write_com(0x0c);//取消光标闪烁TR0=1; //启动定时器使时钟开始走}}}if(key2num!=0)//只有功能键被按下后,增加和减小键才有效{if(key2==0){delay(5);if(key2==0)//增加键确认被按下{while(!key2);//按键释放if(key2num==1)//若功能键第一次按下{miao++; //则调整秒加1if(miao==60)//若满60后将清零miao=0;write_sfm(0x0e,miao);//每调节一次送液晶显示一下write_com(0x80+0x0e);//显示位置重新回到调节处}if(key2num==2)//若功能键第二次按下{fen++;//则调整分钟加1if(fen==60)//若满60后将清零fen=0;write_sfm(0x0b,fen);//每调节一次送液晶显示一下write_com(0x80+0x0b);//显示位置重新回到调节处}if(key2num==3)//若功能键第三次按下{shi++;//则调整小时加1if(shi==24)//若满24后将清零shi=0;write_sfm(8,shi);;//每调节一次送液晶显示一下write_com(0x80+8);//显示位置重新回到调节处}}}if(key3==0){delay(5);if(key3==0)//确认减小键被按下{while(!key3);//按键释放if(key2num==1)//若功能键第一次按下{miao--;//则调整秒减1if(miao==-1)//若减到负数则将其重新设置为59miao=59;write_sfm(0x0e,miao);//每调节一次送液晶显示一下write_com(0x80+0x0e);//显示位置重新回到调节处}if(key2num==2)//若功能键第二次按下{fen--;//则调整分钟减1if(fen==-1)//若减到负数则将其重新设置为59fen=59;write_sfm(0x0b,fen);//每调节一次送液晶显示一下write_com(0x80+0x0b);//显示位置重新回到调节处}if(key2num==3)//若功能键第三次按下{shi--;//则调整小时减1if(shi==-1)//若减到负数则将其重新设置为23shi=23;write_sfm(8,shi);//每调节一次送液晶显示一下write_com(0x80+8);//显示位置重新回到调节处}}}}}/*主函数*/void main(){led_cs=0;init_1602();while(1){keyscan();}}/*中断函数*/void timer0() interrupt 1//定时器0中断服务程序{TH0=(65536-50000)/256;//再次装定时器初值TL0=(65536-50000)%256;count++; //中断次数累加if(count==20) //20次50毫秒为1秒{count=0;sec++;if(sec==60)//秒加到60则进位分钟{sec=0;//同时秒数清零min++;if(min==60)//分钟加到60则进位小时{min=0;//同时分钟数清零hour++;//boom=1;//delay(5);//boom=0;if(hour==24)//小时加到24则小时清零{hour=0;week++;if(week>7){week=1;}if(mon==1){if(day>31){day=1;mon++;}}if(mon==2){if((year%4==0 && year%100!=0)||year%4==0){if(day>29){day=1;}}else if(day>28) {day=1;mon++;}}if(mon==3) {if(day>31) {day=1;mon++;}}if(mon==4) {if(day>30) {day=1;}}if(mon==5) {if(day>31) {day=1; mon++;}}if(mon==6) {if(day>30) {day=1; mon++;}}if(mon==7) {if(day>31){day=1; mon++;}}if(mon==8) {if(day>31) {day=1; mon++;}}if(mon==9) {if(day>30) {day=1; mon++;}}if(mon==10) {if(day>31) {day=1; mon++;}}if(mon==11) {if(day>30) {day=1; mon++;}}if(mon==12) {if(day>31) {day=1; mon=1;ye2++;}}}write_sfm(0x4e,week);write_sfm(0x48,day);write_sfm(0x45,mon);write_sfm(0x40,ye1);write_sfm(0x42,ye2);}write_sfm(0,hour);//小时若变化则重新写入}write_sfm(3,min);//分钟若变化则重新写入}write_sfm(6,sec); //秒若变化则重新写入if((hour==shi && min==fen) && sec==miao) {boom=1;delay(5);boom=0;}}。

单片机实验报告 ——LCD1602显示时钟

单片机实验报告 ——LCD1602显示时钟

XXXX学院实验报告Experimentation Report of Taiyuan Normal University系部计算机年级大三课程单片机原理与接口技术姓名同组者日期学号项目 LCD1602显示时钟一、实验目的1、了解单片机顺序执行的特点;2、掌握C语言的编写和keilc51的使用;3、熟悉DS1302芯片的工作过程二、实验仪器硬件资源:单片机开发板笔记本电脑 DS1302芯片;软件资源:软件 Keil uVision5;三、实验原理1、流程图2、连接图四、实验结果将LCD屏连接到单片机上,点击编译运行,LCD屏上显示时间:2013-01-01 2 12-00-38。

在DS1302.c文件里修改uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01,0x02, 0x13};为uchar TIME[7] = {0x14, 0x11, 0x19, 0x28, 0x11,0x04, 0x19};点击编译运行按钮,LCD屏幕显示2019-11-28 4 19-11-14。

四、实验代码及分析//主函数void main(){Ds1302Init(); //初始化DS1302LcdInit(); //初始化LCDwhile(1){Ds1302ReadTime(); //DS1302读时间LcdDisplay(); //LCD显示时间}}//初始化DS1302void Ds1302Init(){uchar n;Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能for (n=0; n<7; n++) //写入7个字节的时钟信号:分秒时日月周年{Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80); //打开写保护功能}//读取时钟信息void Ds1302ReadTime(){uchar n;for (n=0; n<7; n++) //读取7个字节的时钟信号:分秒时日月周年{TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);}}//---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。

基于单片机的1602电子时钟设计

基于单片机的1602电子时钟设计

基于单片机的1602电子时钟设计一.实验目的:(1)用单片机设计基于单片机的1602电子时钟显示;(2)熟练掌握Keil软件;(3)熟练掌握Proteus软件仿真;(4)掌握单片机的I/O接口的工作原理;(5)掌握LCD显示器的原理和编程方法;(6)掌握独立式键盘的工作原理和编程方法;(7)掌握单片机下载方法;二.实验要求(1)可实现时钟显示(2)可调整时间三.实验内容(1)画仿真图如图1图1(2)编写程序(3)下载运行(4)运行结果,分析其中的错误四.程序(一)#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^0;sbit LCD_RW=P2^1 ;sbit LCD_EN=P2^2;void Delay_ms(uint xms) ;bit lcd_busy();void lcd_wcmd(uchar cmd);void lcd_wdat(uchar dat) ;void lcd_clr() ;void lcd_init() ;/********以下是延时函数********/void Delay_ms(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒for(j=110;j>0;j--);}/********以下是LCD忙碌检查函数********/bit lcd_busy(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;_nop_(); _nop_(); _nop_(); _nop_();result = (bit)(P0&0x80);LCD_EN = 0;return result;}/********以下是写指令寄存器IR函数********/void lcd_wcmd(uchar cmd){while(lcd_busy());LCD_RS = 0; LCD_RW = 0; LCD_EN = 0;_nop_(); _nop_();P0 = cmd;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 1;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 0;}/********以下是写寄存器DR函数********/void lcd_wdat(uchar dat){while(lcd_busy());LCD_RS = 1; LCD_RW = 0; LCD_EN = 0;P0 = dat;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 1;_nop_(); _nop_(); _nop_(); _nop_();LCD_EN = 0;}/********以下是LCD清屏函数********/void lcd_clr(){lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}/********以下是LCD初始化函数********/void lcd_init(){Delay_ms(15); //等待LCD电源稳定lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x0c); //显示开,关光标Delay_ms(5);lcd_wcmd(0x06); //移动光标Delay_ms(5);lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}(二)#include <reg51.h>#include "LCD_drive.h"#define uchar unsigned char#define uint unsigned intuchar year=12,mon=10,day=10,hour=12,min=00,sec=00;uchar count_10ms;sbit k7=P3^0; sbit k1=P3^2; sbit k2=P3^3; sbit k3=P3^4;sbit k4=P3^5; sbit k5=P3^6; sbit k6=P3^7; bit k1_flag=0;uchar code line1_data[] = {"----"};uchar code line2_data[] = {"****"};uchardisp_buf[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; void LCD_conv(char in1,in2,in3,in4,in5,in6){disp_buf[0]=in1/10+0x30; disp_buf[1]=in1%10+0x30; disp_buf[2]=in2/10+0x30; disp_buf[3]=in2%10+0x30; disp_buf[4]=in3/10+0x30; disp_buf[5]=in3%10+0x30; disp_buf[6]=in4/10+0x30; disp_buf[7]=in4%10+0x30; disp_buf[8]=in5/10+0x30; disp_buf[9]=in5%10+0x30; disp_buf[10]=in6/10+0x30; disp_buf[11]=in6%10+0x30; }void LCD_disp(){lcd_wcmd(0x04|0x80);lcd_wdat(disp_buf[0]); lcd_wdat(disp_buf[1]);lcd_wdat(0xb0);lcd_wdat(disp_buf[2]); lcd_wdat(disp_buf[3]);lcd_wdat(0xb0);lcd_wdat(disp_buf[4]); lcd_wdat(disp_buf[5]);lcd_wcmd(0x44|0x80);lcd_wdat(disp_buf[6]); lcd_wdat(disp_buf[7]);lcd_wdat(0x3a);lcd_wdat(disp_buf[8]); lcd_wdat(disp_buf[9]);lcd_wdat(0x3a);lcd_wdat(disp_buf[10]); lcd_wdat(disp_buf[11]);}void timer1() interrupt 3{TH1=0xdc; TL0=0x00;count_10ms++;if(count_10ms>=100){count_10ms=0; sec++;if(sec>=60){sec=0; min++;if(min>=60){min=0; hour++;if(hour>=24){hour=0; day++;if(day>=30){day=1; mon++;if(mon>=12){mon=1; year++;} }}} } }}void keyprocess(){TR1=0;if(k2==0){Delay_ms(10);if(k2==0){while(!k2); year++; }}if(k3==0){Delay_ms(10);if(k3==0){while(!k3); mon++;if(mon>12){mon=0;} } }if(k4==0){Delay_ms(10);if(k4==0){while(!k4); day++;if(day>30){day=0;} } }if(k5==0){Delay_ms(10);if(k5==0){while(!k5); hour++;if(hour==24){hour=0;} }}if(k6==0){Delay_ms(10);if(k6==0){while(!k6); min++; if(min==60) {min=0;} }}if(k7==0){Delay_ms(10);if(k7==0){while(!k7);TR1=1; k1_flag=0;} }}void timer1_init(){TMOD=0x10;TH1=0xdc; TL1=0x00;EA=1; ET1 =1; TR1 =1;}void main(){uchar i;P0=0xff; P2=0xff;timer1_init ();lcd_init(); lcd_clr();lcd_wcmd(0x00|0x80);i=0;while(line1_data[i]!='\0'){lcd_wdat(line1_data[i]); i++;}lcd_wcmd(0x0c|0x80); i=0;while(line1_data[i]!='\0'){lcd_wdat(line1_data[i]); i++;}lcd_wcmd(0x40|0x80); i=0;while(line2_data[i]!='\0'){lcd_wdat(line2_data[i]); i++;}lcd_wcmd(0x4c|0x80); i=0;while(line2_data[i]!='\0'){lcd_wdat(line2_data[i]); i++;}while(1){if(k1==0){Delay_ms(10);if(k1==0){while(!k1);k1_flag=1;}}if(k1_flag==1)keyprocess();LCD_conv(year,mon,day,hour,min,sec); LCD_disp();}}。

1602液晶显示程序(时钟)

1602液晶显示程序(时钟)

// ************1602液晶显示程序************ #include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P2^2; //液晶使能位sbit lcdrw=P2^1; //液晶读写位sbit lcdrs=P2^0; //数据命令选择位uchar shi,fen,miao;uchar code time1[]="DATA: 2011-4-19";uchar code time2[]="TIME: 00:00:00";void w_cmd(uint date);void w_data(uint date);void w_cht(uchar add,uchar date);//************初始化及相关子函数*********** void delay(uchar x){uchar y,z;for(y=x;y>0;y--)for(z=110;z>0;z--);}void init() //1602液晶初始化{uchar i,j;lcden=0; //初始使能端lcdrw=0; // 写数据选择w_cmd(0x38);w_cmd(0x01);w_cmd(0x0c);w_cmd(0x06);w_cmd(0x80);for(i=0;i<15;i++)w_data(time1[i]);w_cmd(0x80+0x40);for(j=0;j<15;j++)w_data(time2[j]); //上电初始显示数据}void w_cmd(uint date) //“写”命令子程序{lcdrs=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void w_data(uint date) //”写“数据子程序{lcdrs=1;P0=date;delay(3);lcden=1;delay(5);lcden=0;}void intrupt() //"TO中断"初始{TMOD=0x01; //选择16位定时器0x01 EA=1; //开总中断ET0=1; //开“T0”中断允许位TH0=(65536-50000)/256;TL0=(65536-50000)%256; //定时器装初值TR0=1;}void w_cht(uchar add,uchar date) //时间改变函数{uchar date1,date2;w_cmd(0x80+0x40+add);date1=date/10;date2=date%10;w_data(0x30+date1);w_data(0x30+date2);}//********主函数**************void main(){init();intrupt();while(1);}//*******T0中断子程序************* void T_rupt() interrupt 1{uchar flag; //定义标志位TH0=(65536-50000)/256;TL0=(65536-50000)%256; //赋初值flag++;if(20==flag){flag=0;miao++;if(60==miao){miao=0;fen++;if(60==fen){fen=0;shi++;if(24==shi){shi=0;}w_cht(7,shi);}w_cht(10,fen);}w_cht(13,miao);}}。

(完整word版)1602液晶时钟程序(51单片机)

(完整word版)1602液晶时钟程序(51单片机)

1602液晶时钟程序程序按郭天袢《新概念51单片机C语言教程》第十四章扩展显示年、月、日、星期调节功能。

1)时间显示在1602液晶上,并按秒实时更新2)能调节按键调整时、分、秒、年、月、日和星期3)每次按键按下时有短滴声响声4)断电后下次上电会接着上次断电前的时间数继续运行原理图如图//原代码如下:#include<reg52.h>//#include"24c02.h"#define uchar unsigned char#define uint unsigned int#include"24c02.h"sbit dula=P2^6;sbit wela=P2^7;sbit LCDEN=P3^4;sbit LCDRS=P3^5;sbit s1=P3^0;//定义按键--功能键sbit s2=P3^1;//定义按键--增大键sbit s3=P3^2;//定义按键--减小键sbit rd=P3^7;//按键公共脚sbit beep=P2^3;//定义蜂鸣器脚uchar count,s1_num;//定义中断次数计数变量功能键按键次数变量uchar week,day,month,year;//定义变量:星期日月年char miao,shi,fen;//定义秒分时变量uchar code table[]=" 2012-11-28 Wed";//void write_week(char we);//显示星期几函数void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void di()//蜂鸣器响一声函数{beep=0;delay(100);beep=1;}void write_com(uchar com) //液晶写命令函数{LCDRS=0;P0=com;delay(5);LCDEN=1;delay(5);LCDEN=0;}void write_date(uchar date) //液晶写数据函数{LCDRS=1;P0=date;delay(5);LCDEN=1;delay(5);LCDEN=0;}void write_week(char we) //写星期几显示函数{write_com(0x80+12);switch(we){case 1: write_date('M');delay(5); //星期一Mondaywrite_date('o');delay(5);write_date('n');delay(5);break;case 2: write_date('T');delay(5); //星期二Tuesdaywrite_date('u');delay(5);write_date('e');delay(5);break;case 3: write_date('W');delay(5); //Wednesdaywrite_date('e');delay(5);write_date('d');delay(5);break;case 4: write_date('T');delay(5); //Thursdaywrite_date('h');delay(5);write_date('u');delay(5);break;case 5: write_date('F');delay(5); //星期五Fridaywrite_date('r');delay(5);write_date('i');delay(5);break;case 6: write_date('S');delay(5); //星期六Saturdaywrite_date('a');delay(5);write_date('t');delay(5);break;case 7: write_date('S');delay(5); //星期日Sundaywrite_date('u');delay(5);write_date('n');delay(5);break;default: break;}}void write_sfm(uchar add,uchar date) //写时分秒函数{uchar shiwei,gewei;shiwei=date/10;gewei=date%10;write_com(0x80+0x40+add);//设置显示位置write_date(0x30+shiwei);//加上0x30是因为数字变成字符串需要加上0x30,看ASCII码值与字符的关系write_date(0x30+gewei);}void write_year_month_day(uchar add,uchar day) //写年月日数函数{uchar shi,ge;shi=day/10;ge=day%10;write_com(0x80+add);//设置显示位置write_date(0x30+shi);//加上0x30是因为数字变成字符串需要加上0x30,看ASCII码值与字符的关系write_date(0x30+ge);}void init() //初始化函数{uchar num;rd=0;beep=1;dula=0;wela=0;LCDEN=0;//将使能端置0以完成高脉冲fen=0;miao=0;shi=0;count=0;//计数初始为0init_24c02();write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口write_com(0x0c);//设置开显示,不显示光标write_com(0x06);//写一个字符后地址指针自动加1write_com(0x01);//显示清0,数据指针清0write_com(0x80); //设置显示初始坐标for(num=0;num<15;num++) //显示年月日{write_date(table[num]);delay(5);}write_com(0x80+0x40+6); //写出时间显示部分的两个冒号write_date(0x3a);delay(5);write_com(0x80+0x40+9);write_date(0x3a);delay(5);miao=read_add(1);//开机上电时读取24c02 IIC的数据赋值fen=read_add(2);shi=read_add(3);week=read_add(4);//读取星期几day=read_add(5);//读取多少日month=read_add(6);year=read_add(7);write_sfm(10,miao);//分别送去液晶显示write_sfm(7,fen);write_sfm(4,shi);write_week(week);//开机从24c02读取的星期几数从新写入液晶显示出来write_year_month_day(9,day);write_year_month_day(6,month);write_year_month_day(3,year);//定时器初始化TMOD=0x01; //设置定时器0工作模式1TH0=(65536-45876)/256; //定时器装初值TL0=(65536-45876)%256;EA=1; //开总中断ET0=1; //打定时器0中断TR0=1; //启动定时器0}void keyscan() //按键扫描函数{if(s1==0){delay(5);if(s1==0){s1_num++; //功能键按下次数记录while(!s1); //按键释放确认di();if(s1_num==1) //只按一次按键时TR0=0; //关闭定时器write_com(0x80+0x40+11);write_com(0x0f); //打开光标闪烁}if(s1_num==2) //第二次按下光标闪烁定位到分钟位置{write_com(0x80+0x40+8);}if(s1_num==3) //第三次按下光标闪烁定位到小时位置{write_com(0x80+0x40+5);}/**************************************if(s1_num==4) //第三四次按下退出{s1_num=0;write_com(0x0c); //取消光标闪栎TR0=1; //启动定时器使时钟开始走}***************************************/if(s1_num==4) //光标处星期{write_com(0x80+14);}if(s1_num==5) //光标处日{write_com(0x80+10);}if(s1_num==6) //光标处月{write_com(0x80+7);}if(s1_num==7) //光标处年{write_com(0x80+4);}if(s1_num==8) //当第八次按功能键时退出光标闪烁及开始计时{s1_num=0;write_com(0x0c); //取消光标闪栎TR0=1; //启动定时器使时钟开始走}}if(s1_num!=0){if(s2==0)//增加键确认按下{delay(5);if(s2==0){while(!s2);di();if(s1_num==1){miao++;if(miao==60)miao=0;write_sfm(10,miao);write_com(0x80+0x40+11);write_add(1,miao);}if(s1_num==2){fen++;if(fen==60)fen=0;write_sfm(7,fen);write_com(0x80+0x40+8);write_add(2,fen);}if(s1_num==3){shi++;if(shi==24)shi=0;write_sfm(4,shi);write_com(0x80+0x40+5);write_add(3,shi);}if(s1_num==4)//按四次功能键后光标至星期几处,可调节星期几{week++;if(week==8)week=1;write_week(week);write_com(0x80+14); //写一个字符后光标会移一位,所以要重新定义光标位置write_add(4,week);}if(s1_num==5) //光标至显示日处,可调节多少日{day++;if(day==32)day=1;write_year_month_day(9,day);write_com(0x80+10);write_add(5,day);}if(s1_num==6) //光标至显示月处调节月份{month++;if(month==13)month=1;write_year_month_day(6,month);write_com(0x80+7);write_add(6,month);}if(s1_num==7){year++;if(year==100)year=00;write_year_month_day(3,year);write_com(0x80+4);write_add(7,year);}}}if(s3==0) //确认减小键被按下{delay(5);//按键防抖延时if(s3==0) //确认减小键被按下{while(!s3);di();if(s1_num==1){miao--;if(miao==-1)miao=59;write_sfm(10,miao);write_com(0x80+0x40+11);write_add(1,miao);}if(s1_num==2){fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+0x40+8);write_add(2,fen);}if(s1_num==3){shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+0x40+5);write_add(3,shi);}if(s1_num==4){week--;if(week==0)week=7;write_week(week);write_com(0x80+14); //写一个字符后光标会移一位,所以要重新定义光标位置write_add(4,week);}if(s1_num==5)//光标至显示日处,可调节多少日{day--;if(day==0)day=31;write_year_month_day(9,day);write_com(0x80+10);//光标位置移回在显示多少日的个位write_add(5,day);}if(s1_num==6) //光标至显示月处调节月份{month--;if(month==0)month=12;write_year_month_day(6,month);write_com(0x80+7);write_add(6,month);}if(s1_num==7){year--;if(year==-1)year=99;write_year_month_day(3,year);write_com(0x80+4);write_add(7,year);}}}}}void main(){init();//首先初始化各数据while(1){keyscan(); //按键扫描函数}}void timer0() interrupt 1 //定时器0中断服务程序{TH0=(65536-45876)/256;TL0=(65536-45876)%256;count++; //中断次数累加,计数if(count==20) //50微秒乘以20等于1秒{count=0;miao++;if(miao==60) //秒加到60则进位分钟{miao=0; //同时秒数清0fen++;if(fen==60) //分钟加到60则进位小时{fen=0; //同时分钟清0shi++;if(shi==24) //小时加到24则小时清0{shi=0;}write_sfm(4,shi);//小时若变化则重新写入write_add(3,shi);//写入24c02存储起来,小时数的写入地址为3 }write_sfm(7,fen);//分钟若变化则重新写入write_add(2,fen);}write_sfm(10,miao);//秒若变化则重新写入write_add(1,miao);}}/***********************************24C02.h头文件,将以下源代码需存为与保存的C代码根目录下。

LCD1602显示时间和温度

LCD1602显示时间和温度

/*************************************************************/
/* */
/* 延时子程序 */
delay(5);
lcd_wcom(0x38);
delay(5);
lcd_wcom(0x38);
delay(5);
lcd_wcom(0x0c); //显示开,关光标
delay(5);
lcd_wcom(0x06); //移动光标
delay(5);
lcd_wcom(0x01); //清除LCD的显示内容
delay(5);
}
/*************************************************************/
/* */
/* 1602显示字符串 */
/* */
sbit SDA=P3^4; //数据端
sbit RST = P3^5; // DS1302复位端
sbit LCD_RW = P2^5; //1602的读写端
sbit LCD_RS = P2^6; //1602的数据命令端
sbit LCD_EN = P2^7; //1602的使能
/* */
/* LCD初始化设定 */
/* */
/* */
/*******************************************************************/
void lcd_wcom(uchar com)
/*************************************************************/

1602液晶显示(年月日时分秒星期)

1602液晶显示(年月日时分秒星期)

电子钟—1602液晶显示(年月日时分秒星期)/* 以下是电子钟的c51源程序,用1602液晶显示,虽然程序很庞大,但容易看懂。

改程序花了我两三天的时间才弄好的,现在放在此分享。

*/#include<AT89X52.H>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define T 49998#define T1 64536sbit rs=P2^0;sbit rw=P2^1;sbit en=P2^2;uchar key,n,loca=0,allow=0,cout;uchar week;uchar time[6]={0,6,15,12,30,0}; //对应、月、日、时、分、秒?uint year=2009;void delay(uint ms){uint i;for(;ms>0;ms--){for(i=246;i>0;i--);}}void timer0() interrupt 1{TH0=(65536-T)/256;TL0=(65535-T)%256;n++;}void time_addsec(){if(20<=n){n=0;time[5]++; //产生秒}}uchar key_scan(){uchar i,j,key,temp;uchar code scan[]={0xfe,0xfd,0xfb,0xf7};uchar code keyb[]={0x7e,0xbe,0xde,0xee,0x7d,0xbd,0xdd,0xed,0x7b,0xbb,0xdb,0xeb,0x77,0xb7,0xd7,0xe7};for(i=0;i<4;i++){P3=scan[i];_nop_();temp=P3;if(temp!=scan[i]){for(j=0;j<16;j++){if(keyb[j]==P3){delay(50);// while(keyb[j]==P3);//松手操作// delay(20);// while(keyb[j]==P3);key=j+1;break;}if(keyb[j] != P3){key=0;}}}}return key;}bit lcd_bz()//1602检忙{bit v;rs=0;rw=1;en=1;_nop_();v=(bit)(P0&0x80);en=0;return v;}void lcd_wcmd(uchar cmd)//1602写命令{while(lcd_bz());rs=0;rw=0;en=0;_nop_();P0=cmd;_nop_();en=1;_nop_();_nop_();en=0;_nop_();rs=0;}void lcd_wdat(uchar dat)//1602写数据{while(lcd_bz());rs=1;rw=0;en=0;_nop_();P0=dat;_nop_();en=1;_nop_();;en=0;}void lcd_wstr(uchar *str)//1602写字符串{uchar i;for(i=0;str[i]!='\0';i++){lcd_wdat(str[i]);}}void lcd_pos(uchar pos)//光标定位{while(lcd_bz());lcd_wcmd(pos|0x80);}/*void lcd_cur(){switch(loca){case 0 : lcd_pos(0x46); case 1 : lcd_pos(0x49); case 2 : lcd_pos(0x05); case 3 : lcd_pos(0x08); case 4 : lcd_pos(0x0b); }}*/void lcd_rmove()//光标右移{if(1==allow){if(loca >= 0 && loca < 5) {loca++;}}}void lcd_lmove(){if(1==allow){if(loca > 0 && loca <= 5) {loca--;}}}void lcd_addtime()//调时间加{uint dat ;if(1==allow)switch(loca){case 0 :{dat=year;dat++;year=dat;delay(100);break;}case 1 :{dat=time[1];dat++;if(dat>12)dat=1;time[1]=dat;delay(100);break; }case 2 :{dat=time[2];dat++;if(dat>30)dat=1;time[2]=dat;delay(100);break; }case 3 :{dat=time[3];dat++;if(dat>24)dat=1;time[3]=dat;delay(100);break; }case 4 :{dat=time[4];dat++;if(dat>60)dat=1;time[4]=dat;delay(100);break; }case 5 :{dat=time[5];dat++;if(dat>60)dat=1;time[5]=dat;delay(100);break; }}}void lcd_detime()//调时间减{int dat ;if(1==allow)switch(loca){case 0 :{dat=year;dat--;if(dat<0)dat=2000;year=dat;delay(100);break;}case 1 :{dat=time[1];dat--;if(dat<0)dat=12;time[1]=dat;delay(100);break; }case 2 :{dat=time[2];dat--;if(dat<0)dat=30;time[2]=dat;delay(100);break; }case 3 :{dat=time[3];dat--;if(dat<0)dat=23;time[3]=dat;delay(100);break; }case 4 :{dat=time[4];dat--;if(dat<0)dat=59;time[4]=dat;delay(100);break; }case 5 :{dat=time[5];dat--;if(dat<0)dat=59;time[5]=dat;delay(100);break;}}}void function(){uchar key=key_scan();switch(key){case 5 : lcd_lmove();break;case 6 : lcd_rmove();break;case 7 : lcd_addtime();break;case 8 : lcd_detime();break;case 9 : lcd_wcmd(0x0f);allow=1;break; //显示光标case 10 : lcd_wcmd(0x0c);allow=0;break; //关闭光标}}bit year_tell() //判断是否闰年是1 否0{if((year%4 == 0 && year%100 !=0) || year%400 == 0) return 1;else return 0;}uint count1(uint year , uchar mon , uchar day)//以下count1到count3都是为了计算对应的星期{uint m;switch(mon){case 1 : m=366-day; break;case 2 : m=335-day; break;case 3 : m=306-day; break;case 4 : m=275-day; break;case 5 : m=245-day; break;case 6 : m=214-day; break;case 7 : m=184-day; break;case 8 : m=153-day; break;case 9 : m=122-day; break;case 10 : m=92-day; break;case 11 : m=61-day; break;case 12 : m=31-day; break;default : ;}if(!(year%4 == 0 && year%100 != 0 || year%400 == 0)){if(mon<=2){m=m-1;}}return(m);}uint count2(uint year , uchar mon , uchar day){uint m;if(year%4 == 0 && year%100 != 0 || year%400 == 0){m=366-count1(year , mon , day);}else{m=365-count1(year , mon , day);}return m;}uint count3(uint year1 , uint year2){uint m=0;uchar i;uint n=year2-year1;for(i=1;i<n;i++){if((year1+i)%4 == 0 && (year1+i)%100 != 0 || (year1+i)%400 == 0) {m+=366;}else{m+=365;}}return m;}uchar week_tell()//判断对应的星期{uchar w;w=(count1(1901,1,7)+count2(year,time[1],time[2])+count3(1901,year)+1)%7; if(w!=0)return w;else return 7;}void timecount()//时间计算{if(time[5]>=60) //sec{time[5]=0;time[4]++;}if(time[4]>=60)//min{time[4]=0;time[3]++;}if(time[3]>=24)//hour{time[3]=0;time[2]++; //day}switch(time[1]) //mon{case 1 : if(time[2]>=31){time[2]=0; time[1]++;}case 2 :if(1==year_tell()){if(time[2]>29){time[2]=0; time[1]++;}}else{if(time[2]>28){time[2]=0; time[1]++;}}case 3 : if(time[2]>=31){time[2]=0; time[1]++;}case 4 : if(time[2]>=30){time[2]=0; time[1]++;}case 5 : if(time[2]>=31){time[2]=0; time[1]++;}case 6 : if(time[2]>=30){time[2]=0; time[1]++;} case 7 : if(time[2]>=31){time[2]=0; time[1]++;} case 8 : if(time[2]>=31){time[2]=0; time[1]++;} case 9 : if(time[2]>=30){time[2]=0; time[1]++;} case 10 : if(time[2]>=31){time[2]=0; time[1]++;} case 11 : if(time[2]>=30){time[2]=0; time[1]++;} case 12 : if(time[2]>=31){time[2]=0; time[1]++;} }if(time[1]>12){time[1]=0;year++;}}/*void lcd_clear(){lcd_wcmd(0x01);_nop_();}*/void lcd_display(uchar p)//液晶显示{uchar i,j;uchar str_com[14];str_com[13]=year/1000;str_com[12]=(year/100)%10;str_com[11]=(year%100)/10;str_com[10]=year%10;str_com[9]=time[1]/10;str_com[8]=time[1]%10;str_com[7]=time[2]/10;str_com[6]=time[2]%10;str_com[5]=time[3]/10;str_com[4]=time[3]%10;str_com[3]=time[4]/10;str_com[2]=time[4]%10;str_com[1]=time[5]/10;str_com[0]=time[5]%10;if(0==p)//非设定状态{lcd_pos(0x07);for(i=0,j=0;i<8;i++,j++){if(2==i || 5==i){lcd_wdat(':');j--;}elselcd_wdat(str_com[j]+48);}lcd_pos(0x49);for(i=6,j=6;i<16;i++,j++){if(8==i || 11==i){lcd_wdat('-');j--;}elselcd_wdat(str_com[j]+48);}delay(1 );lcd_wcmd(0x06);lcd_pos(0x4c);switch(week_tell()){case 1 : lcd_wstr("Mon");break;case 2 : lcd_wstr("Tue");break;case 3 : lcd_wstr("Wen");break;case 4 : lcd_wstr("Thu");break;case 5 : lcd_wstr("Fri");break;case 6 : lcd_wstr("Sat");break;case 7 : lcd_wstr("Sun");break;}delay(1 );lcd_wcmd(0x04);}else if(1==p)//时间设定状态{lcd_pos(0x07);lcd_wdat(str_com[0]+48);lcd_wdat(str_com[1]+48);switch(loca) //下面是让光标定在选择位,以便光标稳定的闪烁{case 0 : lcd_pos(0x43);break; case 1 : lcd_pos(0x46);break; case 2 : lcd_pos(0x49);break; case 3 : lcd_pos(0x01);break; case 4 : lcd_pos(0x04);break; case 5 : lcd_pos(0x07);break; }}}void lcd_init()//液晶初始化{delay(15);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);delay(5);lcd_wcmd(0x38);while(lcd_bz());lcd_wcmd(0x0e);while(lcd_bz());lcd_wcmd(0x01);}void init(){TMOD=0x11;TH0=(65536-T)/256;TL0=(65536-T)%256;TH1=T1;TL1=T1;EA=1;TR0=1;ET0=1;TR1=0;ET1=1;}main(){init();lcd_init();while(1){// delay(3);// lcd_clear();delay(1 );lcd_wcmd(0x04);time_addsec();timecount();function();lcd_display(1);cout++;if(cout>=50){cout=0;lcd_display(0);}}}//程序到此结束,估计看了有点晕,不过没关系,程序是没有错的,定时很准,经调试在几个小时之后也达到分秒不差,晶振是12M。

1602按键操控时间显示

1602按键操控时间显示

#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit lcdrw=P2^5;sbit key1=P3^0;sbit key2=P3^1;sbit key3=P3^2;sbit Gnd=P3^7;uchar counter,cycle;uchar key_counter = 0; //定义光标闪烁以及修改操作数的标记uchar second0,second1,minute0,minute1,hour0,hour1;uchar table[][3]={"SUN","MON","TUE","WEN","THU","FRI","SAT"};uchar year[4],day[2],month[2],date; //日期变量uchar small_mon,leap_year;void state() //检查日期状态函数(即判断是否闰年,是否小月的函数) {switch(month[0]){case 1: if(month[1] == 1) //若是11月,则是小月small_mon = 1;else //若是1月,则不是小月small_mon = 0;break;case 4:case 6:case 9: small_mon = 1;break;default:small_mon = 0;break;}if((year[3] * 1000 + year[2] * 100 + year[1] * 10 + year[0]) % 100 == 0){if((year[3] * 1000 + year[2] * 100 + year[1] * 10 + year[0]) % 400 == 0)leap_year = 1;}else if((year[3] * 1000 + year[2] * 100 + year[1] * 10 + year[0]) % 4 == 0)leap_year = 1;elseleap_year = 0;}void Dater() //日期函数{state();day[0]++;date=(date+1)%7;switch(day[0]){case 10:{if(day[1] == 2 && month[0] == 2 && month[1] == 0) //闰年时,把2月30号转变为3月1号{day[0] = 1;day[1] = 0;month[0]++;}else //日期各位满10进1{day[0] = 0;day[1]++;}}break;case 1:{if(day[1] == 3 && small_mon) //小月31号时把日期置为1号,月份+1{day[0] = 1;day[1] = 0;month[0]++;}}break;case 2:{if(day[1] == 3){day[0] = 1;day[1] = 0;month[0]++;}}break;case 9:{if(day[1] == 2 && !leap_year && month[0] == 2 && month[1] == 0) //平年时,把2月29号变为3月1号{day[0] = 1;day[1] = 0;month[0]++;}}break;default:break;}switch(month[0]){case 10:{month[0] = 0;month[1]++;}break;case 3:{if(month[1] == 1) {month[0] = 1;month[1] = 0;year[0]++;}}break;}if(year[0] > 9){year[0] = 0;year[1]++;if(year[1] > 9){year[1] = 0;year[2]++;if(year[2] > 9){year[2] = 0;year[3]++;if(year[3] > 9)year[3] = 0;}}}}void clock() //时钟函数{if (second0 > 9){second0 = 0;second1++;if (second1 > 5){second1 = 0;minute0++;if (minute0 > 9){minute0 = 0;minute1++;if (minute1 > 5){minute1 = 0;hour0++;if (hour0 == 4 && hour1 == 2) {hour0 = hour1 = 0;Dater();}else if (hour0 > 9){hour0 = 0;hour1++;}}}}}}void delay(uint z) //延时函数{for(x = z;x > 0;x--)for(y = 110;y > 0;y--) ;}void write_com(uchar com) //写指令到LCD液晶显示{lcdrs = 0;lcdrw = 0;P0 = com;delay(1);lcden = 1;delay(1);lcden = 0;}void write_data(uchar data0) //写数据到LCD液晶显示{lcdrs = 1;lcdrw = 0;P0 = data0;delay(1);lcden = 1;delay(1);lcden = 0;}void disp_time() //显示时间{write_com(0xc4);write_data(hour1 + 0x30);write_data(hour0 + 0x30);write_data(0x3a);write_data(minute1 + 0x30);write_data(minute0 + 0x30);write_data(0x3a);write_data(second1 + 0x30);write_data(second0 + 0x30);if(key_counter != 0 ){switch(key_counter){case 1:write_com(0x80+0x4b); //定位回光标闪烁位置break;case 2:write_com(0x80+0x48);break;case 3:write_com(0x80+0x45);break;case 4:write_com(0x80+0x0e);break;case 5:write_com(0x80+0x0b);break;case 6:write_com(0x80+0x08);break;case 7:write_com(0x80+0x03);break;}write_com(0x0f);delay(150);}void disp_date() //显示日期{write_com(0x81);for(cycle = 0; cycle < 3;cycle++) write_data(table[date][cycle]); write_data(0x20);for(cycle = 0;cycle < 4;cycle++) write_data(year[3 - cycle]+0x30); write_data(0x2f);write_data(month[1]+0x30); write_data(month[0]+0x30); write_data(0x2f);write_data(day[1]+0x30);write_data(day[0]+0x30);}void setting_detect(){Gnd=0;if(key1==0){delay(5);if(key1==0) //消除抖动{while(!key1); //等待松手TR0=0;key_counter++;do{disp_date();disp_time();if(key1==0) //按键“切换”delay(5);if(key1==0){while(!key1);key_counter++;}}if(key2==0) //按键“加”{delay(5);if(key2==0){while(!key2);switch(key_counter) {case 1:second0++;if(second0 > 9){second0 = 0;second1++;if(second1 == 6) second1 = 0;}break;case 2:minute0++;if(minute0 > 9){minute0 = 0;minute1++;if(minute1 == 6)minute1 = 0;}break;case 3:hour0++;if(hour1 == 2 && hour0 > 3){hour0 = 0;hour1 = 0;}else if(hour0 > 9){hour0 = 0;hour1++;}break;case 4:day[0]++;if(day[0] == 2 && day[1] == 3) {day[0] = 1;day[1] = 0;}if(day[0] == 10){day[0] = 0;day[1]++;}break;case 5:month[0]++;if(month[0] == 3 && month[1] == 1)month[0] = 1; month[1] = 0;}if(month[0] == 10) {month[0] = 0; month[1] = 1;}break;case 6:year[0]++;if(year[0] > 9) {year[0] = 0;year[1]++;if(year[1] > 9) {year[1] = 0;year[2]++;if(year[2] > 9) {year[2] = 0;year[3]++;if(year[3] > 9) year[3] = 0;}}}break;case 7:date=(date+1)%7; break;}}if(key3==0) //按键“减”{delay(5);if(key3==0){while(!key3);switch(key_counter) {case 1:if(second0 == 0){second0 = 9;if(second1 == 0) second1 = 5;elsesecond1--;}elsesecond0--;break;case 2:if(minute0 == 0){minute0 = 9;if(minute1 == 0) minute1 = 5;elseminute1--;}elseminute0--;break;case 3:if(hour0 == 0){if(hour1 == 0){hour0 = 3;hour1 = 2;}else{hour0 = 9;hour1--;}}elsehour0--;break;case 4:if(day[0] == 1 && day[1] == 0)day[1] = 3;if(day[0] == 0){day[0] = 9;day[1]--;}elseday[0]--;break;case 5:if(month[0] == 1 && month[1] == 0) {month[0] = 2; month[1] = 1;}else if(month[0] == 0) {month[0] = 9; month[1]--;}elsemonth[0]--;break;case 6:if(year[0] == 0){year[0] = 9;if(year[1] == 0){year[1] = 9;if(year[2] == 0){year[2] = 9;if(year[3] == 0)year[3] = 9;elseyear[3]--;}elseyear[2]--;}elseyear[1]--;}elseyear[0]--;break;case 7:date=(date+6)%7;break;}}}}while(key_counter != 8);key_counter = 0; //退出设置时关掉光标显示TR0=1;}}}void Lcd_init() //显示屏初始化{lcden = 0;write_com(0x01); //清屏write_com(0x02); //位置复位为左上方write_com(0x06); //光标右移write_com(0x0e); //显示开,有光标,闪烁write_com(0x38);}void timer0() interrupt 1 //定时器{TH0 = (65536-39970)/256;TL0 = (65536-39970)%6;counter++;if(counter == 25){counter = 0;clock();}void Timer_init() //定时器初始化{TMOD = 0x01;TH0 = (65536-29995)/256;TL0 = (65536-29995)%6;EA = 1;ET0 = 1;TR0 = 1;}void Date_init() //日期初始化{date = 6;day[0] = 7;day[1] = 0;month[0] = 7;month[1] = 0;year[0] = 2;year[1] = 1;year[2] = 0;year[3] = 2;}void Time_init() //时间初始化{second0 = 0;second1 = 3;minute0 = 0;minute1 = 3;hour0 = 2;hour1 = 1;counter = 0;}void main() //主函数{Lcd_init();Time_init();Date_init();Timer_init();while(1){disp_date();disp_time(); setting_detect();}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for(i=0;i<5;i++);
}
void delay5ms(uint j)
{
uint a,b;
for(a=j;a>0;a--)
for(b=100;b>0;b--);
}
void init_time0()
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=0x4c;
TL0=0x00;
TR0=1;
}
void write_com(uchar com)
图3晶振电路
3.1.3
单片机复位的条件是:必须使RST/VPD或RST引(9)加上持续两个机器周期(即24个振荡周期)的高电平。例如,若时钟频率为12 MHz,每机器周期为1μs,则只需2μs以上时间的高电平,在RST引脚出现高电平后的第二个机器周期执行复位。单片机常见的复位如图所示。电路为上电复位电路,它是利用电容充电来实现的。在接电瞬间,RESET端的电位与VCC相同,随着充电电流的减少,RESET的电位逐渐下降。只要保证RESET为高电平的时间大于两个机器周期,便能正常复位。该电路除具有上电复位功能外,若要复位,只需按图中的RESET键,此时电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,它不再需要多路转接电路MUX;因此它作为输出口使用时,无需再外接上拉电阻,当作为输入口使用时,同样也需先向其锁存器写“1”,使输出驱动电路的FET截止。
P2口:P2口电路比P1口电路多了一个多路转接电路MUX,这又正好与P0口一样。P2口可以作为通用的I/O口使用,这时多路转接电路开关倒向锁丰存器Q端。
1.3
1).时制式为24小时制。
2).采用LCD1602液晶显示年、月、日、时、分,秒采用数字显示。
3).具有方便的时间调校功能。
4).计时稳定度高,可精确校正计时精度。
二、
2.1
利用MCS-51系列单片机的可编程定时/计数器、中断系统来实现时钟计数。
计数初值计算:把定时器设为工作方式1,定时时间为50ms,则计数溢出20次即得时钟计时最小单位1s。
_nop_();
P0=date;
_nop_();
_nop_();
_nop_();
_nop_();
e=1;
_nop_();
_nop_();
_nop_();
_nop_();
e=0;
}
void lcd_init()
{
write_com(0x01); delay();
write_com(0x3c); delay();
{
write_com(0x80);delay();
write_date('D');delay();
write_date('A');delay();
write_date('T');delay();
write_date('E');delay();
write_date(':');
write_date(tab[nian/1000]);
课程论文
题目:简易电子时钟
设计
学生姓名:殷焱
学生学号:1008030320
系别:电气学院
专业:电子信息工程
年级:103
任课教师:朱士永
电气信息工程学院制
2012年11月
一、设计任务及要求
1.1背景:
数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。尽管目前市场上已有现成的数字钟集成电路芯片出售,价格便宜、使用也方便,但鉴于单片机的定时器功能也可以完成数字钟电路的设计,因此进行数字钟的设计是必要的。在这里我们将已学过的比较零散的数字电路的知识有机的、系统的联系起来用于实际,来培养我们的综合分析和设计电路,写程序、调试电路的能力。单片机具有体积小、功能强可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。
write_date(tab[nian%1000/100]);//delay();
write_date(tab[nian%1000%100/10]); //delay();
write_date(tab[nian%10]);delay();
write_date('-');//delay();
write_date(tab[yue/10]);//delay();
1.2
(1)巩固、加深和扩大单片机应用的知识面,提高综合及灵活运用所学知识解决工业控制的能力;
(2)培养针对课题需要,选择和查阅有关手册、图表及文献资料的自学能力,提高组成系统、编程、调试的动手能力;
(3)过对课题设计方案的分析、选择、比较、熟悉单片机用系统开发、研制的过程,软硬件设计的方法、内容及步骤。
write_com(0x0c); delay();
write_com(0x06); //delay();
}
void sec_init()
{
write_com(0x3c); delay();
write_com(0x0f); delay();
write_com(0x06); //delay();
}
void time0() interrupt 1
图6按键模块电路原理图
3.
下图一为电子时钟的总体电路图,图中BLK是调节液晶显示器的亮度的端口,可以通过改变滑动变阻器阻值的改变来改变液晶的显示亮度。
图二为图一所示原理图的PCB图
图一:原理图
图二:PCB图
四、
4.1
在编程上,首先进行了初始化,定义程序的的入口地址以及中断的入口地址,在主程序开始定义了一组固定单元用来储存计数的时.分.秒,在显示初值之后,进入主循环。在主程序中,对不同的按键进行扫描,实现秒表,时间调整,复位清零等功能,系统总流程图如下图:
write_date(tab[yue%10]);delay();
write_date('-');//delay();
write_date(tab[ri/10]);// delay();
write_date(tab[ri%10]));delay();
write_date('T');delay();
2.
利用AT89C52单片机内部的定时/计数器进行中断时,配合软件延时实现年、月、日、时、分、秒的计时。该方案节省硬件成本,且能使读者在定时/计数器的使用、中断及程序设计方面得到锻炼与提高,对单片机的指令系统能有更深入的了解,从而对学好单片机技术这门课程起到一定的作用。
2.
AT89C52的P0口外接LCD1602液晶显示器的数据输入端,用P2.0、P2.1口作指令的控制端口,P1.0、P1.1、P1.2口作时钟调节电路外接3个按键,AT89C52是一种低功耗,高性能的CMOS 8位微型计算机。它带有8k可编程和擦除的只读存储器(ROM),有很丰富的指令系统。且成本很低。简易电子钟的功能不复杂,采用其现有的I/O便可完成,所以本设计中采用此的设计方案。
图4单片机复位电路
3.2
用P0口来控制LCD液晶显示器的数据线,而用P2.0,P2.1口来控制其操作时序。因只对LCD1602进行写的操作,故读写控制端置为低电平。在软件操作时须对液晶进行初始化设置。
图5LCD1602液晶显示显示电路
3.3
下图为按键模块电路原理图,K1为时钟调控键,K2为数字增加键,K3为数字减小键。
if(day==30)
day=1;
mon++;
}
else if(!((year/4==0&&year/100!=0)&&(year/100==0&&year/400==0)))
{
if(day>28)
{
day=1;
mon++;
}
}
}
if(mon==13)
{
mon=1;
year++;
}
}
}
}
}
}
void lcd_display(uint nian,uint yue,uint ri,uint shi,uint fen,uint miao)
3.
右图所示为时钟电路原理图,在AT89S51芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。而在芯片内部,XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器。时钟电路产生的振荡脉冲经过触发器进行二分频之后,才成为单片机的时钟脉冲信号。
sbit k2=P1^1;
sbit k3=P1^2;
sbit rs=P2^0;
sbit e=P2^1;
sbit beep=P2^2;
uint count,year=2012,mon=9,day=28,hour=23,min=59,sec=50;
uchar c;
void delay()
{
uchar i;
P3口:P3口特点在于,为适应引脚信号第二功能的需要,增加了第二功能控制逻辑。当作为I/O口使用时,第二功能信号引线应保持高电平,与非门开通,以维持从锁存器到输出端数据输出通路的畅通。当输出第二功能信号时,该位应应置“1”,使与非门对第二功能信号的输出是畅通的,从而实现第二功能信号的输出,具体第二功能如表1所示。
相关文档
最新文档