基于51的1602时钟显示
来源:互联网 发布:匕首cad图纸数据 编辑:程序博客网 时间:2024/06/06 02:35
#include<reg52.h>
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义
sbit dula=P2^6;//控制数码管
sbit wela=P2^7;
sbit rs=P3^5;//控制液晶数据名命令选择
sbit lcden=P3^4;//液晶写数据控制
sbit s1=P3^0;//控制矩阵键盘的S9
sbit s2=P3^1;//控制矩阵键盘的S13
sbit s3=P3^2;//控制矩阵键盘的S17
sbit rd=P3^7;//申明RD的位
uchar count,date,shi,fen,miao,s1num;
uchar code table[]=" 2017-10-17 MON";//初始化显示日期
uchar code table1[]=" 19:28:20";//初始化显示时间
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;//lcden拉低
P0=com;
delay(5);
lcden=1;//拉高
delay(5);//稳定五毫秒
lcden=0;//拉低
}
void write_date(uchar date)//写指数据函数
{
rs=1;//数据置高
lcden=0;//lcden拉低
P0=date;
delay(5);
lcden=1;//拉高
delay(5);//稳定五毫秒
lcden=0;//拉低
}
void init()
{
uchar num;
dula=0;//关闭数码管
wela=0;
lcden=0;//通过1602的资料显示lcden初始为低
/* 一定注意这里的赋值与程序开头的自定义赋值,当二者赋值一致的时候才会正常走动,不也一样时就会出现错误,原因未知*/
fen=28;
miao=20;
shi=19;
/***************************************************/
write_com(0x38);//设置16X2显示,5X7点阵,8位数据接口
delay(5);
write_com(0x0c);//00001100开显示,不显示光标
write_com(0x06);//00000110,读入一个字符后指针和光标都加一,整屏不移动
write_com(0x01);//清零,不清零会显示出错
write_com(0x80);//指针赋值,写入地址,表示从第一行开始写
for(num=0;num<15;num++)//第一行共需要15个显示位,显示位数一定要一一对应
{
write_date(table[num]);//写数据进去
delay(5);
}
write_com(0x80+0x40);//写入第二行的地址
for(num=0;num<12;num++)//第二行共需要11个显示位,显示位数一定要一一对应,
{
write_date(table1[num]);//写数据进去
delay(5);
}
TMOD=0x01;//采用定时器0的方式1
TH0=(65536-50000)/256;//装初值
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//打开T0中断
TR0=1;//启动定时器0
}
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);//通过1602的字符手册,让十位显示0(0x30),送数据到第二行
write_date(0x30+ge);//通过1602的字符手册,让个位显示0(0x30),送数据到第二行
}
void keyscan()//编写按键控制时钟函数
{//5
rd=0;//让RD接地,要控制那一列就让那一列接地,通过矩阵键盘原理图判断
if(s1==0)//检测s1是否按下
{//4
s1num++;//每按下一次s1就加一
delay(5);//延时消抖
if(s1==0)//判断s1确实被按下
{
while(!s1);//检测是否松手
if(s1num==1)//按下第一次让秒闪烁
{
TR0=0;//关闭定时器,禁止时钟继续走动
write_com(0x80+0x40+11);//控制第二行的第几位
write_com(0x0f);//显示光标,并让光标闪烁,0x0f来源于1602的原理图
}
if(s1num==2)//按下第二次让分闪烁
{
TR0=0;//关闭定时器,禁止时钟继续走动
write_com(0x80+0x40+8);//控制第二行的第几位
write_com(0x0f);//显示光标,并让光标闪烁,0x0f来源于1602的原理图
}
if(s1num==3)//按下第三次让时闪烁
{
TR0=0;//关闭定时器,禁止时钟继续走动
write_com(0x80+0x40+5);//控制第二行的第几位
write_com(0x0f);//显示光标,并让光标闪烁,0x0f来源于1602的原理图
}
if(s1num==4)//第四次按下,清零,让光标不闪烁
{
s1num=0;//清零
write_com(0x0c);//光标停止闪烁
TR0=1;//开启定时器,时钟重新开始走动
}
}
}//4
if(s1num!=0)//确认s1键被按下
{//3
if(s2==0)//检测s2被按下
{//2
delay(5);
if(s2==0)//确定s2被按下
{//1
while(!s2);
if(s1num==1)//确定让秒加一
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)//确定让分加一
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//确定让时加一
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}//1
}//2
if(s3==0)//检测s3被按下
{//2
delay(5);
if(s3==0)//确定s2被按下
{//1
while(!s3);
if(s1num==1)//确定让秒加一
{
miao--;
if(miao==0)
miao=60;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)//确定让分加一
{
fen++;
if(fen==0)
fen=60;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//确定让时加一
{
shi++;
if(shi==0)
shi=24;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}//1
}//2
} //3
}//5
void main()
{
init();
while(1)
{
keyscan();
if(count==20)//判断是否到了1秒
{
count=0;
miao++;
if(miao==60)//判断是否到了一分钟
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);//10表示table1[]中的秒位正好在第十个字符位后面
}
}
}
void timer0() interrupt 1//选择中断源
{
TH0=(65536-50000)/256;//装初值
TL0=(65536-50000)%256;
count++;
}
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义
sbit dula=P2^6;//控制数码管
sbit wela=P2^7;
sbit rs=P3^5;//控制液晶数据名命令选择
sbit lcden=P3^4;//液晶写数据控制
sbit s1=P3^0;//控制矩阵键盘的S9
sbit s2=P3^1;//控制矩阵键盘的S13
sbit s3=P3^2;//控制矩阵键盘的S17
sbit rd=P3^7;//申明RD的位
uchar count,date,shi,fen,miao,s1num;
uchar code table[]=" 2017-10-17 MON";//初始化显示日期
uchar code table1[]=" 19:28:20";//初始化显示时间
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;//lcden拉低
P0=com;
delay(5);
lcden=1;//拉高
delay(5);//稳定五毫秒
lcden=0;//拉低
}
void write_date(uchar date)//写指数据函数
{
rs=1;//数据置高
lcden=0;//lcden拉低
P0=date;
delay(5);
lcden=1;//拉高
delay(5);//稳定五毫秒
lcden=0;//拉低
}
void init()
{
uchar num;
dula=0;//关闭数码管
wela=0;
lcden=0;//通过1602的资料显示lcden初始为低
/* 一定注意这里的赋值与程序开头的自定义赋值,当二者赋值一致的时候才会正常走动,不也一样时就会出现错误,原因未知*/
fen=28;
miao=20;
shi=19;
/***************************************************/
write_com(0x38);//设置16X2显示,5X7点阵,8位数据接口
delay(5);
write_com(0x0c);//00001100开显示,不显示光标
write_com(0x06);//00000110,读入一个字符后指针和光标都加一,整屏不移动
write_com(0x01);//清零,不清零会显示出错
write_com(0x80);//指针赋值,写入地址,表示从第一行开始写
for(num=0;num<15;num++)//第一行共需要15个显示位,显示位数一定要一一对应
{
write_date(table[num]);//写数据进去
delay(5);
}
write_com(0x80+0x40);//写入第二行的地址
for(num=0;num<12;num++)//第二行共需要11个显示位,显示位数一定要一一对应,
{
write_date(table1[num]);//写数据进去
delay(5);
}
TMOD=0x01;//采用定时器0的方式1
TH0=(65536-50000)/256;//装初值
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//打开T0中断
TR0=1;//启动定时器0
}
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);//通过1602的字符手册,让十位显示0(0x30),送数据到第二行
write_date(0x30+ge);//通过1602的字符手册,让个位显示0(0x30),送数据到第二行
}
void keyscan()//编写按键控制时钟函数
{//5
rd=0;//让RD接地,要控制那一列就让那一列接地,通过矩阵键盘原理图判断
if(s1==0)//检测s1是否按下
{//4
s1num++;//每按下一次s1就加一
delay(5);//延时消抖
if(s1==0)//判断s1确实被按下
{
while(!s1);//检测是否松手
if(s1num==1)//按下第一次让秒闪烁
{
TR0=0;//关闭定时器,禁止时钟继续走动
write_com(0x80+0x40+11);//控制第二行的第几位
write_com(0x0f);//显示光标,并让光标闪烁,0x0f来源于1602的原理图
}
if(s1num==2)//按下第二次让分闪烁
{
TR0=0;//关闭定时器,禁止时钟继续走动
write_com(0x80+0x40+8);//控制第二行的第几位
write_com(0x0f);//显示光标,并让光标闪烁,0x0f来源于1602的原理图
}
if(s1num==3)//按下第三次让时闪烁
{
TR0=0;//关闭定时器,禁止时钟继续走动
write_com(0x80+0x40+5);//控制第二行的第几位
write_com(0x0f);//显示光标,并让光标闪烁,0x0f来源于1602的原理图
}
if(s1num==4)//第四次按下,清零,让光标不闪烁
{
s1num=0;//清零
write_com(0x0c);//光标停止闪烁
TR0=1;//开启定时器,时钟重新开始走动
}
}
}//4
if(s1num!=0)//确认s1键被按下
{//3
if(s2==0)//检测s2被按下
{//2
delay(5);
if(s2==0)//确定s2被按下
{//1
while(!s2);
if(s1num==1)//确定让秒加一
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)//确定让分加一
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//确定让时加一
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}//1
}//2
if(s3==0)//检测s3被按下
{//2
delay(5);
if(s3==0)//确定s2被按下
{//1
while(!s3);
if(s1num==1)//确定让秒加一
{
miao--;
if(miao==0)
miao=60;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)//确定让分加一
{
fen++;
if(fen==0)
fen=60;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)//确定让时加一
{
shi++;
if(shi==0)
shi=24;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}//1
}//2
} //3
}//5
void main()
{
init();
while(1)
{
keyscan();
if(count==20)//判断是否到了1秒
{
count=0;
miao++;
if(miao==60)//判断是否到了一分钟
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);//10表示table1[]中的秒位正好在第十个字符位后面
}
}
}
void timer0() interrupt 1//选择中断源
{
TH0=(65536-50000)/256;//装初值
TL0=(65536-50000)%256;
count++;
}
阅读全文
0 0
- 基于51的1602时钟显示
- 基于DS1302芯片---使用51单片机C语言编制的电子时钟(液晶1602显示)
- 基于51单片机的电子时钟
- 时钟的显示
- 显示毫秒的时钟
- 有意思的时钟显示
- LCD的时钟显示
- 时钟的实时显示
- STC89C51时钟 1602显示
- 基于MFC的时钟绘制
- 基于FPGA的数字时钟
- 基于JavaScript的数码时钟
- 速求一基于51单片机的时钟倒计时计时器的设计方案
- 一个显示时钟的脚本
- 简单的页面时钟显示
- 简单的页面显示时钟
- 显示时钟的JavaScript源码
- 用 LCD1602 显示的时钟
- Unity3D面试题整合——第四部分及答案
- Linux操作系统命令学习第八天
- Java多线程系列(六)—AQS源码分析
- 复数实现
- 1035. Password (20)
- 基于51的1602时钟显示
- Spring boot打包部署
- effective java(13) 之使类和成员的可访问性最小化
- $.ajax()方法详解
- 实验楼之一个简单的课程数据库
- Oracle中before触发器中伪列的使用
- 数据类型
- Windows编程基础--第2节 win32程序资源管理
- shell编程学习(一)