基于51单片机LCD1602数字钟

合集下载

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

基于51单片机DS1302LCD1602数字时钟显示

基于51单片机DS1302LCD1602数字时钟显示
#include <reg51.h>
#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="I LIKE MCU!";
sbit RS=P2^0;
dispaly_string(0x00,lcd_buffer1);
dispaly_string(0x40,lcd_buffer2);
}
}
delay(5);
}
void write_a_byte_tods1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
IO=x&0x01;
sclk=1;
sclk=0;
x=x>>1;
}
}
uchar get_a_byte_fromds1302()
{
uchar i,b=0x00;
for(i=0;i<8;i++)
uchar lcd_buffer2[]={"TIME 00:00:00 "};
uchar datetime[7];
void delay(uchar ms)
{
uchar i;
while(ms--)
for(i=0;i<120;i++);
}
//忙检测
uchar busy()
{
uchar test;
RW=1;
{

基于c51功能最全的电子钟程序(lcd1602)

基于c51功能最全的电子钟程序(lcd1602)

功能最全的电子钟【单片机】c51数字时钟(带年月日显示)摘要:本设计以单片机为核心,lcd1602显示。

采用独立键盘输入能任意修改当前时间日期和设定闹钟时间。

具有显示年月日(区分闰年和二月),闹钟报警和整点报时功能主程序:/********************************************************************************************************************************************************************************* ****************************************** lcd1602电子钟********************************************************************************************************************************** *************************************************************************************************** ********************/# include <reg52.h># include "lcd16024.h"sbit key1 = P2^0; //调整sbit key2 = P2^1; //加1sbit key3 = P2^2; //减1sbit speaker = P2^3; //蜂鸣器sbit key4 = P2^4; //闹钟设计bit cal_year = 1; //进入判断闰年标志位bit leap_year; //闰年标志位bit calculate = 0; //日加一标记bit run = 0; //闹钟标志bit beep = 0; //整点报时标志//uint8 num = 0; //调整是给的脉冲uint8 code str1[] = "D: ";uint8 code str2[] = "T: ";uint8 code str3[] = "Wek";uint8 daystr[]="2013-07-29 "; //年月日格式uint8 timestr[]="21:30:59 N"; //时分秒格式uint8 daystr1[]="2013-07-29 "; //闹钟年月日格式uint8 timestr1[]="21:30:59 N"; //闹钟时分秒格式uint8 numweek = 0; //星期加1标记char week = 1; //星期char sec = 53; //秒char min = 50; //分char hour = 23; //时uint8 day = 30; // 日uint8 month = 9; //月uint16 year = 2013; //年char week1 = 1; //闹钟星期char sec1 = 58; //闹钟秒char min1 = 50; //闹钟分char hour1 = 23; //闹钟时uint8 day1 = 30; //闹钟日uint8 month1 = 9; //闹钟月uint16 year1 = 2013; //闹钟年uint8 WeekData1; //闹钟星期标记uint8 number = 0; //定时uint8 WeekData; //星期标记uint8 speaker_num; //整点报时次数uint8 scan_key(void); //函数声名/****************************************************************************** ***************************** 更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange(){//时分秒timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';timestr[4] = min%10+'0';timestr[3] = min/10+'0';timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';//年月日daystr[9] = day%10+'0';daystr[8] = day/10+'0';daystr[6] = month%10+'0';daystr[5] = month/10+'0';daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';//星期WeekData = week+'0';}/****************************************************************************** ***************************** 闹钟更新LCD时间分离读取******************************************************************************************************************* *******/void TimeChange1(){//时分秒timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';//年月日daystr1[9] = day1%10+'0';daystr1[8] = day1/10+'0';daystr1[6] = month1%10+'0';daystr1[5] = month1/10+'0';daystr1[3] = year1%10+'0';daystr1[2] = year1/10%10+'0';daystr1[1] = year1/100%10+'0';daystr1[0] = year1/1000+'0';//星期WeekData1 = week1+'0';}/****************************************************************************** ***************************** 初始化系统定时器0 ******************************************************************************************************************* *******/void systimer0_init(void){TMOD |=0x01;//设置为1时用或(|)TMOD &=0xfd;//设置为0时用与(&)TH0 = 0xDC; // 定时10msTL0 = 0x00;EA = 1;ET0=1;TR0=1;EX0 = 1;}/****************************************************************************** ***************************** 闹钟时间设置*************************************************************************************************************** *******/void naozhong(){uint8 number = 1;uint8 a = 0;uint8 b = 0;if(0 == key4){Delay1Ms(5);if(0 == key4){a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}while(!key4);}while(a){if(0 == key4){Delay1Ms(5);if(0 == key4){a = 0;run = ~run;while(!key4);}}if(run){timestr[9] = 'Y';}else{timestr[9] = 'N';}if(0 == key1){Delay1Ms(5);if(0 == key1){b = 1;}while(!key1);}while(b){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;if(4 == number)b = 0;}while(!key1);if(number == 1){LCD_write_command(0xc0+9);LCD_write_command(0x0f);}if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}}}switch(number){case 1:if(0 == key2) //闹钟秒加1的设置{Delay1Ms(5);if(0 == key2){sec1++;if(60 == sec1){sec1 = 0;}while(!key2);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}if(0 == key3) //闹钟秒减1的设置Delay1Ms(5);if(0 == key3){sec1--;if(sec1 < 0){sec1 = 59;}while(!key3);timestr1[7] = sec1%10+'0';timestr1[6] = sec1/10+'0';LCD_write_char(8,1,timestr1[6]);LCD_write_char(9,1,timestr1[7]);LCD_write_command(0xc0+9);}}break;case 2:if(0 == key2) //闹钟分加1的设置{Delay1Ms(5);if(0 == key2){min1++;if(60 == min1){min1 = 0;}while(!key2);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}if(0 == key3) //闹钟分减1的设置{Delay1Ms(5);if(0 == key3){min1--;if(min1 < 0){min1 = 59;}while(!key3);timestr1[4] = min1%10+'0';timestr1[3] = min1/10+'0';;LCD_write_char(5,1,timestr1[3]);LCD_write_char(6,1,timestr1[4]);LCD_write_command(0xc0+6);}}break;case 3:if(0 == key2) //闹钟时加1的设置{Delay1Ms(5);if(0 == key2){hour1++;if(24 == hour1){hour1 = 0;}while(!key2);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //闹钟时减1的设置{Delay1Ms(5);if(0 == key3){hour1--;if(hour1 < 0){hour1 = 23;}while(!key3);timestr1[1] = hour1%10+'0';timestr1[0] = hour1/10+'0';LCD_write_char(2,1,timestr1[0]);LCD_write_char(3,1,timestr1[1]);LCD_write_command(0xc0+3);}}break;case 4:b = 0;LCD_write_command(0x0c);break;}}}LCD_write_command(0x0c);while(!key4);}/****************************************************************************** ***************************** 判断按键进入时间调整*************************************************************************************************************** *******/uint8 scan_key(void){uint8 number = 1;uint8 a = 0;if(0 == key1){Delay1Ms(5);if(0 == key1){while(!key1);a = 1;LCD_write_command(0xc0+9);LCD_write_command(0x0f);}}while(a){if(0 == key1){Delay1Ms(5);if(0 == key1){number++;while(!key1);TR0 = 0;if(number == 2){LCD_write_command(0xc0+6);LCD_write_command(0x0f);}if(number == 3){LCD_write_command(0xc0+3);LCD_write_command(0x0f);}if(number == 4){LCD_write_command(0x80+11);LCD_write_command(0x0f);}if(number == 5){LCD_write_command(0x80+8);LCD_write_command(0x0f);}if(number == 6){LCD_write_command(0x80+5);LCD_write_command(0x0f);}if(number == 7){LCD_write_command(0xc0+14);LCD_write_command(0x0f);}if(8 == number){LCD_write_command(0x0c);a = 0;number = 0;}}}switch(number){case 1:if(0 == key2) //秒加1的设置{Delay1Ms(5);if(0 == key2){sec++;if(60 == sec){sec = 0;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key2);}}if(0 == key3) //秒减1的设置{Delay1Ms(5);if(0 == key3){sec--;if(sec < 0){sec = 59;}timestr[7] = sec%10+'0';timestr[6] = sec/10+'0';LCD_write_char(8,1,timestr[6]);LCD_write_char(9,1,timestr[7]);LCD_write_command(0xc0+9);while(!key3);}}break;case 2:if(0 == key2) //分加1的设置{Delay1Ms(5);if(0 == key2){min++;if(60 == min){min = 0;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';;LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key2);}}if(0 == key3) //分减1的设置{Delay1Ms(5);if(0 == key3){min--;if(min < 0){min = 59;}timestr[4] = min%10+'0';timestr[3] = min/10+'0';LCD_write_char(5,1,timestr[3]);LCD_write_char(6,1,timestr[4]);LCD_write_command(0xc0+6);while(!key3);}}break;case 3:if(0 == key2) //时加1的设置{Delay1Ms(5);if(0 == key2){hour++;while(!key2);if(24 == hour){hour = 0;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}if(0 == key3) //时减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);hour--;if(hour < 0){hour = 23;}timestr[1] = hour%10+'0';timestr[0] = hour/10+'0';LCD_write_char(2,1,timestr[0]);LCD_write_char(3,1,timestr[1]);LCD_write_command(0xc0+3);}}break;case 4:if(0 == key2) //日加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(day > 31){day=1;}}if(month==4|month==6|month==9|month==11){day++;if(day > 30){day=1;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day > 30){day=1;}}else{day++;if(day > 29){day=1;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}if(0 == key3) //日减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);calculate = 1;if(calculate == 1){if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day--;if(day == 0){day=31;}}if(month==4|month==6|month==9|month==11){day--;if(day == 0){day=30;}}if(month == 2){cal_year = 1;while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day--;if(day == 0){day=30;}}else{day--;if(day == 0){day=29;}}}calculate = 0;}daystr[9] = day%10+'0';daystr[8] = day/10+'0';LCD_write_char(10,0,daystr[8]);LCD_write_char(11,0,daystr[9]);LCD_write_command(0x80+11);}}break;case 5:if(0 == key2) //月加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);month++;if(13 == month){month = 1;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}if(0 == key3) //月减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);month--;if(month == 0){month = 12;}daystr[6] = month%10+'0';daystr[5] = month/10+'0';LCD_write_char(7,0,daystr[5]);LCD_write_char(8,0,daystr[6]);LCD_write_command(0x80+8);}}break;case 6:if(0 == key2) //年加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);year++;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}if (0 == key3) //年减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);year--;if(year == 0){year = 2020;}daystr[3] = year%10+'0';daystr[2] = year/10%10+'0';daystr[1] = year/100%10+'0';daystr[0] = year/1000+'0';LCD_write_char(2,0,daystr[0]);LCD_write_char(3,0,daystr[1]);LCD_write_char(4,0,daystr[2]);LCD_write_char(5,0,daystr[3]);LCD_write_command(0x80+5);}}break;case 7:if(0 == key2) //星期加1的设置{Delay1Ms(5);if(0 == key2){while(!key2);week++;if(7 == week){week = 0;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}if (0 == key3) //星期减1的设置{Delay1Ms(5);if(0 == key3){while(!key3);week--;if(week < 0){week = 6;}LCD_write_char(14,1,week+'0');LCD_write_command(0xc0+14);}}break;case 8:TR0 = 1;break;}}}/****************************************************************************** ***************************** 主函数******************************************************************************************************************* *******/void main(void){systimer0_init();LCD_init();LCD_write_str(0,0,str1);LCD_write_str(0,1,str2);LCD_write_str(13,0,str3);speaker = 0;while (1){TimeChange();scan_key();naozhong();LCD_write_str(2,0,daystr);LCD_write_str(2,1,timestr);LCD_write_char(14,1,WeekData);if(1 == run){if(sec==sec1 & month==month1 & hour==hour){speaker_num =30;beep = 1;}}else{speaker_num =0;beep = 0;}}}/****************************************************************************** ***************************** 定时中断0 ******************************************************************************************************************* *******/void time_0() interrupt 1{TH0 = 0xDC; // 定时10msTL0 = 0x00;number++;if(number ==100){sec++;if(beep){speaker=!speaker;speaker_num--;if(speaker_num == 0){beep=0;speaker = 0;}}if(sec == 60){sec = 0;min++;if(min == 60){min = 0;hour++; //小时加1speaker_num = hour%12; //蜂鸣器响的次数beep = 1;if(hour == 24){hour = 0;calculate = 1;if(calculate == 1) //判断这个月有多少天{if(month==1|month==3|month==5|month==7|month==8|month==10|month==12){day++;if(month==7|month==12){week++;if(7 == week){week = 0;}}else{if(day <= 31){week++;if(7 == week){week = 0;}}}if(day > 31){if(month==7|month==12){day = 1;}else{day=0;}month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month==4|month==6|month==9|month==11) {day++;week++;if(7 == week){week = 0;}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}if(month == 2){while(cal_year == 1){leap_year = ((year % 4 == 0 && year % 100 != 0)||(year % 400 == 0));cal_year = 0;}if(leap_year==1){day++;if(day <= 30){week++;if(7 == week){week = 0;}}if(day > 30){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}else{day++;week++;if(7 == week){week = 0;}if(day > 29){day=1;month++;if(month > 12){month=1;year++;cal_year=1;}}}}}calculate=0;}}}}}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.c子程序:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /****************************************************************************** ***************************** lcd1602低层函数********************************************************************************************************************* *******/# include <reg52.h># include <intrins.h># include "lcd16024.h"# define LCD_DATA P0 //LCD1602的数据口定义sbit LCD_RS = P0^0; //LCD1602控制线的定义,4位控制方式sbit LCD_RW = P0^1;sbit LCD_EN = P0^2;/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Us(uint16 n){for(;n>0;n--){_nop_();}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void Delay1Ms(uint16 n){while(n--){Delay1Us(1000);}}/****************************************************************************** ***************************** 延时1MS********************************************************************************************************************* *******/void LCD_en_write(void){LCD_EN=0;LCD_EN=1;Delay1Us(1);LCD_EN=0;}/****************************************************************************** ************************ LCD写一个字节命令函数************************************************************************************************************ *******/void LCD_write_command(uint8 command){Delay1Us(16);LCD_RS=0;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();command=command<<4;LCD_DATA&=0x0f;LCD_DATA|=command&0xf0;LCD_en_write();}/****************************************************************************** ********************** LCD写一个字节数据函数*************************************************************************************************************** *******/void LCD_write_data(uint8 Data){Delay1Us(16);LCD_RS=1;LCD_RW=0;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();Data=Data<<4;LCD_DATA&=0x0f;LCD_DATA|=Data&0xf0;LCD_en_write();}/****************************************************************************** ***************************** LCD1602光标定位函数************************************************ x--列0~15;y--行0~1********************************************************************************************************* *******/void LCD_set_xy(uint8 x,uint8 y){uint8 address;if(y==0)address=0x80+x;else address=0xc0+x;LCD_write_command(address);}/***************************************************************************************************** LCD1602 初始化函数,四位显示方式******************************************************************************************************* *******/void LCD_init(){LCD_write_command(0x28);// Delay1Us(40);LCD_write_command(0x28);LCD_write_command(0x0c);LCD_write_command(0x01);LCD_write_command(0x06);Delay1Ms(2);}/****************************************************************************** ***************************** LCD写字符串函数******************************************************* x--列0~15;y--行0~1******************************************************* s指向字符串数组**************************************************************************************************************** *******/void LCD_write_str(uint8 x,uint8 y,uint8 *s){LCD_set_xy(x,y);while(*s){LCD_write_data(*s);s++;}}/****************************************************************************** ***************************** LCD写一个字符函数******************************************************* x--列0~15;y--行0~1******************************************************* d--字符的ASCII码**************************************************************************************************************** *******/void LCD_write_char(uint8 x,uint8 y,uint8 d){LCD_set_xy(x,y);LCD_write_data(d);}/*////////////////////////////////////////////////////////////////// 等待繁忙标志/////////////////////////////////////////////////////////////////void LCD_wait(void){P0 = 0xFF;do{LCD_RS = 0;LCD_RW = 1;LCD_EN = 0;LCD_EN = 1;}while (BUSY == 1);LCD_EN = 0;}*//****************************************************************************** ***************************** LCD1602左移********************************************************************************************************************* *******void LCD_youyi(uint8 y,uint8 *s){LCD_write_str(17,y,s);for(a=0;a<16;a++){LCD_write_command(0x1c); //左移LCD_write_command(0x1c); 为右移Delay1Ms(6);}}*///LCD_write_command(0x0d);//光标闪烁//LCD_write_command(0x0e);//光标显示不闪烁//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Lcd1602.h头文件////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _LCD16024_H_#define _LCD16024_H_typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long uint32;void Delay1Us(uint16 n);void Delay1Ms(uint16 n);void LCD_write_data(uint8 dat);void LCD_write_command(uint8 com); //BuysC为0时忽略忙检测void LCD_set_xy(uint8 x,uint8 y);void LCD_en_write(void);void LCD_write_char(uint8 x, uint8 y, uint8 Data1);void LCD_write_str(uint8 x, uint8 y,uint8 *s);void LCD_init();//void LCD_wait(void);//void LCD_youyi(uint8 y,uint8 *s);#endif。

基于51单片机LCD1602数字钟讲解

基于51单片机LCD1602数字钟讲解

基于51单片机的数字时钟实训单位: 南耕科技系别: 工程技术系专业:姓名:摘要本文介绍了基于AT89C51单片机的数字式时钟的设计,详细叙述了系统硬件、软件的具体实现过程。

本文在硬件、软件设计上均采用模块化的方法,使得在设计和调试方面取得很大的方便。

软件同样采用模块化的设计,包括中断模块、时间调整模块等设计,并采用简单流通性强的C语言编写实现。

本设计实现了时、分、秒的显示和时间修改的功能。

通过对比实际的时钟,查找出误差的来源,确定调整误差的方法,尽可能的减少误差,使得系统可以达到实际数字钟的允许误差范围内。

关键字:AT89C51单片机;数字钟;模块化;目录1 绪论 (1)1.1 课题背景 (1)1.2 课题意义 (2)1.3 数字式时钟的应用 (2)1.4 本章小结 (3)2 单片机简介 (3)2.1 单片机的选择 (3)2.1.1 单片机的特点 (5)2.1.2 单片机的应用领域 (5)2.2 AT89C51单片机的基本结构 (6)2.3 本章小结 (11)3 数字式时钟的硬件设计 (12)3.1 最小系统设计 (13)3.2 数字式时钟的外围电路设计 (14)3.3 本章小结 (19)4 数字式时钟的软件设计 (19)4.1 系统软件设计内容 (19)4.2主程序 (20)4.3时钟设置子程序 (22)4.4中断子程序 (24)4.5 LCD显示子程序 (24)4.6 本章小结 (26)5 数字式时钟的Protues软件仿真 (26)5.1 Protues软件的概述 (26)5.2 Protues软件的功能特点 (27)5.3 Protues软件具有4大功能模块 (27)5.4 数字式时钟的Proteus软件仿真 (29)5.5 本章小结 (35)结论 (36)致谢 (37)单片机介绍 (37)附录 (41)1 绪论1.1 课题背景单片机自1976年由Intel公司推出MCS-48开始,迄今已有二十多年了。

基于51单片机24小时可调时钟1602液晶显示程序

基于51单片机24小时可调时钟1602液晶显示程序

基于51单片机24小时可调时钟1602液晶显示程序#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;sbit key6=P1^5;sbit rs=P0^0; //液晶的第4端RS由开关独立s2 p3^5控制高电平写数据,低电平写命令。

sbit lecdn=P0^1; //使能端需控制LECDN,p3^6控制。

根据硬件电路而定uchar miao ,fen ,shi,num;uchar miao1,miao2,shi1,shi2,fen1,fen2;uchar table[]="0123456789";void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=10;j>0;j--);}void write_com(uchar com )//写指令{P2=com;//RW=0;写指令位定义一个io口控制lecdn=0; //起初为低电平时序图rs=0; //写指令rs为低delay(10); //简短延时lecdn=1; //给以高脉冲delay(5);lecdn=0;}void write_data(uchar shu ) //写数据{P2=shu; //将数据送给控制数据位的io口//RW=0;写指令位定义一个io口控制lecdn=0;rs=1; //写数据rs为低区别delay(10);lecdn=1;delay(5);lecdn=0;}void init() //初始化{write_com(0x38); //显示模式设置delay(20);write_com(0x0f); // 显示开关,和光标设置,开关必开,光标不开ox0c,开并闪烁0x0fdelay(20);write_com(0x06); //写完一个数据,数据地址指针自动往后移动一位delay(20);write_com(0x01); //清屏指令,按下复位键上次的结果变清掉。

基于51单片机与DS1302时钟芯片和LCD1602液晶显示的数字时钟

基于51单片机与DS1302时钟芯片和LCD1602液晶显示的数字时钟

unsigned char DS1302OutputByte(void) {
unsigned char i; for(i=8; i>0; i--) {
ACC = ACC >>1; ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; } return(ACC); }
P3.0/RXD P3.1/TXD P3.2/INT0 P3.3/INT1
P3.4/T0 P3.5/T1 P3.6/WR P3.7/RD
D1 LC
SD E
S V
VD
E V
S R
RW E
0 1 2 3 4 5 67 D D D D D D DD
D N +5V G 39 38
37
36 35
34
33 32
GotoXY(0,0); Print(" tian ma dian zi"); GotoXY(0,1); Print("Time: ");
Word 文档
.
while(1) {
DS1302_GetTime(&CurrentTime); TimeToStr(&CurrentTime); GotoXY(6,1); Print(CurrentTime.TimeString);
unsigned char i; ACC = d; for(i=8; i>0; i--) {
DS1302_IO = ACC0; DS1302_CLK = 1;
// 实时时钟写入一字节 (部函数 ) // 相当于汇编中的 RRC
Word 文档
.
DS1302_CLK = 0; ACC = ACC >> 1; } }

用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开始计时,按秒更新,时分秒可用装置的两个按键进行调节,分别为时间设置键,数值增大键,闹钟的时间设置只能通过程序进行更改,一旦液晶显示时间和程序设定时间完全一致,蜂鸣器发声。

基于51单片机DS1302LCD1602数字时钟显示

基于51单片机DS1302LCD1602数字时钟显示
dispaly_string(0x00,lcd_buffer1);
dispaly_string(0x40,lcd_buffer2);
}
}
sbit RW=P2^1;
sbit EN=P2^2;
sbit IO=P1^0;
sbit sclk=P1^1;
sbit rst=P1^2;
uchar *week[]={"SUN","****","MON","TUS","WEN","THU","FRI","SAT"};
uchar lcd_buffer1[]={"DATE 00-00-00 "};
delay(5);
}
void write_a_byte_tods1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
IO=x&0x01;
sclk=1;
sclk=0;
x=x>>1;
}
}
uchar get_a_byte_fromds1302()
{
uchar i,b=0x00;
for(i=0;i<8;i++)
a[1]=d%10+'0';
}
void main()
{
init();
while(1)
{
gettime();
zhuanhuan(datetime[6],lcd_buffer1+5);
zhuanhuan(datetime[4],lcd_buffer1+8);

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++)

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

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

用51单片机和1602液晶做的数字钟数字钟是人们日常生活中常见的时间显示设备,它能够精确显示当前的时间,并且兼具简约和实用性。

本文将介绍使用51单片机和1602液晶屏幕制作自己的数字钟的方法。

所需材料在开始制作之前,我们需要准备以下材料: - 51单片机开发板 - 1602液晶屏幕 - 数字时钟芯片RTC(Real-Time Clock) - 面包板和导线 - 电阻和电容 - 编程器和烧录器硬件连接首先,我们需要将51单片机、1602液晶屏幕和RTC芯片连接起来。

根据硬件接口的定义和引脚功能的规定,我们可以进行以下连接: - 将51单片机的VCC 引脚连接到1602液晶屏幕的VCC引脚,用于提供电源。

- 将51单片机的GND引脚连接到1602液晶屏幕的GND引脚,用于地线连接。

- 将51单片机的P0口连接到1602液晶屏幕的数据线D0-D7,用于数据传输。

- 将51单片机的P2口连接到1602液晶屏幕的RS引脚,用于选择数据和命令传输。

- 将51单片机的P3口连接到1602液晶屏幕的EN引脚,用于启用LCD。

此外,还需要将RTC芯片连接到51单片机上,以实现时间的准确显示。

具体的连接方式可以参考RTC芯片的规格说明书。

软件编程完成硬件连接后,我们需要进行软件编程,以便控制51单片机、1602液晶屏幕和RTC芯片的功能。

初始化首先,我们需要对51单片机和1602液晶屏幕进行初始化设置。

这包括设置引脚的功能模式、初始化1602液晶屏幕的显示模式和清空显示区域。

读取时间接下来,我们需要通过RTC芯片来读取当前的时间。

这通常包括读取RTC芯片存储的年、月、日、时、分和秒的数据。

显示时间读取时间后,我们可以将其显示在1602液晶屏幕上。

这可以通过更新特定的LCD显示区域来实现。

我们可以在指定的位置、特定的行和列上显示时间。

更新时间为了实现实时的时间显示,我们需要定期更新显示的时间。

可以使用定时器中断来定期更新时间,并根据需要刷新液晶屏幕上的显示。

基于51单片机定时器的1602液晶显示器时钟显示(带年月日)

基于51单片机定时器的1602液晶显示器时钟显示(带年月日)

基于51单片机定时器的1602液晶显示器时钟显示(带年月日)#include#define uchar unsigned char#define uint unsigned intuchar a,count,S1num,xqnum;char yue,ri,shi,fen,miao;int nian;sbit lcdrs=P2^5;sbit lcdrw=P2^4;sbit lcden=P2^3;sbit S1=P3^0; //定义键——进入设置sbit S2=P3^1; //定义键——增大sbit S3=P3^2; //定义键——减小sbit S4=P3^3; //定义键——退出设置uchar code table0[]="2014-08-13 WED";uchar code table1[]="00:00:00";uchar code xingqi[][3]={"MON","TUE","WED","THU","FRI","SAT","SUN"};void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/**************************************************1602液晶显示器模块sbit lcdrs=P2^5;sbit lcdrw=P2^4;sbit lcden=P2^3;*************************************************/ void write_com(uchar com) //液晶写指令{lcdrw=0;lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar dat) //液晶写数据{lcdrw=0;lcdrs=1;P0=dat;delay(5);lcden=1;delay(5);lcden=0;}/********************************************年月日写入1602函数********************************************/void write_sfm(uchar add,uchar dat) //写时分秒函数{ uchar shi,ge;shi=dat/10;ge=dat%10;write_com(0x80+0x40+add);write_data(0x30+shi);write_data(0x30+ge);}void write_yr(uchar add,uchar dat) //写月日函数{uchar shi,ge;shi=dat/10;ge=dat%10;write_com(0x80+add);write_data(0x30+shi);write_data(0x30+ge);}void write_nian(uchar add,uint dat) //写年函数{ uint qian,bai,shi,ge;qian=dat/1000;bai=dat%1000/100;shi=dat%100/10;ge=dat%10;write_com(0x80+add);write_data(0x30+qian);write_data(0x30+bai);write_data(0x30+shi);write_data(0x30+ge);/*************************************************** 初始化***************************************************/ void init_lcd() //液晶初始化{lcden=0;nian=2014;yue=8;ri=13;shi=0; //初始shi、fen、miaofen=0;miao=0;write_com(0x38); //设置16x2显示,5x7点阵,8位数据口write_com(0x0c); //设置开显示,不显示光标write_com(0x06); //写一个字符后地址指针加1write_com(0x01); //显示清0,数据指针清0}void init() //初始化函数{init_lcd(); //液晶初始化write_com(0x80); //设置显示初始坐标for(a=0;a<14;a++) //显示年月日初始值{write_data(table0[a]);delay(5);}write_com(0x80+0x40); //设置显示初始坐标for(a=0;a<8;a++) //显示时分秒初始值{write_data(table1[a]);delay(5);}write_nian(0,nian);write_sfm(6,miao); //分别将shi、fen、miao送去液晶显示write_sfm(3,fen);write_sfm(0,shi);count=0;xqnum=0;S1num=0; //初始化全局变量countTMOD=0x01; //设置定时器0工作模式 1 TH0=(65535-50000)/256; //定时器装初始值TL0=(65535-50000)%256;EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; //启动定时器0}/**************************************************独立键盘sbit S1=P3^0; //定义键——进入设置sbit S2=P3^1; //定义键——增大sbit S3=P3^2; //定义键——减小sbit S4=P3^3; //定义键——退出设置独立键盘已接地*************************************************/void keyscan(){if(S1==0){delay(5); //确认定义键被按下if(S1==0){S1num++; //定义键S1按下次数记录while(!S1); //释放按键确认if(S1num==1) //S1按下一次时{TR0=0; //关闭定时器write_com(0xc0+7); //光标定位到秒位置write_com(0x0f); //光标闪烁}if(S1num==2) //S1按下两次时{write_com(0xc0+4); //光标定位到分位置}if(S1num==3) //S1按下三次时{write_com(0xc0+1); //光标定位到时位置}if(S1num==4) //S1按下四次时{write_com(0x80+13); //光标定位到星期位置}if(S1num==5) //S1按下五次时{write_com(0x80+9); //光标定位到日位置}if(S1num==6) //S1按下六次时{write_com(0x80+6); //光标定位到月位置}if(S1num==7) //S1按下七次时{write_com(0x80+3); //光标定位到年位置}if(S1num==8) //S1按下八次时{S1num=0; //S1记录按键次数清零TR0=1; //开启定时器write_com(0x0c); //取消光标闪烁}}}if(S1num!=0) //只有定义键按下后S2、S3、S4才有效{ if(S2==0){delay(5); //防抖if(S2==0) //确认按键被按下{while(!S2); //释放按键确认if(S1num==1) //S1按下一次时{miao++; //调整秒加1if(miao==60) //满60清零miao=0;write_sfm(6,miao); //每调节一次送液晶显示一次write_com(0x80+0x40+6); //显示位置重新回到调节处} if(S1num==2) //S1按下两次时{fen++; //调整分加1if(fen==60)fen=0;write_sfm(3,fen);write_com(0x80+0x40+3);}if(S1num==3) //S1按下三次时{shi++; //调整时加1if(shi==24)write_com(0x80+0x40); write_sfm(0,shi);}if(S1num==4) //星期加调整{ xqnum++;if(xqnum==7)xqnum=0;write_com(0x80+0x0b);for(a=0;a<3;a++){write_data(xingqi[xqnum][a]); delay(5);}}if(S1num==5) //日加调整{ri++;if(yue==2){if(nian%400==0){if(ri==30){ri=1;}}if(nian%400!=0){if(ri==29){}}}else if(yue<=7){if(yue%2==0&yue!=2) {if(ri==31){ri=1;}}else if(yue%2!=0&yue!=2) {if(ri==32){ri=1;}}}else if(yue>=8){if(yue%2==0){if(ri==32){ri=1;}}else if(yue%2!=0){if(ri==31){ri=1;}}}write_yr(8,ri);}if(S1num==6) //月加调整{ yue++;if(yue==13)yue=1;write_yr(5,yue);}if(S1num==7) //年加调整{ nian++;if(nian==2019)nian=2014;write_nian(0,nian);}}}if(S3==0){delay(5);if(S3==0) //确认按键被按下{while(!S3);if(S1num==1){miao--; //调整秒减1if(miao==-1) //减到00后再减重新设置为59 miao=59;write_sfm(6,miao);write_com(0x80+0x40+6);}if(S1num==2){fen--; //调整分减1if(fen==-1)fen=59;write_sfm(3,fen);write_com(0x80+0x40+3);}if(S1num==3){shi--; //调整时减1if(shi==-1)shi=23;write_sfm(0,shi);write_com(0x80+0x40);}if(S1num==4){xqnum--; //调整星期减一if(xqnum==-1)xqnum=6;write_com(0x80+0x0b);for(a=0;a<3;a++){write_data(xingqi[xqnum][a]); delay(5);}}if(S1num==5) //调整日{ri--;if(yue==2){if(nian%400==0){if(ri==0){ri=29;}}if(nian%400!=0){if(ri==0){ri=28;}}}else if(yue<=7){if(yue%2==0&yue!=2){if(ri==0)ri=30;}}else if(yue%2!=0&yue!=2) {if(ri==0){ri=31;}}}else if(yue>=8){if(yue%2==0){if(ri==0){ri=31;}}else if(yue%2!=0){if(ri==0){ri=30;}}}write_yr(8,ri);if(S1num==6) //调整月{yue--;if(yue==0)yue=12;write_yr(5,yue);}if(S1num==7) //调整年{nian--;if(nian==2013)nian=2018;write_nian(0,nian);}}}if(S4==0) //退出设置、开启中断{delay(5);if(S4==0){S1num=0;TR0=1;write_com(0x0c);}}}}/**************************************************定时器0*************************************************/void timer0() interrupt 1 //定时器0中断服务程序{TH0=(65535-50000)/256; //重装定时器初始值TL0=(65535-50000)%256;count++; //中断次数累加if(count==20) //20次50毫秒即一秒{count=0;miao++;if(miao==60) //秒加到60时分进位{miao=0;fen++;if(fen==60) //分加到60时时进位{fen=0;shi++;if(shi==24) //时加到24时清0{shi=0;xqnum++;ri++;if(yue==2) //如果是二月{if(nian%400==0) //闰年判断{if(ri==30){ri=1;yue++;write_yr(5,yue);}}if(nian%400!=0) //平年判断{if(ri==29){ri=1;yue++;write_yr(5,yue);}}}else if(yue<=7&yue!=2) //一月到七月{if(yue%2==0) //偶数月(除二月){if(ri==31){ri=1;yue++;}}else if(yue%2!=0) //奇数月{if(ri==32){ri=1;yue++;}}write_yr(5,yue);}else if(yue>=8) //八月到12月{if(yue%2==0) //偶数月(除二月){if(ri==32){ri=1;yue++;if(yue==13) //如果判断月份为12月,则加一后重新定义月份为1{yue=1;nian++;write_nian(0,nian);}write_yr(5,yue);}}else if(yue%2!=0) //奇数月{if(ri==31){ri=1;yue++;write_yr(5,yue);}}}write_yr(8,ri);if(xqnum==7) //星期写入xqnum=0;write_com(0x80+0x0b);for(a=0;a<3;a++){write_data(xingqi[xqnum][a]);delay(5);}}write_sfm(0,shi); //重新写入数据}write_sfm(3,fen); //重新写入数据}write_sfm(6,miao); //重新写入数据}}/************************************************* 主函数*************************************************/ void main(){init();while(1){keyscan(); //不停的检测按键是否被按下}}。

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

51单片机控制基于1602液晶显示 电子时钟【带闹铃和整点报时】
void buzz_pro(uchar be)//蜂鸣器发声函数
{
switch(be)
{//uint i;
/*用于整点响铃*/case 0:{
buzz=~buzz;
//delay1();
}break;
/*用于闹铃报时*/case 1:{
buzz=~buzz;
//delay(10);
}break;
}
}
void write_com(uchar com)//命令写入函数
{
rs=0;
delay(3);
P0=com;
delay(3);
lcden=1;
delay(3);
lcden=0;
}
void write_date(uchar date)//数据写入函数
{
rs=1;
delay(3);
P0=date;
delay(3);
write_date(0x30+ge);
}
void write_ymd(uchar add,uchar date)//年月日写入子程序
{
uchar sh,ge;
sh=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+sh);
write_date(0x30+ge);
sbit buzz=P1^5; //蜂鸣器控制端
uchar code week0[]="Sun";
uchar code week1[]="Mon";
uchar code week2[]="Tue";

基于51单片机LCD1602数字时钟演示ppt

基于51单片机LCD1602数字时钟演示ppt

液晶屏LCD1602和单片机的接口
要使液晶屏正常工作,首先要让它接上外部的供电电 源,我们把VSS接地,VDD和VEE接5V的正电源。 让RS、RW、E分别接上单片机的P2.0、P2.1和P2.2 ,让单片机控制数据写入液晶屏中。单片机的P0.0— P0.7分别接上液晶屏的D0—D7引脚,进行数据的传输 ,液晶屏就可以显示单片机所发送过来的数据了。
本设计采取的模块
本设计采取的字符型液晶模块是一种常用5*7 点阵图形、2行16个字来显示字符的液晶显示 器LCD1602,如图所示。 每位之间有一个点 距的间隔,每行之间也有间隔起到了字符间距 和行间距的作用,该模块还配有3个按键,可 设置温度控制值。
Байду номын сангаас
引脚接口说明: 第1脚:VSS为地电源。 第2脚:VDD接5V正电源。 第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对 比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器 调整对比度。 第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令 寄存器。 第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。 当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平 R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数 据。 第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命 令。 第7~14脚:D0~D7为8位双向数据线。 第15脚:背光源正极。 第16脚:背光源负极。
液晶显示器的分类
液晶显示的分类方法有很多种,通常可 按其显示方式分为段式、字符式、点阵式 等。除了黑白显示外,液晶显示器还有多 灰度有彩色显示等。如果根据驱动方式来 分,可以分为静态驱动(Static)、单纯矩 阵驱动(Simple Matrix)和主动矩阵驱动 (Active Matrix)三种。据显示内容可分为 1行16个字、2行16个字、2行20个字等。 巧的诸多优点在袖珍式仪表和低功耗应用 系统中得到越来越来广泛的应用。

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

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

基于单片机的LCD1602电子时钟设计近年来,随着物联网和智能设备的快速发展,电子时钟作为一种常见的智能设备,广泛应用于家庭、办公室等各种场合。

本文将基于单片机设计一款LCD1602电子时钟,实现时间显示、闹钟设置等功能。

一、硬件设计1.单片机选择在本设计中,选择常用的51系列单片机AT89C51,具有丰富的外设资源和强大的处理能力。

该单片机具有8位数据总线、16位地址总线,并且集成了定时/计数器、中断控制器和串行通信接口等外设。

2.显示模块选择3.时钟模块选择通过接入DS1302时钟模块,可以实现实时时钟的功能。

DS1302模块具有时钟计数器、电压检测电路、串行通信接口等,并且具有低功耗特点。

4.控制板设计根据LCD1602的引脚连接方式,设计一个控制板,用于将单片机、显示模块和时钟模块等连接在一起。

同时,需注意设计供电电路、外设输入输出电平等电路。

二、软件设计1.初始化设置通过单片机的GPIO口配置,将LCD1602和DS1302对应的引脚设置为输出模式,同时初始化LCD显示屏并进行清屏操作。

此外,需设置DS1302时钟模块的时钟、日期、闹钟等参数。

2.时间显示通过读取DS1302时钟模块的计数器,获得当前的小时、分钟和秒数,然后将其格式化为HH:MM:SS的形式,并通过LCD显示出来。

3.时间设置通过单片机的外部中断,当用户按下设置按钮后,进入时间设置模式。

在时间设置模式下,用户可以通过按下不同的按键来调整小时、分钟和秒数。

调整完成后,再次按下设置按钮即可保存设置。

4.闹钟设置通过单片机的定时器中断,设定一个闹钟定时器。

当闹钟定时器触发时,触发相应的中断,然后通过LCD显示闹钟提示。

此外,用户也可以通过按下按钮来设置闹钟时间,并通过单片机的外部中断进行处理。

5.闹钟响铃当闹钟时间到达时,触发相应的中断,通过LCD显示闹钟提示,并通过蜂鸣器发出响铃声。

总结通过本设计,可以实现一款功能齐全的LCD1602电子时钟。

通过51单片机实现电子时钟功能并通过LCD1602显示

通过51单片机实现电子时钟功能并通过LCD1602显示

通过51单片机实现电子时钟功能并通过LCD1602显示通过51 单片机实现时钟功能并通过LCD1602 显示.rar 工程文件点击下载实验截图如下:实验中涉及的硬件:51 单片机,LCD1602 模块,EEPROMAT24C02 型号一个,按键3 个,蜂鸣器一个其中LCD1602 模块引脚定义如下:EEPROM 引脚连接情况如下:软件环境:uVision4(Keil_C51_V9.00(点击下载)). rar,Win7Sp1X64 源代码如下:****************************************************************author:lee yangdata:2011/11/12e-mail;liyangdut@live 硬件接口定义:sda P2; scl P2;s1=P3; //定义按键--功能键sbit s2=P3;//定义按键--增加键sbit s3=P3 ;//定义按键--减小键sbit rs=P2;//定义1602 液晶RS 端sbit lcden=P2;//定义1602 液晶LCDEN 端sbit rw=P2 ; //定义1602 液晶R/W 端sbit beep=P2;//定义蜂鸣器端**********************************************************************#include//包含52 单片机头文件#define uchar unsigned char#define uint unsigned intbit write=0; //写24C02 的标志;sbit sda=P2; sbit scl=P2;vo i d delay0() { ;; }void start() //开始信号{sda=1;delay0();scl=1;delay0();sda=0;delay0();}void stop() //停止{sda=0;delay0();scl=1;delay0();sda=1;delay0();}void respons() //应答{uchari;scl=1;delay0();while((sda==1)&&(idelay0();sda=CY;delay0();scl=1;delay0();}scl= 0;delay0();sda=1;delay0();}uchar read_byte()//读一个字节函数{uchar i,k;scl=0;delay0();sda=1;delay0();for(i=0;i<8;i++){scl=1;delay0();k=(k<<1)|sda;scl= 0;delay0();}return k;}void write_add(uchar address,uchar date)//指定地址写一个字节{start();write_byte(0xa0);respons();write_byte(address);respons();write_byte(date);。

基于51单片机的用 LCD1602 显示时钟的程序

基于51单片机的用 LCD1602 显示时钟的程序

用LCD1602 显示的时钟2012-04-30 15:04有这样一个题目:求一个为51 单片机编写的LCD 电子时钟的设计,简单就好!希望说一下怎么设计这个时钟,都需要些什么东西,最重要的——把这个设计需要的程序写出来。

设计的任务:以单片机控制的时钟,在LCD 显示器上显示当前的时间。

设计的基本要求:1.使用文字型LCD 显示器显示当前时间。

2.显示格式为“时时:分分:秒秒”。

3.用4个功能键操作来设置当前时间。

各个功能键的功能如下:K1:进入设置现在的时间。

K2:设置小时。

K3:设置分钟。

K4:确认完成设置。

4. 程序执行后工作指示灯LED 闪烁,表示程序开始执行,LCD 显示“00:00:00”,然后开始计时。

题目链接:/question/416705477.html//==================================================提到设计时钟,很多人都想到了时钟芯片DS1302,都说它简单、准确。

其实,这是个误区。

仅仅使用一般的单片机,简单的编程,达到相同DS1302 的准确度,并不是难事。

如果不要求计算平闰年、不要求分清大小月、不要求计算星期几,只是要求一个简单的时钟(及日历),用DS1302,就是自寻烦恼。

大家可以打开题目链接,看看其中的一些答案,就可以看出使用DS1302 是多么的繁琐了,简直就是一场噩梦。

做而论道以前就使用普通的单片机和LCD1602 设计过《时钟与日历》,程序设计的非常合理,时间精度就完全取决于晶振的精度。

设计出来的时钟,几个月都差不上一秒。

针对这个题目,做而论道翻出了以前的设计,删节了一些不需要的功能,设计出了符合题目要求的时钟,用PROTEUS 仿真截图如下:程序用C 语言编写,全部代码如下://---------------------------------------------------#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define KEY_IO P3#define LCD_IO P0sbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;sbit SPK = P1^2;sbit LED = P2^4;bit new_s, modify = 0;char t0, sec = 50, min = 59, hour = 23;char code LCD_line1[] = "Designed by ZELD"; char code LCD_line2[] = "Timer: 00:00:00 "; char Timer_buf[] = "23:59:50";//---------------------------------------------------void delay(uint z){uint x, y;for(x = z; x > 0; x--) for(y = 100; y > 0; y--);//---------------------------------------------------void W_LCD_Com(uchar com) //写指令{LCD_RS = 0; LCD_IO = com; // LCD_RS和R/W都为低电平时,写入指令LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_Dat(uchar dat) //写数据{LCD_RS = 1; LCD_IO = dat; // LCD_RS为高、R/W为低时,写入数据LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲}//---------------------------------------------------void W_LCD_STR(uchar *s) //写字符串{while(*s) W_LCD_Dat(*s++);}//---------------------------------------------------void W_BUFF(void) //填写显示缓冲区{Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);}//---------------------------------------------------uchar read_key(void){uchar x1, x2;KEY_IO = 255;x1 = KEY_IO;if (x1 != 255) {delay(100);x2 = KEY_IO;if (x1 != x2) return 255;while(x2 != 255) x2 = KEY_IO;if (x1 == 0x7f) return 0;else if (x1 == 0xbf) return 1;else if (x1 == 0xdf) return 2;else if (x1 == 0xef) return 3;else if (x1 == 0xf7) return 4;}return 255;//---------------------------------------------------void Init(){LCD_RW = 0;W_LCD_Com(0x38); delay(50);W_LCD_Com(0x0c);W_LCD_Com(0x06);W_LCD_Com(0x01);W_LCD_Com(0x80); W_LCD_STR(LCD_line1);W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);TMOD = 0x01; //T0定时方式1TH0 = 0x4c;TR0 = 1; //启动T0PT0 = 1; //高优先级, 以保证定时精度ET0 = 1;EA = 1;}//---------------------------------------------------void main(){uint i, j;uchar Key;Init();while(1) {//-------------------------------if (new_s) { //如果出现了新的一秒, 修改时间new_s = 0; sec++; sec %= 60;if(!sec) { min++; min %= 60;if(!min) { hour++; hour %= 24;}}W_BUFF(); //写显示//-------------------------------if (!sec && !min) { //整点报时for (i = 0; i < 200; i++) {SPK = 0; for (j = 0; j < 100; j++);SPK = 1; for (j = 0; j < 100; j++);} }}//-------------------------------Key = read_key(); //读出按键switch(Key) { //分别处理四个按键case 0: modify = 1; break;case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}case 3: modify = 0; break;} }}//---------------------------------------------------void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次{TH0 = 0x4c;t0++; t0 %= 20; //20, 一秒钟if(t0 == 0) {new_s = 1; LED = ~LED;}if(modify) LED = 0;}//===================================================呵呵,全部程序,也不过120 行左右。

基于51单片机的液晶LCD1602显示程序源代码(带LCD1602液晶接口电路))

