我是刚学的单片机,利用单片机实现了可调时钟可能还有许多做的不好的地方,希望各位大神指正。

其实实现可调时钟用到的51单片机的内容也不多,需要学习蜂鸣器,按键控制,延时函数,定时器中断,还有最重要的1602液晶屏了。

时钟功能介绍:时钟能够通过独立按键实现调时分秒,年月日的功能,,并且在调年月日的时候后面的星期会自动变化。按键用的是矩阵键盘,功能键是矩阵键盘中的s13,增大键是s17,减小键是s21,按键分为功能键,增大建和减小键,功能键用来把光标定位到要调的部分,利用增大键或减小键可以调节时间了,而且当按键按下的时候,蜂鸣器会发出哔~的响声。

话不多说,我直接上代码了,就不一一分部分介绍了,代码大部分都有注释,如果有错的话也希望你们能够指出来。

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;    //段选
sbit wela=P2^7;     //位选
sbit rs=P3^5;  //定义液晶RS端
sbit lcden=P3^4;   //定义液晶LCDEN端
sbit s1=P3^0; //定义功能键
sbit s2=P3^1;   //定义增大建
sbit s3=P3^2;  //定义减小键
sbit rd=P3^7;
sbit beep=P2^3;  //定义蜂鸣器端
uchar count,s1num;  //count用来计时,达到一秒时秒数加一,s1num用来记录按键次数
uchar code table[]=" 20";
int code month[12]={31,28,31,30,31,30,31,31,30,31,30,31};//每个月的月份,闰年2月有29天,后面用comparemonth来修改
char miao,shi,fen,nian,yue,ri,zhou,comparemonth,m,n;
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)    //液晶写命令函数
{rs=0;   //选择写命令模式,表示输入命令lcden=0;    //使使能端置0P0=com;      //将要写的命令字送到数据总线中delay(5);   //稍作延时以待数据稳定lcden=1;    //使能端给一高脉冲delay(5);lcden=0;    //将使能端置0以完成高脉冲
}
void write_date(uchar date)   //液晶写数据函数
{rs=1;   //送显示数据lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;
}
void write_nyr(uchar add,uchar date)    //写年月日函数,由于我设置的年月日都是两位数,后面如果用到具体年份的话就用nian+2000
{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);
}
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_week(char we)      //写星期函数
{write_com(0x80+12);          //后面用到了一个超级厉害的公式求星期几,叫基姆拉尔森公式,可以自行百度一下switch(we){case 0:   write_date('S');delay(5);write_date('U');delay(5);write_date('N');break;case 1:   write_date('M');delay(5);write_date('O');delay(5);write_date('N');break;case 2:    write_date('T');delay(5);write_date('U');delay(5);write_date('E');break;case 3:   write_date('W');delay(5);write_date('E');delay(5);write_date('D');break;case 4:    write_date('T');delay(5);write_date('H');delay(5);write_date('U');break;case 5:   write_date('F');delay(5);write_date('R');delay(5);write_date('I');break;case 6:   write_date('S');delay(5);write_date('T');delay(5);write_date('A');break;}
}
void settime_add()       //设置时间增加函数,用来处理时间和日期溢出的情况
{if(miao==60) miao=0;if(fen==60)  fen=0;if(shi==24)  shi=0;comparemonth=month[yue-1];if(yue==2){if((nian+2000)%4==0){comparemonth=29;}}if(ri>comparemonth) ri=1;if(yue>12) yue=1;if(nian>99) nian=0;write_nyr(3,nian);write_nyr(6,yue);write_nyr(9,ri);write_sfm(4,shi);write_sfm(7,fen);write_sfm(10,miao);if((yue==1)||(yue==2))      //公式要求如果月份为1月或者2月时,将1月或2月当做上一年的13月和14月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算{m=yue+12;n=nian-1;}else{m=yue;n=nian;}zhou=(ri+2*m+3*(m+1)/5+(n+2000)+(n+2000)/4-(n+2000)/100+(n+2000)/400+1)%7;   //这就是基姆拉尔森公式啦write_week(zhou);}
void settime_minus()       //时间设置减少函数,用来处理时间和日期减少是溢出的情况
{if(miao<0) miao=59;if(fen<0)  fen=59;if(shi<0)  shi=23;comparemonth=month[yue-1];if(yue==2){if((nian+2000)%4==0){comparemonth=29;}}if(ri==0) ri=comparemonth;if(yue==0) yue=12;if(nian<0) nian=99;write_nyr(3,nian);write_nyr(6,yue);write_nyr(9,ri);write_sfm(4,shi);write_sfm(7,fen);write_sfm(10,miao);if((yue==1)||(yue==2)){m=yue+12;n=nian-1;}else{m=yue;n=nian;}zhou=(ri+2*m+3*(m+1)/5+(n+2000)+(n+2000)/4-(n+2000)/100+(n+2000)/400+1)%7;write_week(zhou);}
void init()   //初始化函数
{uchar num;rd=0;dula=0;wela=0;lcden=0;nian=22;yue=3;ri=2;fen=0;miao=0;zhou=(ri+2*yue+3*(yue+1)/5+(nian+2000)+(nian+2000)/4-(nian+2000)/100+(nian+2000)/400+1)%7;shi=0;count=0;s1num=0;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<3;num++){write_date(table[num]);    //固定部分为20~~年delay(5);}write_com(0x80+5);write_date('-');delay(5);write_com(0x80+8);write_date('-');delay(5);write_com(0x80+0x40+6);write_date(':');delay(5);write_com(0x80+0x40+9);write_date(':');delay(5);write_sfm(10,miao);write_sfm(7,fen);write_sfm(4,shi);write_nyr(3,nian);write_nyr(6,yue);write_nyr(9,ri);write_week(zhou);TMOD=0x01;TH0=(65536-50000)/256;       //定时器确定初值TL0=(65536-50000)%256;EA=1;          //开总中断ET0=1;TR0=1;
}
void keyscan()
{zhou=(ri+2*yue+3*(yue+1)/5+(nian+2000)+(nian+2000)/4-(nian+2000)/100+(nian+2000)/400+1)%7;if(s1==0)    //s1是功能键{delay(5);     //延时5毫秒if(s1==0)  //确认功能键被按下{s1num++;  //功能键按下次数记录while(!s1);    //释放确认di();if(s1num==1)   //功能键第一次被按下时{TR0=0;     //当按下功能键时关闭定时器write_com(0x80+0x40+10);   //光标移到秒位置write_com(0x0f);   //在指定位置光标闪烁}if(s1num==2)    //功能键第二次被按下时{write_com(0x80+0x40+7);  //光标移到分位置}if(s1num==3)     //功能键第三次被按下{write_com(0x80+0x40+4);   //光标移到时位置}if(s1num==4)    //当功能键第四次被按下时{write_com(0x80+9);  }if(s1num==5)  //当功能键第五次被按下时{write_com(0x80+6);}if(s1num==6)     //当功能键第六次被按下时{write_com(0x80+3);}if(s1num==7)  //当功能键被第七次按下时{s1num=0;  //记录按键数清0write_com(0x0c);  //取消光标闪烁TR0=1;         //启动定时器让时钟继续走}}}if(s1num!=0)    //只有功能键被按下后,增大键和减小键才有效{if(s2==0)    //s2是增大键{delay(5);if(s2==0)   //确认增大建被按下{while(!s2);       //按键释放di();if(s1num==1)  //秒{miao++;write_com(0x80+0x40+10); settime_add();}if(s1num==2) //分{fen++;write_com(0x80+0x40+7);settime_add();}if(s1num==3)        //时{shi++;write_com(0x80+0x40+4); settime_add();}if(s1num==4)     //日{ri++;write_com(0x80+9); settime_add();   }if(s1num==5)   //月{yue++;write_com(0x80+6);settime_add();}if(s1num==6)    //年{nian++;write_com(0x80+3); settime_add();    }}}if(s3==0)      //s3是减小键{delay(5);if(s3==0)       //当减小键被按下{while(!s3);di();if(s1num==1){miao--;write_com(0x80+0x40+10); settime_minus();}if(s1num==2){fen--;write_com(0x80+0x40+7); settime_minus();}if(s1num==3){shi--;write_com(0x80+0x40+4); settime_minus();}if(s1num==4){ri--;write_com(0x80+9); settime_minus(); }if(s1num==5){yue--;write_com(0x80+6); settime_minus();}if(s1num==6)   //当减小键第一次被按下时{nian--;write_com(0x80+9);settime_minus();    }}}}
}
void main()
{init();while(1){keyscan();}
}
void timer0() interrupt 1    //中断程序
{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;if(count==20){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;ri++;settime_add();}write_sfm(4,shi);}write_sfm(7,fen);}write_sfm(10,miao);}
}

