基于52单片机控制的1602液晶电子时钟显示程序(精心整理)

合集下载

基于51单片机的1602日历时钟程序

基于51单片机的1602日历时钟程序
x &= 0x0f ; //x值限定在0~15之间
if(y == 0)
x |= 0x40 ; //如果显示是在第二行,则x的值加0x40
x |= 0x80 ; //获得x的值
LCD1602_write_cmd(x) ;//写入坐标值到LCD
}
}
/************************************************************
case 3 : sele_count = 3 ; break ;
default : break ;
}
return(self_cou***************************************************
蜂鸣器
************************************************************/
void delay_ms(uint16 count) // 延时时间count*1ms
{ uint16 i;
for(;count>0;count--)
LCD1602_DATA = dat ;
LCD1602_EN = 1 ;
LCD1602_EN = 0 ;
}
/***********************************************************
1602初始化
************************************************************/
uint8 LCD1602_display_self(uint8 count)

51单片机实现电子时钟功能-1602液晶显示

51单片机实现电子时钟功能-1602液晶显示

第一章设计要求及系统组成一、基本操作时序:读状态:输入:RS=L,RW=H,E=H 输出:D0~D7=状态字写指令:输入:RS=L,RW=L,D0~D7=指令码,E=高脉冲输出:无读数据:输入:RS=H,RW=H,E= 高脉冲输出:D0~D7数据写数据:输入:RS=H,RW=L。

D0~D7=数据,E=高脉冲输出:无二、、、状态字说明:STA7 D7\ STA6 D6\ STA5 D5 \ STA4 D4 \STA3 D3 \ STA2 D2\\ STA1 D1STA0-6:当前数据地址指针的数值STA7:读写操作使能 1表示禁止,0表示允许对控制器每次进行读写操作之前,都必须进行读写检测,确保STA7为0;但是我们可以进行延时进行实现。

RAM地址映射: LCD 16字*2行00 01 02 03 04 05 06 07 08 08 09 0A 0B 0C 0D 0E 0F (27)40 41 42 4F 50 (67)指令说明:1.初始化设置 1.显示模式设置指令码:00111000(0x38)功能:设置16*2显示,5*7点阵,8位数据接口必须开显示 2.显示开、关及光标设置指令码:00001DCB,功能:D=1 开显示;D=0 关显示;C=1显示光标;B=1 光标闪烁;B=0 光标不显示 000001NS:功能:N=1当读或写一个字符后地址指针加1,且光标加1;N=0相应的减1;S=1当写一个字符,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而屏幕移动的效果。

S=0 当写一个字符,正屏显示不移动。

数据控制:控制器内部设有一个数据地址指针,用户可通过它们来访问内部的全部80字节RAM4.2.1 数据指针设置:指令码:80H+地址码(0-27H,第二行开始:40H-67H) 4..2.2 读数据,写数据其它设置:01H:显示清屏:1.数据指令清零 2 所有显示清零 02H:显示回车:1.数据清零如何进行连接:实际操作中,液晶接到,第一管脚是D,第二管脚是VCC,15和16是背光,D0-D7是数据口,接到单片机的P0口,P0口接了两个锁存器,液晶,D/A,具有高阻状态的都可以随便接,没有影响,,第六管脚是LCDEN相当于 E,使能信号,它接P3^4,R/W接地,表示低电平,因为我们只进行写操作,RS接2实验板上的P3^5;只需这两端口便足以控制液晶,2和3是偏压信号,一端接地,接口信号说明:编号:1 VSS(符号表示)电源地(引脚说明)2VDD 电源正极3VL液晶显示偏压信号4RS数据/命令选择端(H/L)5R/W 读写选择端(H/L)6E使能信号7D0 Data 1/0 8D1 Data 1/0 9 D2 Data 1/0 10 D3 Data 1/0 11D4 Data 1/0 12D5 Data 1/0 13D6 Data 1/0 14D7 Data 1/0 15BLK背光源正极16 BLK背光源负极实际操作:::先写光标程序;写两个子程序,一个写数据,一个写指令:先进性两个宏定义,再位申明LCDEN与RS;为了电量充足。

基于51单片机的1602液晶显示温度和时间的C程序

基于51单片机的1602液晶显示温度和时间的C程序