基于51单片机的液晶LCD1602显示程序源代码(带LCD1602液晶接口电路))

液晶LCD1602显示字符和数字程序源代码/***********************液晶LCD1602测试程序源代码*************************单片机型号:STC15W4K56S4,内部晶振:22.1184M。

功能:液晶LCD1602显示功能测试。

操作说明:液晶LCD1602显示字符和倒计时。

**************************************************************************/#include "stc15.h" //包含头文件stc15.h#include <intrins.h> //包含头文件intrins.h#define Busy 0x80 //LCD忙sbit LCD_D0 = P0^0; //LCD_D0对应P0.0sbit LCD_D1 = P0^1; //LCD_D1对应P0.1sbit LCD_D2 = P0^2; //LCD_D2对应P0.2sbit LCD_D3 = P0^3; //LCD_D3对应P0.3sbit LCD_D4 = P0^4; //LCD_D4对应P0.4sbit LCD_D5 = P0^5; //LCD_D5对应P0.5sbit LCD_D6 = P0^6; //LCD_D6对应P0.6sbit LCD_D7 = P0^7; //LCD_D7对应P0.7sbit LCD_RS = P1^0; //LCD_RS对应P1.0sbit LCD_RW = P1^1; //LCD_RW对应P1.1sbit LCD_EN = P3^4; //LCD_EN对应P3.4void delay(unsigned int t); //delay延时函数void delay_us(unsigned int t); //delay_us延时函数void delay_ms(unsigned int t); //delay_ms延时函数void Delay5Ms(void); //5Ms延时函数void GPIO_1602_Configuration(void); //LCD1602液晶IO口初始化void WriteDataLCD(unsigned char WDLCD); //LCD写数据函数void WriteCommandLCD(unsigned char WCLCD,BuysC); //LCD写命令函数unsigned char ReadDataLCD(void); //LCD读数据函数unsigned char ReadStatusLCD(void); //LCD读状态函数void LCDInit(void); //LCD初始化void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);//LCD显示一个字符void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//LCD显示一个字符串unsigned char code welcome[] = {"Hello My Friends"};//液晶LCD1602显示Hello My Friendsunsigned char code countdown[] = {"CountDown: S"};//液晶LCD1602显示CountDown: Svoid delay(unsigned int t) //delay延时函数{while(t--);}void delay_us(unsigned int t) //delay_us延时函数{unsigned char i;while(t--){i=3;while(i--)delay(1);}}void delay_ms(unsigned int t) //delay_ms延时函数{while(t--){delay_us(t);}}void Delay5Ms(void) //5ms延时函数{unsigned int TempCyc = 3552;while(TempCyc--);}void GPIO_1602_Configuration(void) //LCD1602液晶IO口初始化{P0M1 = P3M1&0x00;P0M0 = P3M0&0x00;P1M1 = P3M1&0xfc;P1M0 = P3M0&0xfc;P3M1 = P4M1&0xef;P3M0 = P4M0&0xef;}unsigned char ReadStatusLCD(void) //测试LCD忙碌状态{LCD_D7 = 1; //LCD的D7置1LCD_RS = 0; //LCD管脚RS设置成低电平LCD_RW = 1; //LCD管脚RW设置成高电平LCD_EN = 0; //LCD管脚E设置成低电平LCD_EN = 0; //LCD管脚E设置成低电平LCD_EN = 1; //LCD管脚E设置成高电平while(LCD_D7); //检测忙信号return(Busy); //表示当前忙}void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if(BuysC) ReadStatusLCD(); //根据需要检测忙LCD_EN = 0; //LCD管脚E设置成低电平_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_RS = 0; //LCD管脚RS设置成低电平LCD_RW = 0; //LCD管脚RW设置成低电平_nop_(); //空操作,延时_nop_(); //空操作,延时P0 = WCLCD; //将数据送入P0口,即写入指令或地址_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 1; //E置高电平_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 0;//当E由高电平跳变成低电平时,液晶模块开始执行命令}void WriteDataLCD(unsigned char WDLCD) //LCD写数据函数{ReadStatusLCD(); //读取LCD状态LCD_EN = 0; //LCD管脚E设置成低电平_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_RS = 1; //LCD管脚RS设置成高电平LCD_RW = 0; //LCD管脚RW设置成低电平P0 = WDLCD;//将数据送入P0口,即将数据写入液晶模块_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 1; //E置高电平_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时_nop_(); //空操作,延时LCD_EN = 0;//当E由高电平跳变成低电平时,液晶模块开始执行命令}void LCDInit(void) //LCD初始化{WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); //显示光标移动设置WriteCommandLCD(0x0C,1); //显示开及光标设置}void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCD(X,0); //这里不检测忙信号,发送地址码WriteDataLCD(DData); //发送数据}void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData){unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1 while (DData[ListLength]>=0x20) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}void main(void){GPIO_1602_Configuration(); //LCD1602液晶IO口初始化delay_ms(10); //延时LCDInit(); //LCD1602初始化delay_ms(10); //延时DisplayListChar(0,0,welcome); //LCD1602显示Hello My Friends delay_ms(10); //延时DisplayListChar(0,1,countdown); //LCD1602显示CountDown: S delay_ms(10); //延时DisplayOneChar(14,1,0x39); //LCD1602显示9delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x38); //LCD1602显示8delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x37); //LCD1602显示7delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x36); //LCD1602显示6delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x35); //LCD1602显示5delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x34); //LCD1602显示4delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x33); //LCD1602显示3delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x32); //LCD1602显示2delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x31); //LCD1602显示1delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时DisplayOneChar(14,1,0x30); //LCD1602显示0delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200);delay_ms(200); //延时while(1){;}}程序源代码是编译通过并在电路板上测试过参考液晶LCD1602接口电路图该程序的实际运行效果。

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

