日志提醒录.docx
- 文档编号:30088845
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:23
- 大小:261.36KB
日志提醒录.docx
《日志提醒录.docx》由会员分享,可在线阅读,更多相关《日志提醒录.docx(23页珍藏版)》请在冰豆网上搜索。
日志提醒录
课程设计报告
(2012--2013年度第一学期)
名称:
仪器仪表实训
题目:
电子时钟设计
院系:
自动化系
班级:
测控
学号:
2009学生姓名:
指导教师:
设计周数:
一周
日期:
2013.01.16
成绩:
摘要
本论文主要讲述了日志提醒录的设计过程,主要包括硬件设计和程序设计。
硬件主要包括以AT89C52单片机为主要控制电路、键盘输入电路、显示电路等。
控制电路的核心器件就是AT89C52单片机,显示电路采用LCD1602显示芯片,键盘为矩阵键盘,逐行逐列扫描后判断按键按下。
由单片机控制矩阵键盘的扫描,确认按键按下后,再通过与单片机连接的LCD1602将内容显示输出。
功能说明:
时间显示,时间调试,时间设定
关键词:
单片机、矩阵键盘、LCD1602
1.设计任务及方案分析
一、任务要求
设计内容:
用单片机设计电子时钟
设计要求:
1.硬件设计。
掌握单片机、矩阵键盘、
显示电路等相关原理与知识;画出原理图
2、软件设计
3、用keil软件对硬件系统进行仿真
4、五人一组做实物
5、交一份设计报告
二、设计总体方案及方案论证
按照系统的设计要求,本系统主要分为三个部分:
主控制器AT89C52,矩阵键盘及LCD1602驱动显示电路。
主控制器:
矩阵键盘:
LCD1602显示电路:
2.芯片功能简介
一AT89C52的功能简介
AT89C52是美国ATMEL公司生产的低电平,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的只读程序存储器(PEROM)和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和Flash存储单元,32个可编程I/O口线,3个16位定时/计数器,低功耗空闲和掉电模式。
功能强大的AT89C52单片机适合于许多较为复杂控制应用场合。
二、矩阵键盘
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。
由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
确定矩阵式键盘上何键被按下介绍一种“行扫描法”。
行扫描法行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。
1、判断键盘中有无键按下将全部行线Y0-Y3置低电平,然后检测列线的状态。
只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。
若所有列线均为高电平,则键盘中无键按下。
2、判断闭合键所在的位置在确认有键按下后,即可进入确定具体闭合键的过程。
其方法是:
依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。
若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
下面给出一个具体的例子:
8051单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。
列线P1.0-P1.3分别接有4个上拉电阻到正电源+5V,并把列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。
4根行线和4根列线形成16个相交点。
1、检测当前是否有键被按下。
检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键闭合。
2、去除键抖动。
当检测到有键按下后,延时一段时间再做下一步的检测判断。
3、若有键被按下,应识别出是哪一个键闭合。
方法是对键盘的行线进行扫描。
P1.4-P1.7按下述4种组合依次输出:
P1.71110
P1.61101
P1.51011
P1.40111
在每组行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。
由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值
4、为了保证键每闭合一次CPU仅作一次处理,必须却除键释放时的抖动。
三LCD1602显示部分
所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
引脚定义如下表所示:
基本操作时序:
读状态 输入:
RS=L,RW=H,E=H
输出:
DB0~DB7=状态字
写指令 输入:
RS=L,RW=L,E=下降沿脉冲,DB0~DB7=指令码
输出:
无
读数据 输入:
RS=H,RW=H,E=H
输出:
DB0~DB7=数据
写数据 输入:
RS=H,RW=L,E=下降沿脉冲,DB0~DB7=数据
输出:
无
3.软件编程调试及说明书
一、整个软件的主流程图如下图所示:
五次
两次
四次
三次
二、使用说明
1.键盘说明
调时
增
减
2.调时
(1)按“调时”,进入调秒状态,通过“增”“减”按钮来调节秒。
(2)再按“调时”进入调分状态,通过“增”“减”按钮来调节分。
(3)再按“调时”进入调时状态,通过“增”“减”按钮来调节时。
三、感想
通过课程设计,有很多的心得体会。
此次单片机内部时钟设计,使我更加扎实的掌握了有关单片机方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手操作,使我们掌握的知识不再是纸上谈兵。
结果很欣慰。
能够交出自己满意的作品。
这里面的个中滋味只有真正写一遍才能理会!
四、主程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitrw=P1^1;
sbitrs=P1^0;//数据、指令选择
sbitlcden=P1^2;//使能信号
sbita=P2^0;//扫描行
sbitb=P2^1;
sbitc=P2^2;
sbitd=P2^3;
sbite=P2^4;//扫描列
sbitf=P2^5;
sbitg=P2^6;
sbith=P2^7;
sbitq=P1^6;
intcount,s1num,run;
charmiao,shi,fen,nian,yue,ri;
ucharcodetable[]="2013-01-16";//显示样式
ucharcodetable1[]="00:
00:
00";//显示样式
ucharcodetable6[]={32,29,32,31,32,31,32,32,31,32,31,32};//显示平年月份上限
ucharcodetable7[]={32,30,32,31,32,31,32,32,31,32,31,32};//显示闰年月份上限
voiddelay(uintz)//延时函数
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//写命令函数
{
P0=com;
rs=0;
rw=0;
lcden=0;
delay(5);
lcden=1;
}
voidwrite_date(uchardate)//写数据函数
{
P0=date;
rs=1;
rw=0;
lcden=0;
delay(5);
lcden=1;
}
voidinit()//初始化函数
{
ucharnum;
write_com(0x01);//清屏
write_com(0x38);//8位格式,两行
write_com(0x0c);//整体显示,关光标,不闪烁
write_com(0x06);//输入方式设定:
不增移
write_com(0x01);
write_com(0x80);//输入地址位置
for(num=0;num<16;num++)//显示第一行
{
write_date(table[num]);
delay(5);
}
delay(5);
write_com(0xc0);
for(num=0;num<12;num++)//显示第二行
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;//定时器0开,8位计数器。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
voidwrite_sfm(ucharadd,uchardate)//在特定地址写数据
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
voidwrite_nyr(ucharadd,uchardate)//在特定地址写数据
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
voidkeyscan()//时间设定函数
{inttempnian;
a=1;b=1;c=1;d=0;
if(e==0){delay(10);
if(e==0){//显示光标的位置,便于调节时间
s1num++;while(!
e);//slnum为选中的小时,分钟,秒
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+5);
}
if(s1num==5)
{
write_com(0x80+8);
}if(s1num==6)
{
write_com(0x80+11);
}
if(s1num==7)
{
s1num=0;
write_com(0x0c);
delay(5);
TR0=1;
}
}
}
if(s1num!
=0)
{a=1;b=1;c=0;d=1;//为增一设定
if(e==0){delay(10);
if(e==0){while(!
e);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_com(0x80+0x40+10);
write_sfm(10,miao);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_com(0x80+0x40+7);
write_sfm(7,fen);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_com(0x80+0x40+4);
write_sfm(4,shi);
}
if(s1num==4)
{
nian++;
if(nian==100)
nian=0;
write_com(0x80+5);
write_nyr(5,nian);
}
if(s1num==5)
{
yue++;
if(yue==13)
yue=1;
write_com(0x80+8);
write_nyr(8,yue);
}
if(s1num==6)
{tempnian=nian%4;
if(tempnian==0)
{ri++;if(ri==table7[yue])ri=1;run=1;}
else
{ri++;if(ri==table6[yue])ri=1;run=0;}
write_com(0x80+11);
write_nyr(11,ri);
}
}
}
a=1;b=0;c=1;d=1;//为减一设定
if(e==0){delay(10);
if(e==0){while(!
e);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_com(0x80+0x40+10);
write_sfm(10,miao);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_com(0x80+0x40+7);
write_sfm(7,fen);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_com(0x80+0x40+4);
write_sfm(4,shi);
}
if(s1num==4)
{
nian--;
if(nian==-1)
nian=99;
write_com(0x80+5);
write_nyr(5,nian);
}
if(s1num==5)
{
yue--;
if(yue==0)
yue=12;
write_com(0x80+8);
write_nyr(8,yue);
}
if(s1num==6)
{tempnian=nian%4;
if(tempnian==0)
{ri++;if(ri==0)ri=table7[yue]-1;}
else
{ri++;if(ri==0)ri=table6[yue]-1;}
write_com(0x80+11);
write_nyr(11,ri);
}
}}
}
}
//===================================================================================================
//===================================================================================================
voidtimepro(void)//时间进程函数
{if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
ri++;
if(run==0)
if(ri==table6[yue]){ri=1;
yue++;
if(yue==13)
{yue=1;
nian++;
if(nian==100)
nian=0;
write_nyr(5,nian);
}write_nyr(8,yue);}
else
if(ri==table7[yue]){ri=1;
yue++;
if(yue==13)
{yue=1;
nian++;
if(nian==100)
nian=0;write_nyr(5,nian);
}write_nyr(8,yue);}
write_nyr(11,ri);
}write_sfm(4,shi);
}write_sfm(7,fen);
}write_sfm(10,miao);
}
//===================================================================================================
voidmain()//主函数
{s1num=0;shi=0;fen=0;miao=0;nian=13;yue=1;ri=16;
init();
while
(1)
{
keyscan();
}
}
voidtimer0()interrupt1//中断函数,调整时、分、秒。
到提醒时间提示。
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
{
count=0;
miao++;
}
timepro();//时间进程函数必须在终端中写,因为如果不是这样就会有如下的毛病:
当我们想设定时间的时候光标不会跟随更改的位置发生变化。
设定时间的时候我们也应该把中断关闭。
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 日志 提醒