//液晶显示温度#include "AT89X52.H"#define Ddata P0sbit RS=P2^7; //命令数据控制端sbit RW=P2^6; //读写选择端sbit LCDE=P2^5; //液晶使能端sbit DQ=P2^0; //ds18b20与单片机连接口#define uchar unsigned char#define uint unsigned intunsigned char hour=0,min=0,sec=0; //定义初值unsigned int count=0;unsigned char line1[16]={" temp: "}; //16个字符unsigned char line2[16]={" time: 00:00:00"}; //16个字符unsigned char tab[]={'0','1','2','3','4','5','6','7','8','9'}; //数组uchar data disdata[5];uint tvalue; //温度值uchar tflag; //温度正负标志void time();/*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<110;j++);}void delay5ms()//延时5毫秒(不够精确的){unsigned int i;for (i=0;i<1000;i++);}void delay50us(){register int i;for (i=0;i<20;i++);}void delay(){unsigned char m,n;for(m=255;m>0;m--)for(n=255;n>0;n--);}void wr_com(unsigned char comm) //********写控制字符程序E=1 RS=0RW=0 **********//{LCDE=0; //使能端RS=0; //********RS寄存器选择输入端,当RS=0;当进行写模块操作,指向指令寄存器。

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('-');}}}。

关于52单片机驱动74HC595控制LCD1602的程序

关于52单片机驱动74HC595控制LCD1602的程序

关于52单片机驱动74HC595控制LCD1602的程序谁能帮忙写个52单片机驱动74hc595控制LCD1602的程序#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define LcdBus P0sbit LED1602_RS=P2^6; //LCD端口定义sbit LED1602_RW=P2^5 ;sbit LED1602_EN=P2^4 ;void LcdIni(void);void WrOp(uchar dat);void WrDat(uchar dat);void ChkBusy(void);void print_LCD(uchar disp[],uchar num);//延时n ms子程序void delayms(unsigned int n){unsigned int i,j;for(i=0;i<n;i++)for(j=0;j<120;j++);}main(){uchar disp1[16]={'S','u','n','J','i','e',' ','m','a','d','e',' ','a','t',' ',' '};uchar disp2[16]={'2','0','0','8',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};while(1){LcdIni();WrOp(0x80); //数据指针地址第一行print_LCD(disp1,16);WrOp(0xc0); //第二行print_LCD(disp2,4);delayms(3000);WrOp(0x01);}}/**************************************************************************************** **名称:led1602显示程序模块功能:驱动1602 包括数据口P1 三个控制口编译:keil作者:孙杰时间:2008-8-9**************************************************************************************** ***/void print_LCD(uchar disp[],uchar num) //显示数组disp 显示长度为num {uchar i;for(i=0;i<num;i++){WrDat(disp[i]);delayms(300);}}void LcdIni(){WrOp(0x38);WrOp(0x06); //光标加1WrOp(0x0f); //开显示光标闪烁// WrOp(0x0c); //开显示光标不闪烁}void WrOp(uchar dat){//uchar i;ChkBusy();LED1602_RS=0; //RS=0LED1602_RW=0; //RW=0LED1602_EN=0; //EN=0LcdBus=dat; //送数据LED1602_EN=1; //EN=1delayms(10); //延时LED1602_EN=0; //EN=0}void WrDat(uchar dat){//uchar i;ChkBusy();LED1602_RS=1; //rs=1LED1602_RW=0; //rw=0LED1602_EN=0; //en=0LcdBus=dat; //送数据LED1602_EN=1; //en=1delayms(10);; //延时LED1602_EN=0; //en=0}void ChkBusy(){LED1602_RS=0; //RS=0LED1602_RW=1; //RW=1LED1602_EN=1; //EN=1while(LcdBus&0x80); //送数据LED1602_EN=0; //en=0}74hc595驱动问题#define uc unsigned char#define ui unsigned int#include<iom128v.h>uc Bmp[]={/*------------------------------------------------------------------------------ ; 源文件/ 文字:; 宽×高(像素): 64×8; 字模格式/大小: 单色点阵液晶字模,横向取模,字节正序/64字节; 数据转换日期: 2009-4-7 11:11:41------------------------------------------------------------------------------*/0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40, 0x40,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10, 0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x04, 0x04,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01};uc B1[8]={0};uc B2[8]={0};void delay(ui n) //延时函数{ui j;ui i;for(i=0;i<n;i++)for(j=0;j<20;j++);}void H_B1(uc h) //十六进制转换为二进制,转换后放在数组B1中{B1[7]=h&0x01;B1[6]=h&0x02;B1[5]=h&0x04;B1[4]=h&0x08;B1[3]=h&0x10;B1[2]=h&0x20;B1[1]=h&0x40;B1[0]=h&0x80;}void H_B2(uc h) //十六进制转换为二进制,转换后放在数组B2中{B2[0]=h&0x01;B2[1]=h&0x02;B2[2]=h&0x04;B2[3]=h&0x08;B2[4]=h&0x10;B2[5]=h&0x20;B2[6]=h&0x40;B2[7]=h&0x80;}void print(void) //扫描函数{uc byte=0;uc j=0;uc row=7; //扫第一行uc column;uc bit=0;uc h=0;PORTD=row; //行数赋给PDH_B1(Bmp[0]);while(1){for(row=7;row!=0xff;row--){PORTD=row; //行数赋给PDPORTF=0X00; //给一个扫描点PORTC=0xff;PORTC=0x00;PORTF=0XFF;for(byte=0;byte<8;byte++){H_B1(Bmp[byte+j]);for(bit=0;bit<8;bit++){//delay(2000);PORTC=0xff; //时钟上升沿//delay(1000);if(B1[bit]==0) PORTE=0Xff;//如果该点不应亮则74_138输出高阻else {PORTE=0X00; delay(40);}//否则输出低电平PORTF=0XFF; //扫描点后面通通熄灭//delay(2000);PORTC=0x00; //时钟下降沿}PORTG=0Xff;//delay(2000);PORTG=0X00;//bit=0;}j+=8;byte=0;}j=0;}}void main(void){DDRC=0XFF; //PC口为时钟输出DDRD=0XFF; //PD为行选,连74_138的ABC输入端DDRF=0XFF; //PF为列选,扫描点,接74_595的DS端DDRE|=0X80; //PE7为输出,74_138使能控制,低电平有效DDRG =0Xff;PORTG=0X00;PORTE=0XFF; delay(5000); PORTE=0X00; //开机信号//PORTE=0X00;print();}这是我刚写的一个64*8的点阵扫描程序用74HC595做行选,但是没用锁存,可以显示,但亮度很低。