基于51单片机的数字时钟实训单位: 南耕科技系别: 工程技术系专业:姓名:摘要本文介绍了基于AT89C51单片机的数字式时钟的设计,详细叙述了系统硬件、软件的具体实现过程。

本文在硬件、软件设计上均采用模块化的方法,使得在设计和调试方面取得很大的方便。

软件同样采用模块化的设计,包括中断模块、时间调整模块等设计,并采用简单流通性强的C语言编写实现。

本设计实现了时、分、秒的显示和时间修改的功能。

通过对比实际的时钟,查找出误差的来源,确定调整误差的方法,尽可能的减少误差,使得系统可以达到实际数字钟的允许误差范围内。

关键字:AT89C51单片机;数字钟;模块化;目录1 绪论 (1)1.1 课题背景 (1)1.2 课题意义 (2)1.3 数字式时钟的应用 (2)1.4 本章小结 (3)2 单片机简介 (3)2.1 单片机的选择 (3)2.1.1 单片机的特点 (5)2.1.2 单片机的应用领域 (5)2.2 AT89C51单片机的基本结构 (6)2.3 本章小结 (11)3 数字式时钟的硬件设计 (12)3.1 最小系统设计 (13)3.2 数字式时钟的外围电路设计 (14)3.3 本章小结 (19)4 数字式时钟的软件设计 (19)4.1 系统软件设计内容 (19)4.2主程序 (20)4.3时钟设置子程序 (22)4.4中断子程序 (24)4.5 LCD显示子程序 (24)4.6 本章小结 (26)5 数字式时钟的Protues软件仿真 (26)5.1 Protues软件的概述 (26)5.2 Protues软件的功能特点 (27)5.3 Protues软件具有4大功能模块 (27)5.4 数字式时钟的Proteus软件仿真 (29)5.5 本章小结 (35)结论 (36)致谢 (37)单片机介绍 (37)附录 (41)1 绪论1.1 课题背景单片机自1976年由Intel公司推出MCS-48开始,迄今已有二十多年了。