51单片机用1602液晶屏实现可调时钟相关推荐

  1. 51单片机12864大液晶屏proteus仿真

    51单片机竞赛设计实例程序44例(Proteus仿真资料),可以做参赛设计的参考,可以用来做毕业设计,也可以做项目参考,平时的练习项目,带源码,可以说费了很多时间才集齐的,希望对你们有帮助,闯客网技术 ...

  2. 单片机控制lcd序c语言,51单片机驱动1602液晶的C程序

    # include /***************************************** 电路连接 P1------DB0-DB7 P2.0------RS P2.1------RW ...

  3. 电子时钟万年历+51单片机+1602液晶屏+DS1302+DS18B20+按键

    电子时钟万年历+51单片机+1602液晶屏+DS1302+DS18B20+按键 这次课程设计要完成的是制作一个基于51单片机的电子时钟的万年历(protues仿真),需要用到1602液晶屏+DS130 ...

  4. 单片机显示屏c语言程序,51单片机驱动1602液晶显示器c程序

    51单片机驱动1602液晶显示器c程序 /* 程序效果:单片机控制液晶显示器1602显示字母数字,用户自行更改io 程序版权:http://www.51hei.com */ #include //头文 ...

  5. arduino下载库出错_arduino的I2C通讯 3:驱动1602液晶屏

    上个推送,我们学习了I2C功能的基础知识.而且知道了使用很多器件都需要安装库.本次,我们一起来做一个实例,用arduino驱动1602液晶屏 1602代表屏幕有16列,2行.传统的驱动方式占用了大量的 ...

  6. 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...

  7. 台达触摸屏modbusRTU与51单片机通讯台达屏与郭天祥51单片机通讯程序

    台达触摸屏modbusRTU与51单片机通讯台达屏与郭天祥51单片机通讯程序亲测过好用,P1口led显示8个位的状态上传给触摸屏,d2至d7为16数据寄存器能写能读,数码管显示当前写入的数码id=60 ...

  8. 51单片机驱动HMI串口屏,串口屏的下载方式

    51单片机驱动HMI串口屏,串口屏的下载方式 串口屏 串口屏的程序下载 51程序 总结 串口屏 串口屏是一个集成了单片机的屏幕模块,采用的是TTL串口协议,可以直接通过对应指令控制屏幕, 本文采用的串 ...

  9. 基于51单片机PWM(即脉冲宽度调制)调速数码管显示测速L298M芯片控制直流电机正反运转的项目

    基于51单片机PWM(即脉冲宽度调制)调速数码管显示测速L298芯片控制直流电机正反运转的项目 一.前言 1.基于51单片机PWM(即脉冲宽度调制)调速数码管显示测速L298芯片控制直流电机正反运转的 ...

  10. 51单片机定时器及其应用(1)(时钟功能)

    51单片机定时器及其应用(1)(时钟功能)   STC89C51单片机有2个定时器,叫做定时器0和定时器1,可以用作普通定时器,计数器.普通定时器可以用来进行中断定时,波特率发生等,计数器可以用来对脉 ...