用51单片机和1602液晶做的数字钟

用51单片机和1602液晶做的数字钟

课程设计报告数字钟姓名:学号:班级:指导教师:高雪飞目录一、设计题目和要求 (1)二、设计原理与实现功能 (1)三、元器件介绍………………………………………………四、电路设计…………………………………………………五、软件设计…………………………………………………六、设计总结…………………………………………………一、设计题目和要求题目:用STC89C52单片机和1602液晶做的数字时钟要求:1.准确计时,以数字形式显示时、分、秒的时间;2.小时的计时要求为“24翻1”,分和秒的计时为60进制。

二、设计原理与实现功能设计原理:控制芯片采用STC89C52RC单片机,晶振频率为11.0592MHZ,采用C语言编程,显示模块采用通用型1602液晶,发声模块采用无源蜂鸣器。

参考资料:51单片机C语言编程,1602datasheet,网络。

本装置使用的1602液晶为5v电压驱动,带背光,可显示两行,每行16个字符,不能显示汉字,内置含128个字符的ASCII字符集字库,只有并行接口,无串行接口,关于1602液晶的接口信号说明,主要技术参数,基本操作时序,RAM地址映射图,数据指针设置,初始化设置,写操作时序和其他设置请查阅1602的相关资料。

计时部分采用T0计时器中断方式1,TO定时器既有定时功能又有计数功能,通过设置与它们相关的特殊功能寄存器可以选择启用定时功能或计数功能。

当定时器的计数器计满后,会产生中断,通知CPU该如何处理。

关于51单片机的寄存器和中断功能及操作说明请查阅相关资料。

蜂鸣器的发声为单片机的一个引脚加一个三极管控制。