由于单片机集成度高、功能强、可靠性高、体积小、功耗低、使用方便、价格低廉等一系列优点,目前已经渗入到人们工作和生活的各个方面,几乎“无处不在,无所不为”。

单片机的应用领域已从面向工业控制、通讯、交通、智能仪表等迅速发展到家用消费产品、办公自动化、汽车电子、PC机外围以及网络通讯等广大领域。

单片机有两种基本机构形式:一种是在通用微型计算机中广泛采用的,将程序存储器和数据存储器合用一个存储空间的结构,称为普林斯顿结构。

另一种是将程序存储器和数据存储器截然分开,分别寻址的结构,一般需要较大的程序存储器,目前的单片机以采用程序存储器和数据存储器截然分开的结构为多。

本文讨论的单片机多功能定时器的核心是目前应用极为广泛的51系列单片机,配置了外围设备,构成了一个可编程的计时定时系统,具有体积小,可靠性高,功能强等特点。

不仅能满足所需要求,而且还有很多功能可供开发,有着广泛的应用领域。

20世纪80年代中期以后,Intel公司以专利转让的形式把8051内核技术转让给许多半导体芯片生产厂家,如ATMEL、PHILPS、ANALOG、DEVICES、DALLAS等。

这些厂家生产的芯片是MCS-51系列的兼容产品,准确地说是与MCS-51指令系统兼容的单片机。