最新文章

  1. 可能是东半球最好的 Curl 学习指南,强烈建议收藏!
  2. poi获取段落位置_Apache POI:从java中的word文档(docx)中提取段落和后续表格
  3. 日周月筛选器_举个栗子!Tableau 技巧(147):使用 动态参数 筛选到最新日期值...
  4. 商丘高中计算机考试成绩查询系统,河南省中招考生服务平台2019商丘中考成绩查询系统入口...
  5. 解决tshark报错:tshark: Some fields aren‘t valid
  6. PostgreSQL一些简单问题以及解决办法
  7. 发票专用驱动sjz_增值税发票选择确认平台使用手册
  8. excel linux时间戳转换成日期,Excel将Unix时间戳转换为日期
  9. ICMP协议(网际报文控制协议)详解
  10. 服务器显示共享文件夹的图标,Win7共享文件夹上的小锁图标怎么关闭?
  11. 2021年笔迹鉴定收费?江西南昌收费标准是什么?
  12. 被打脸!谁说区块链无落地?这50大落地场景拿走不谢
  13. UICollectionView 右对齐的解决方案
  14. 记录下Makefile
  15. java实现回文数算法
  16. 非线性方程线性化求参数的简单例子
  17. AWS 再次发生宕机事件,云时代下的我们该如何补救?
  18. [Java] Java基础
  19. (c语言)兔子繁衍问题
  20. 无人驾驶-从零入门(一)

热门文章

  1. GSAP教程之Tween详解
  2. java win7 管理员权限_获得WIN7管理员权限(可通过修改注册表,或者组策略改变)...
  3. Python全栈开发实战学习14
  4. python发微信图片加文字_python向企业微信发送文字和图片消息的示例
  5. 网易云音乐评论 破解JS加密参数
  6. c语言买100只鸡,C语言经典问题--百钱买百鸡问题
  7. 伪标签Pseudo Label
  8. unlink php 实例,PHP unlink()用法及代碼示例
  9. Django 千锋培训读书笔记
  10. js-beautify-html配置,HTML-Beautify.js学习