(1.要画出结构框图;2.数字钟的实现方法不止一种,因此必须说明自己所设计的数字钟采用何种方法、何种原理)实现功能:开启装置,则在1602液晶上有左向右划过“hello world I love programing”文字,之后上下两行显示年月日,星期和时间,其中年月日星期只能通过程序更改,时分秒自动从0开始计时,按秒更新,时分秒可用装置的两个按键进行调节,分别为时间设置键,数值增大键,闹钟的时间设置只能通过程序进行更改,一旦液晶显示时间和程序设定时间完全一致,蜂鸣器发声。

1602电子时钟程序

1602电子时钟程序

#include<reg52.h> //52单片机头文件#define uchar unsigned char //宏定义#define uint unsigned intsbit rs=P1^0; //声明单片机P1口的第一位读写指令还是数据端sbit rw=P1^1; //声明单片机P1口的第二位读写数据端sbit lcden=P1^2; //声明单片机P1口的第三位液晶使能端sbit s1=P2^5; //声明单片机P2口的第六位按键控制端sbit s2=P2^6; //声明单片机P2口的第七位按键控制端sbit s3=P2^7; //声明单片机P2口的第八位按键控制端sbit s4=P2^0; //声明单片机P2口的第一位按键控制端sbit s5=P2^4; //声明单片机P2口的第五位按键控制端sbit a=P3^5; //声明单片机P3口的第六位按键控制端char count,shi,fen,miao,s1num,xp,s5num,date1; //定义有符号字符形变量char nian,tian,yue,nshi,nfen; //定义有符号字符形变量uchar code table[]=" 2000-01-01 Mon "; //定义日期时间数组uchar code table1[]=" 00:00:00";uchar code table2[]=" Alarm clock"; //定义日期时间数组uchar code table3[]=" 00:00";void delay(uint z){uint x,y;for(x=z;x>0;x--) //延时子函数for(y=110;y>0;y--);}void write_com(uchar com) //指令子函数{rs=0; //选择写指令lcden=0; //使能端初始为底P0=com; //将送到要写的指令数据线上delay(5); //延时待数据稳定lcden=1; //使能端给一个高脉冲把数据写入1602液晶delay(5); //延时lcden=0; //拉低使能端完成高脉冲}void write_date(uchar date) //数据子函数{rs=1; //选择写数据lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void init() //初始子函数{uchar num; //定义变量用来调用数组rw=0; //选择只写数据到液晶lcden=0; //初始使能端为低电平write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口write_com(0x0c); //开显示,不显示光标write_com(0x06); //写一个字符指针自动加1write_com(0x01); //显示清零,数据指针清零write_com(0x80); //将数据指针定位到第一行第一个字处for(num=0;num<15;num++){write_date(table[num]); //写日期数组数据delay(20);}write_com(0x80+0x40); //选择将时间写到液晶第二行for(num=0;num<12;num++){write_date(table1[num]); //写时间数组数据delay(20);}write_com(0x80+16); //使用移屏操作for(num=0;num<13;num++){write_date(table2[num]); //写闹钟名称delay(20);}write_com(0x80+0x40+16); //选择移屏第二行for(num=0;num<10;num++){write_date(table3[num]); //写闹钟初始值delay(20);}TMOD=0x01; //选择定时器工作方式为方式1TH0=(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_sfn(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 keyscan() //按键子函数{{s4=0; //让共同接口置零if(s1==0) //判断s1是否被按下{delay(5); //延时5ms去斗if(s1==0) //再次判断s1是否真被按下{s1num++; //设置变量判断s1被按下几次while(!s1); //松手检测if(s1num==1) //S1被第一次按下{TR0=0; //关定时器write_com(0x80+0x40+11); //确定指针位置在秒钟write_com(0x0f); //开显示显示光标光标闪烁}}if(s1num==2){write_com(0x80+0x40+8); //确定指针位置在分钟}if(s1num==3){write_com(0x80+0x40+5); //确定指针位置在时针}if(s1num==4){write_com(0x80+4); //确定指针位置在时针}if(s1num==5){write_com(0x80+7); //确定指针位置在时针}if(s1num==6){write_com(0x80+10); //确定指针位置在时针}if(s1num==7){write_com(0x80+14); //确定指针位置在时针}if(s1num==8){uchar num ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ; //移屏操作write_com(0x18) ;write_com(0x18) ;write_com(0x18) ; //整屏左移同时光标也跟着移动write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x18) ;write_com(0x80+0x40+22); //确定指针位置在时针}if(s1num==9){write_com(0x80+0x40+25); //确定指针位置在时针}if(s1num==10){uchar n;while(n<24){n++; //移屏操作write_com(0x18);}s1num=0;n=0;write_com(0x0c); //结束光标显示表开始走TR0=1;}}}if(s1num!=0) //说明已S1被按下{if(s2==0) //判断S2是否被按下{delay(5); //判断S2是否真被按下if(s2==0); //判断S2是否真被按下{while(!s2); //松手检测if(s1num==1) //判断S1被按下一下{miao++; //秒自加一if(miao==60) //判断miao是否为60miao=0; //秒清零write_sfm(10,miao) ; //把秒数据写到指定位置write_com(0x80+0x40+11); //不让指针向后移}if(s1num==2) //判断S1被按下两下{fen++; //分自加一if(fen==60) //判断fen是否为60fen=0; //fen清零write_sfm(7,fen) ; //把fen数据写到指定位置write_com(0x80+0x40+8); //不让指针向后移}if(s1num==3) //判断S1被按下三下{shi++; //shi自加一if(shi==24) //判断shi是否为24shi=0; //shi清零write_sfm(4,shi) ; //把shi数据写到指定位置write_com(0x80+0x40+5); //不让指针向后移}if(s1num==4) //判断S1被按下四下{nian++; //nian自加一write_sfn(3,nian) ; //把年数据写到指定位置write_com(0x80+4); //不让指针向后移}if(s1num==5) //判断S1被按下五下{yue++; //yue自加一if(yue==13) //使月循环加yue=1;write_sfn(6,yue) ; //把月数据写到指定位置write_com(0x80+7); //不让指针向后移}if(s1num==6) //判断S1被按下六下{tian++; //tian自加一if(yue==1,3,5,7,8,10,12){if(tian==32)tian=1;}if(yue==2){if(tian==29)tian=1;}if(yue==4){if(tian==31) //解决不同的月有不同的天的问题tian=1;}if(yue==6){if(tian==31)tian=1;}if(yue==9){if(tian==31)tian=1;}if(yue==11){if(tian==31)tian=1;}write_sfn(9,tian) ; //把天数据写到指定位置write_com(0x80+10); //不让指针向后移}if(s1num==8) //判断S1被按下八下{nshi++; //闹钟的时自加一if(nshi==24)nshi=0;write_sfm(21,nshi) ;write_com(0x80+0x40+22);}if(s1num==9) //判断S1被按下九下{nfen++; //闹钟的分自加一if(nfen==60) //判断nfen是否为60nfen=0; //nfen清零write_sfm(24,nfen) ; //把nfen数据写到指定位置write_com(0x80+0x40+25); //不让指针向后移}}}if(s1num==7) //判断S1被按下七下{if(s5==0){delay(5);if(s5==0){s5num++;while(!s5);if(s5num==1){write_com(0x80+12);write_date(0x4D);write_com(0x80+13);write_date(0x6F); //写星期一write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==2){write_com(0x80+12);write_date(0x54);write_com(0x80+13); //写星期二write_date(0x75);write_com(0x80+14);write_date(0x65);write_com(0x80+14);}if(s5num==3){write_com(0x80+12);write_date(0x57);write_com(0x80+13);write_date(0x65); //写星期三write_com(0x80+14);write_date(0x64);write_com(0x80+14);}if(s5num==4){write_com(0x80+12);write_date(0x54);write_com(0x80+13);write_date(0x68); //写星期四write_com(0x80+14);write_date(0x75);write_com(0x80+14);}if(s5num==5){write_com(0x80+12);write_date(0x46);write_com(0x80+13);write_date(0x72); //写星期五write_com(0x80+14);write_date(0x69);write_com(0x80+14);}if(s5num==6){write_com(0x80+12);write_date(0x53);write_com(0x80+13);write_date(0x61); //写星期六write_com(0x80+14);write_date(0x74);write_com(0x80+14);}if(s5num==7){write_com(0x80+12);write_date(0x53);write_com(0x80+13);write_date(0x75); //写星期日write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==7){s5num=0;}}}}if(s3==0) //判断S3是否被按下{delay(5); //判断S3是否真被按下if(s3==0) //判断S3是否真被按下{while(!s3); //松手检测if(s1num==1) //判断S1被按下一下{miao--; //秒自减一if(miao==-1) //当秒等于-1时miao=59; //把秒赋值为59write_sfm(10,miao); //把秒数据写到指定位置write_com(0x80+0x40+11); //不让指针向后移}if(s1num==2) //判断S1被按下两下{fen--; //分自减一if(fen==-1) //当分等于-1时fen=59; //把分赋值为59write_sfm(7,fen); //把分数据写到指定位置write_com(0x80+0x40+8); //不让指针向后移}if(s1num==3) //判断S1被按下三下{shi--; //时自减一if(shi==-1) //当时等于-1时shi=23; //把时赋值为59write_sfm(4,shi); //把时数据写到指定位置write_com(0x80+0x40+5); //不让指针向后移}if(s1num==4) //判断S1被按下四下{nian--; //年自减一if(nian==-1){nian=0; //不让年少于2000}write_sfn(3,nian); //把时数据写到指定位置write_com(0x80+4); //不让指针向后移}if(s1num==5) //判断S1被按下五下{yue--; //月自减一if(yue==-1) //当月等于-1时yue=12; //把月赋值为12if(yue==0)yue=12; //解决月第一次减不正确的问题write_sfn(6,yue); //把时数据写到指定位置write_com(0x80+7); //不让指针向后移}if(s1num==6) //判断S1被按下六下{tian--; //天自减一if(yue==2){if(tian==-1)tian=28;if(tian==0)tian=28;}if(yue==4){if(tian==-1)tian=30;if(tian==0) // 解决不同的月有不同的天的问题tian=30;}if(yue==6){if(tian==-1)tian=30;if(tian==0)tian=30;}if(yue==9){if(tian==-1)tian=30;if(tian==0)tian=30;}if(yue==11){if(tian==-1)tian=30;if(tian==0)tian=30;}if(yue==1,3,5,7,8,10,12){if(tian==-1)tian=31;if(tian==0)tian=31;}write_sfn(9,tian); //把时数据写到指定位置write_com(0x80+10); //不让指针向后移}if(s1num==8) //判断S1被按下八下{nshi--; //闹钟的时自减一if(nshi==-1)nshi=23;write_sfm(21,nshi) ; //把nshi数据写到指定位置write_com(0x80+0x40+22); //不让指针向后移}if(s1num==9) //判断S1被按下九下{nfen--; //闹钟的分自加一if(nfen==-1) //判断nfen是否为-1nfen=59; //nfen为59write_sfm(24,nfen) ; //把nfen数据写到指定位置write_com(0x80+0x40+25); //不让指针向后移}}}}}void main() //主函数{init(); //初始化函数while(1){keyscan(); //控制按键}}void timer0() interrupt 1 //中断子函数{TH0=(65536-50000)/256; //重装初值TL0=(65536-50000)%256;count++; //用以计时的变量if(count==20) //判断中断时间是否为一秒{count=0; //为一秒count清零重新计时miao++; //秒加一if(miao==60) //判断miao是否为60{miao=0; //为60miao清零fen++; //fen加一if(fen==60) //判断fen是否为60{fen=0; //为60fen清零shi++; //时加一if(shi==24) //判断shi是否为24{shi=0; //为24shi清零tian++; //天自加一s5num++;if(s5num==1){write_com(0x80+12);write_date(0x4D);write_com(0x80+13);write_date(0x6F); //写星期一write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==2){write_com(0x80+12);write_date(0x54);write_com(0x80+13);write_date(0x75); //写星期二write_com(0x80+14);write_date(0x65);write_com(0x80+14);}if(s5num==3){write_com(0x80+12);write_com(0x80+13);write_date(0x65); //写星期三write_com(0x80+14);write_date(0x64);write_com(0x80+14);}if(s5num==4){write_com(0x80+12);write_date(0x54);write_com(0x80+13);write_date(0x68); //写星期四write_com(0x80+14);write_date(0x75);write_com(0x80+14);}if(s5num==5){write_com(0x80+12);write_date(0x46);write_com(0x80+13);write_date(0x72); //写星期五write_com(0x80+14);write_date(0x69);write_com(0x80+14);}if(s5num==6){write_com(0x80+12);write_date(0x53);write_com(0x80+13);write_date(0x61); //写星期六write_com(0x80+14);write_date(0x74);write_com(0x80+14);}if(s5num==7){write_com(0x80+12);write_com(0x80+13);write_date(0x75); //写星期日write_com(0x80+14);write_date(0x6E);write_com(0x80+14);}if(s5num==7){s5num=1;}if(yue==1,3,5,7,8,10,12){if(tian==32)tian=1;}if(yue==4){if(tian==31) //解决天循环问题tian=1;}if(yue==6){if(tian==31)tian=1;}if(yue==9){if(tian==31)tian=1;}if(yue==11){if(tian==31)tian=1;}if(yue==2){if(tian==29)tian=1;}write_sfn(9,tian); //写天到指定位置if(tian==1){yue++;if(yue==13) //月循环{yue=1;}if(yue==1)nian++;write_sfn(3,nian); //写年到指定位置}write_sfn(6,yue); //写月到指定位置}write_sfm(4,shi); //写小时到指定位置}write_sfm(7,fen); //写分钟到指定位置if(shi==nshi&&fen==nfen){uchar n,s;while(n<60){n++;if(s5==0){ //控制闹钟delay(5);if(s5==0){while(!s5);s++;}}if(s!=1){s=0;a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50); //蜂鸣器的响与断a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);a=0; delay(50);a=1; delay(50);}}if(n==60){fen++;if(fen==60){fen=0; shi++;} write_sfm(4,shi); //闹钟响一分钟分自加一}write_sfm(7,fen); //写分钟到指定位置n=0;s=0;}}}write_sfm(10,miao); //写秒钟到指定位置}。

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】
{
write_date(week6[num]);
delay1();
}
};
break;
}
}
void display() //显示时间子程序
{
write_week(week);
write_ymd(3,year);
write_ymd(6,months);
write_ymd(9,day);
write_sfm(0,shi);
write_sfm(3,fen);
write_sfm(6,miao);
}
void display_1() //显示闹钟子程序
{
write_week(week_1);
write_ymd(3,year1);
write_ymd(6,months1);
write_ymd(9,day1);
write_sfm(0,shi1);
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);
}
void write_week(uchar add) //周几显示
{
switch(add)
{
case 0:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)
{
write_date(week3[num]);
delay1();
}
};
break;
case 4:{
write_com(0x80+12);//设置数据起始地址
for(num=0;num<3;num++)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于52单片机控制的1602液晶电子时钟显示程序
关于利用52单片机制作1602液晶电子时钟显示的程序,网上也有很多资料,不过个人感觉还是挺乱的。

曾经我也是一名初学者,看过很多别人的资料,查找过很多书籍,一个个程序的摸索,经常被弄得头昏脑涨,深受其苦。

今天,我自己精心的整理了一份“基于52单片机控制的1602液晶电子时钟显示程序”的资料,程序每个点几乎都有注释,适合初学者学习,供有兴趣的朋友参考。

也算作为自己一直以来在网上搜索那么多资料而给大家的一点点回报吧。

这程序简单易懂,也有一些可改善的地方,比如写命令和写数据的函数可以合并等等。

大家可根据自己的爱好进行修改,多动手多尝试,相信你很快就能学会。

值得注意的是,1,此程序是利用52单片机控制,如果你的是51单片机,需要改动一下头文件#include<reg51.h> 的。

2,关于引脚,大家需要根据实际情况定义具体的引脚,不同的学习板,或者你自己焊接的板子,引脚都可能不一样。

3,本程序的日期是固定的,自己可以编写函数进行年月日显示。

由于本作者水平有限,错误疏漏之处在所难免,欢迎读者指正。

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^4; //1602使能信号
sbit lcdrs=P3^5; //1602命令(0)/数据(1)选择端
sbit wr=P3^6; //1602读写选择端,一般为低电平(0)
sbit key1=P3^7; //定义功能按键,可根据实际情况改变
sbit key2=P2^0; //数字增加按键,也可根据实际情况改变
sbit dula=P2^6; //关闭实验板上数码管的段选,这两句可根据实际情况注释掉sbit wela=P2^7; //关闭实验板上数码管的段选
uchar temp,num,shi,fen,miao;
uchar code tabe[]="2013-07-20"; //固定日期,可扩展为动态
void delay(uint z) //延时1ms程序
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void write_com(uchar com) //写命令
{
lcdrs=0; //rs为低电平写命令
P0=com;
delay(5);
lcden=1; //高脉冲使能
delay(5);
lcden=0;
}
void write_data(uchar dat) //写数据
{
lcdrs=1; //rs为高电平写数据
P0=dat;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() //初始化
{
EA=1; //开总中断
ET1=1; //开定时器1中断
TMOD=0x10; //设置TMOD参数
TH1=(65536-50000)/256; //给寄存器装初值
TL1=(65536-50000)%256;
TR1=1; //开启定时器1
num=0;
shi=0;
fen=0;
miao=0;
lcden=0;
dula=0;
wela=0;
wr=0; //写,低电平有效
write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
write_com(0x0C); //开显示,这里上下四句话需参考厂家提供的1602参数设置write_com(0x06); //写一个字符后地址指针加1,且光标加1,写一个字符时,整屏不动
write_com(0x01); //显示清屏,数据指针清0
}
void d1602(uchar add,uchar date) //给1602发送地址与数据
{
uchar date2,date1; //拆分个位与十位
date2=date/10;
date1=date%10;
write_com(0x80+0x40+add); //写指令,地址
write_data(date2+0x30);delay(5); //写数据,十位
write_data(date1+0x30);delay(5); //写数据,个位
}
void key() //按键函数
{
if(key1==0)
{
delay(5); //去抖延时
if(key1==0)
{
num++; //功能键按下次数
while(!key1); //松手判断
if(num==1) //第一次按下
{
TR1=0; //关定时器1,时钟暂停
write_com(0x8b+0x40); //地址写到显示秒位置
write_com(0x0f); //控制显示光标,光标闪烁
}
if(num==2) //第二次按下
{
write_com(0x88+0x40); //地址写到显示分位置
}
if(num==3) //第三次按下
{
write_com(0x85+0x40); //地址写到显示时位置
}
if(num==4) //第四次按下
{
num=0;
write_com(0x0c); //开显示,不显示光标,光标也不闪烁
TR1=1; //开启定时器1,时钟继续运行}
}
}
if(num!=0) //当有功能按键按下,才进入下面操作
{
if(key2==0) //增加按键按下,增加时或分或秒
{
delay(10); //去抖
if(key2==0)
{
while(!key2); //松手判断
if(num==1) //当功能键按下的次数是一次
{
miao++;
if(miao==60)
miao=0;
d1602(0x0a,miao); //改变一次,给1602送一次数据
write_com(0x10); //因为上面操作一次,光标加1,
} //这里是光标左移,保证闪烁位置不变
if(num==2)
{
fen++;
if(fen==60)
fen=0;
d1602(0x07,fen);
write_com(0x10);
}
if(num==3)
{
shi++;
if(shi==24)
shi=0;
d1602(0x04,shi);
write_com(0x10);
}
}
}
}
if(num==0) //当功能键没用被按下
{
d1602(0x04,shi); //一直送‘时’数据到相应位置
d1602(0x07,fen); //一直送‘分’数据到相应位置
d1602(0x0a,miao); //一直送‘秒’数据到相应位置}
}
void main() //主函数
{
uchar ctr;
init();
write_com(0x83); //第一行首地址
for(ctr=0;ctr<10;ctr++) //固定不变的日期显示,1602的第一行
{
write_data(tabe[ctr]);
delay(5);
}
write_com(0x86+0x40); //具体地址,写数据‘:’
write_data(':');delay(5);
write_com(0x89+0x40);
write_data(':');delay(5);
while(1)
{
key(); //不断的扫描按键
}
}
void timer() interrupt 3 //中断
{
TH1=(65536-50000)/256; //重装初值
TL1=(65536-50000)%256;
temp++; //累加计数,每次计数为50ms if(temp==20) //20次为1s
{
temp=0; //清零,一定别忘记
miao++; //秒
if(miao==60)
{
miao=0;
fen++; //分
if(fen==60)
{
fen=0;
shi++; //时
if(shi==24)
{
shi=0;
}
}
}
}
}。

相关文档
最新文档