这些兼容机与8051的系统机构(主要是指令系统)相同,采用CMOS 工艺。

因而,常用80C51系列来称呼所有具有8051指令系统的单片机,它们对8051单片机一般都作了一些扩充,更有特点。

其功能和市场竞争力更强,不该把它们直接称为MCS-51单片机,因而MCS只是Intel公司专用的单片机系列型号。

MCS-51系列及80C51单片机有很多种品种。

它们引脚及指令系统相互兼容,主要在内部结构上有些区别。

目前使用的MCS-51系列单片机及其兼容产品通常分为以下几类:基本型、增强型、低功耗型、专用型、超8位型、片内闪烁存储器型。

1.2 课题意义在日常生活和工作中,我们常常用到定时控制,如扩印过程中的曝光定时等。

早期常用的一些时间控制单元都使用模拟电路设计制作的,其定时准确性和重复精度都不是很理想,现在基本上都是基于数字技术的新一代产品,随着单片机性能价格比的不断提高,新一代产品的应用也越来越广泛,大可构成复杂的工业过程控制系统,完成复杂的控制功能。

小则可以用于家电控制,甚至可以用于儿童电子玩具。

它功能强大,体积小,质量轻,灵活好用,配以适当的接口芯片,可以构造各种各样、功能各异的微电子产品。

随着电子技术的飞速发展,家用电器和办公电子设备逐渐增多,不同的设备都有自己的控制器,使用起来很不方便。

根据这种实际情况,设计了一个单片机多功能定时系统,他可以避免多种控制器的混淆,利用一个控制器对多路电器进行控制,同时又可以进行时钟校准和定点打铃。

它可以执行不同的时间表(考试时间和日常作息时间)的打铃,可以任意设置时间。

这种具有人们所需要的智能化特性的产品减轻了人的劳动,扩大了数字化的范围,为家庭数字化提供了可能。

1.3 数字式时钟的应用数字点钟具有走时准确,一钟多用等特点,在生活中已经得到广泛的应用。

虽然现在市场上已有现成的电子钟集成电路芯片出售,价格便宜、使用也方便,但是人们对电子产品的应用要求越来越高,数字钟不但显示当前的时间,而且可以显示日期、农历、以及星期等,给人们的生活带来了方便。

另外数字钟还具备秒表和闹钟的功能,且闹钟铃声可自选,使一款电子钟具备了多媒体的色彩。

时间对人们来说总是那么宝贵,工作的忙碌性和繁杂性容易使人忘记当前时间。

忘记了要做的事情,当事情不是很重要的时候,这种遗憾无伤大雅。

但是一旦重要事情,一时的耽误可能酿成大祸。

电子钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及车站、码头、剧院、办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。

由于数字集成电路技术的发展和采用了先进的石英技术,使电子钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。

1.4 本章小结本章主要介绍了单片机的历史发展过程,单片机的产生与发展给人们带来了那些影响。

以及数字钟在日常生活中的具体应用给日常生活带来的方便。

2 单片机简介本次设计的主要思想:使用整个单片机作为中央控制器,由单片机执行采集时钟芯片的时间信号并通过显示模块来输出信号及相关的控制功能。

时钟芯片产生时钟信号,利用单片机的I/O口传输给单片机;并通过I/O口实现LCD的显示。

系统设有4个按键可以对时、分、秒、进行调整。

整个框图如图2-1所示。

图2-1 系统整体框图2.1 单片机的选择随着计算机及电子技术的飞跃发展,单片机也在不断更新换代,并成为电子系统中进行数据采集,信息处理,通信联络和实施控制的重要器件。

单片机技术已渗入到了各个领域,在智能仪器仪表,工业监测控制,电力电子,汽车电子等方面得到了广泛的应用,并取得了巨大的成果。

在今后若干年,MCS-51单片机的应用仍将占主要地位,仍然是我国单片机应用领域的主流机型。

现今各个领域的工程技术人员都应掌握单片机应用技术。

单片机是指一个集成在一块芯片上的完整计算机系统。

尽管它的大部分功能集成在一块小芯片上,但是它具有一个完整计算机所需要的大部分部件CPU、内存内部和外部总线系统。

单片机是将中央处理器,随机存储器。

只读存储器,定时器芯片和I/O接口电路集成于一个芯片上的微控制器。

单片机也被称为微控制器(Microcontroler),是因为它最早被用在工业控制领域。

单片机由芯片内仅有CPU的专用处理器发展而来。

最早的设计理念是通过将大量外围设备和CPU集成在一个芯片中,使计算机系统更小,更容易集成进复杂的而对提及要求严格的控制设备当中。

INTEL的Z80是最早按照这种思想设计出的处理器,从此以后,单片机和专用处理器的发展便分道扬镳。

单片机是靠程序的,并且可以修改。

通过不同的程序实现不同的功能,尤其是特殊的独特的一些功能,这是别的器件需要费很大力气才能做到的,有些则是花大力气也很难做到的。

一个不是很复杂的功能要是用美国50年代开发的74系列,或者60年代的CD4000系列这些纯硬件来搞定的话,电路一定是一块大PCB板!但是如果要是用美国70年代成功投放市场的系列单片机,结果就会有天壤之别!只因为单片机是通过你编写的程序可以实现高智能,高效率,以及高可靠性!单片机的组成如图2-2:图 2-2 单片机组成框图目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。

导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统,录象机、摄象机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不开单片机。

更不用说自动控制领域的机器人、智能仪表、医疗器械了。

因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。

2.1.1 单片机的特点(1)控制性能和可靠性高实时控制功能特别强,其CPU可以对I/O端口直接进行操作,位操作能力更是其它计算机无法比拟的。

另外,由于CPU、存储器及I/O接口集成在同一芯片内,各部件间的连接紧凑,数据在传送时受干扰的影响较小,且不易受环境条件的影响,所以单片机的可靠性非常高。

近期推出的单片机产品,内部集成有高速I/O口、ADC、PWM、WDT等部件,并在低电压、低功耗、串行扩展总线、控制网络总线和开发方式(如在系统编程ISP)等方面都有了进一步的增强。

(2)体积小、价格低、易于产品化单片机芯片即是一台完整的微型计算机,对于批量大的专用场合,一方面可以在众多的单片机品种间进行匹配选择;同时还可以专门进行芯片设计,使芯片的功能与应用具有良好的对应关系;在单片机产品的引脚封装方面,有的单片机引脚已减少到8个或更少,从而使应用系统的印制板减小、接插件减少、安装简单方便。

2.1.2 单片机的应用领域单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域,大致可分如下几个范畴:(1)在智能仪器仪表上的应用单片机具有体积小、功耗低、控制功能强、扩展灵活、微型化和使用方便等优点,广泛应用于仪器仪表中,结合不同类型的传感器,可实现诸如电压、功率、频率、湿度、温度、流量、速度、厚度、角度、长度、硬度、元素、压力等物理量的测量。

采用单片机控制使得仪器仪表数字化、智能化、微型化,且功能比起采用电子或数字电路更加强大。

例如精密的测量设备(功率计,示波器,各种分析仪)。

(2)在工业控制中的应用用单片机可以构成形式多样的控制系统、数据采集系统。

例如工厂流水线的智能化管理,电梯智能化控制、各种报警系统,与计算机联网构成二级控制系统等。

相关文档
最新文档