LCD单片机原理及接口技术 课程设计.docx
《LCD单片机原理及接口技术 课程设计.docx》由会员分享,可在线阅读,更多相关《LCD单片机原理及接口技术 课程设计.docx(26页珍藏版)》请在冰豆网上搜索。
![LCD单片机原理及接口技术 课程设计.docx](https://file1.bdocx.com/fileroot1/2023-1/28/0e5ce8d2-2fc0-4025-bc8d-13e04354afd4/0e5ce8d2-2fc0-4025-bc8d-13e04354afd41.gif)
LCD单片机原理及接口技术课程设计
一、前言…………………………………………………………………………………1
一、设计要求及任务…………………………………………………………3
二、设计的基本步骤及方案………………………………………………………3
三、硬件电路设计及描述……………………………………………………3
<1>开关控制部分…………………………………………………………………3
<2>LCD液晶显示部分……………………………………………………………4
<3>温度测量部分…………………………………………………………………4
四、程序框图…………………………………………………………………5
<1>Lcd1602…………………………………………………………………………5
<2>时间,闹铃设置………………………………………………………………5
<3>温度显示…………………………………………………………………………5
<4>总流程图…………………………………………………………………………6
<5>部分程序说明……………………………………………………………………7
五、硬件的调试过程及调试方法……………………………………………10
六、课程设计体会………………………………………………………………11
七、参考资料……………………………………………………………………11
附录………………………………………………………………………………11
前言
本学期期末,我们进行了单片机实训,对于我们机械设计制造及其自动化专业的学生来说,单片机是自动控制装置中不可缺少的一部分,在当今制造业中有着不可替代的作用。
所谓单片机,就是把CPU、存储器、输入设备、输出设备、定时,计数器、等计算机的主要部件集成在一小块硅片上的单片微型计算机。
因为它体积小可靠性高性价比高等诸多有点,在机电一体化产品领域有着广泛地应用。
本次单片课程实训我们选择的题目是设计一个LCD智能电子时钟,也就是在生活中有着广泛应用的电子表的部分功能电路,虽然在单片机的电路中,此电路属于相对简单的一个,但是在我们制作电路过程中,对我们的启发是很大的。
首先这是我们把理论适用于实践的一次尝试,我们学习的目的是为了实用,也就是通常说的学以致用。
本次实训,我们选择了生活中应用广泛的电子时钟电路的原因也就在于此!
通过LCD电子时钟的设计,我们相信,可以积累更多的实际运用单片机的经验!
便于我们在以后的工作中更好的适应工作环境,更加顺利的进行工作过程,更加熟练的掌握进单片机的应用技术。
其次实训过程也是我们巩固所学知识的过程。
在我们实训过程中,会遇到这样或那样意想不到的问题,需要对设计进行一遍又一遍的改动,在改动和检错的过程中,我们需要向其他通许或老师请教许多关于已知错误的知识,而这些知识大部分是我们平时学习所不掌握或掌握不熟练指之处,因此通过查阅资料和请教他人,我们不仅温习了已学的部分知识,更重要的是接触到了大量的课外知识。
孔子有句话:
“温故而知新,可以为师矣”。
说的就是这个道理!
再次单片机的实训中,培养了我们吃苦耐劳的精神和一丝不苟的学习工作态度。
单片机的实训过程是很辛苦的,要想做好必须要付出极大的努力。
在机的开放期间,几乎在整个实践段都有许多同学在刻苦学习,用心设计。
为了更好更快的完成任务,大家废寝忘食的查找设计过程中的错误和不足,虽然同学们的水平有限,但是大家都尽了自己最大的努力。
单片机的电路设计复杂而繁琐,每一根线都要细心考虑,精心检查,以保证设计电路尽可能的减少错误,因此没有认真严谨的学习态度是很难完成的!
虽然实训的过程很辛苦,但是我们的指导老师更加辛苦,他们在实训的每天都按时到达机房,时刻为我们解答疑难问题!
是我们能够完成任务的保证!
因此要感谢老师的精心指导和无私帮助!
一、设计任务及要求
1.设计任务:
制作一个的智能电子钟。
2.设计要求:
1.使用文字型LCD显示当前时间;
2.显示格式为“时时:
分分:
秒秒;
3.用4个功能键操作来设置当前时间,功能键K1~K4功能如下;
K1———选择设置时/分/秒;
K2———加一;
K3———减一;
K4———确认完成设置。
4.程序执行后工作指示灯LED闪动,LCD显示“00:
00:
00“;
5.@增加万年历显示“年月日”;
6.☆增加温度传感器显示当前的温度;
3.设计原件
AT89C51单片机
LCD采用LM16L16*2字符型LCD液晶显示器;
采用定时器;
温度传感器18b20;
五个开关;
一个LED指示灯;
一个10k排阻;
二、设计的基本步骤及方案
1方案:
本课题采用单元电路设计硬件电路分为4个部分。
1)4个开关控制进行时间设置;
2)LCD采用LM16L16*2字符型LCD液晶显示器显示时间,温度,日历;
3)用18b20进行测温;
4)工作指示灯;
总体设计框图:
2.步骤:
A.首先根据设计要求,分析闹钟工作原理,然后查阅相关元件资料及文献。
如lcd液晶显示器,温度传感器18b20;
B.针对实现的功能,利用protues软件来画硬件图。
C.结合硬件图,写出相关硬件的的程序框图,然后进行编写程序。
D.用keil软件进行程序编译,调试,然后再送给protues仿真。
实现各部分硬件的仿真运行。
E.最后将各个部分程序组合,调试,编译,实现整体仿真。
三、硬件电路设计及描述
<1>开关控制部分:
K1,K2,K3,K4分别闭合时分别给P1.0,P1.1,P1.2,P1.3一个低电平信号。
K1-----控制时间时分秒设置;
K2-----加一;
K3-----减一;
K4-----完成设置;
<2>lcd液晶显示部分:
由于P0口为漏极,所以加个排阻;D0~D7连接P0口;lcd的使能信号端接P2.2,数据/命令端(H/L)接P2.1,读/写选择端(H/L)接P2.0;
<3>温度测量部分:
DS1820数字温度计以9位数字量的形式反映器件的温度值。
DS1820通过一个单线接口发送或接收信息,因此在中央微处理器和DS1820之间仅需一条连接线(加上地线)。
用于读写和温度转换的电源可以从数据线本身获得,无需外部电源。
因为每个DS1820都有一个独特的片序列号,所以多只DS1820可以同时连在一根单线总线上,这样就可以把温度传感器放在许多不同的地方。
这一特性在HVAC环境控制、探测建筑物、仪器或机器的温度以及过程监测和控制等方面非常有用。
数据DQ端接在P2.3口
四、程序框图:
<1>Lcd1602:
<2>时间,闹铃设置:
<3>温度显示:
<4>总流程图:
<5>部分程序说明:
Lcd相关资料:
voidinit()//lcd初始化
{
ucharnum;
rw=0;//写功能;
lcden=0;
write_com(0x38);//显示模式设置
write_com(0x0c);//显示开
write_com(0x06);//关标设置
write_com(0x01);//清除原数据;
write_com(0x80);}//首地址指针
写操作时序图:
voidwrite_com(ucharcom)//写命令
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)//写数据
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
关于18b20资料介绍:
初始化时序图
1.先将数据线置高电平1;
2.延时(该时间要求尽可能小一点);
3.数据线拉到低电平0;
4.延时750us(该时间范围480~960us);
5.数据线拉到高电平1;
6.延时等待,如果初始化成功则在15~60us内产生一个由ds18b20返回的低电平0,据该状态可以确定它的存在.但是应注意,不能无限的等待,不然会使程序进入死循环,所以要进行超时判断;
7.若cpu读到数据线上的低电平0后;还要进行延时,其延时的时间从发出高电平算起(第5步的时间算起)最少要480us
8.将数据线再次拉到高电平1后结束.
voiddelay_18B20(unsignedinti)//延时1微秒
{
while(i--);
}
voidds1820rst()//ds1820复位
{
unsignedcharx=0;
DQ=1;//DQ复位
delay_18B20(4);//延时
DQ=0;//DQ拉低
delay_18B20(100);//精确延时大于480us
DQ=1;//拉高
delay_18B20(40);
}
DS18B20写数据时序图
1.数据线先置低电平0;
2.延时确定的时间为15us;
3.按从低位到高位的顺序发送数据(一次只发送一位);
4.延时时间为45us;
5.将数据线拉到高电平1;
6.重复1~5步骤,直到发送完整个字节;
7.最后将数据线拉高到1;
voidds1820wr(ucharwdata)//写数据
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=wdata&0x01;
delay_18B20(10);
DQ=1;
wdata>>=1;
}
}
DS18B20读数据时序图
1.将数据线拉高到1;
2.延时2us;
3.将数据线拉低到0;
4.延时6us;
5.将数据线拉高到1;
6.延时4us
7.读数据的状态得到一个状态位,并进行数据处理;
8.延时30us.
9.重复1~7步骤,直到读完一个字节;
uchards1820rd()//读数据
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
五、硬件的调试过程及调试方法
硬件用protues仿真实现功能运行。
每用keil编译一次生成hex文件,然后添加到51单片机中,之后运行protues。
看是否实现所要的功能。
调试中也遇到很多问题;
1.在进行lcd显示时,编程端口定义错啦;
2.进行模块组合时,出现显示冲突,各模块的显示控制混乱。
3.用定时器0与18b20送数据到lcd是产生冲突。
T为当前显示温度;11-12-25为年月日;第二排为时间时分秒;
温度传感器检测的当前温度;
LED工作指示灯闪烁表明工作正常;
六、课程设计体会
虽然只有短短两个周的实训时间,但是通过这次的课程设计,在很大程度上提高了我们自主学习和思考的能力,使我们获益良多,不能用文字来表达其中的快乐。
巩固了我门这学期以来所学习的单片机及其原理这门课程,让我们找到了学习的乐趣,明白了带我们的的老师们的良苦用心和殷切希望。
论文中所涉及的很大部分的知识并不是从书本上,而是在已有的知识基础上,借助书籍和网上资源,经过反复思考而得出的,将书本知识运用到实际生活中体现了其价值所在。
七、参考资料
1单片机原理与应用技术。
北京:
清华大学出版社,2009
2吴亦锋.单片机原理与接口技术。
北京:
电子工业出版社,2010
3DS1820单线数字温度计说明书。
4smc1602ALOM使用说明书。
附录:
#include
#defineucharunsignedchar
#defineuintunsignedint
//sbitBLK=P1^0;
sbitDQ=P2^3;
sbitrs=P2^0;
sbitrw=P2^1;
sbitlcden=P2^2;
sbits1=P1^0;
sbits2=P1^1;
sbits3=P1^2;
sbits4=P1^3;
sbitled=P1^4;
sbitl=P2^4;
//sbitbeen=P3^0;
unsignedcharcodestr1[]={"t:
11-12-25"};
unsignedcharcodestr2[]={"00:
00:
00"};
uchardatadisdata[5];
uinttvalue;//温度值
uchartflag;//温度正负标志
ucharcount,s1num,s2num;
charmiao,shi,fen;
/*************************lcd1602程序**************************/
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//写命令
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)//写数据
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidinit()
{
ucharnum;
rw=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<16;num++)//第一排
{
write_date(str1[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)//第二排
{
write_date(str2[num]);
delay
(2);
}
}
/******************************ds1820程序***************************************/
voiddelay_18B20(unsignedinti)//延时1微秒
{
while(i--);
}
voidds1820rst()//ds1820复位
{
unsignedcharx=0;
DQ=1;//DQ复位
delay_18B20(4);//延时
DQ=0;//DQ拉低
delay_18B20(100);//精确延时大于480us
DQ=1;//拉高
delay_18B20(40);
}
uchards1820rd()//读数据
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
voidds1820wr(ucharwdata)//写数据
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=wdata&0x01;
delay_18B20(10);
DQ=1;
wdata>>=1;
}
}
read_temp()//读取温度值并转换
{
uchara,b;
ds1820rst();
ds1820wr(0xcc);///跳过读序列号
ds1820wr(0x44);//启动温度转换
ds1820rst();
ds1820wr(0xcc);//跳过读序列号
ds1820wr(0xbe);//读取温度
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{
tvalue=~tvalue+1;
tflag=1;
}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小?
return(tvalue);
}
/*******************************************************************/
voidds1820disp()//温度值显示
{
ucharflagdat;
disdata[0]=tvalue/1000+0x30;//百位数
disdata[1]=tvalue%1000/100+0x30;//十位数
disdata[2]=tvalue%100/10+0x30;//个位数
disdata[3]=tvalue%10+0x30;//小数位
if(tflag==0)
flagdat=0x20;//正温度不显示符号
else
flagdat=0x2d;//负温度显示负号:
-
if(disdata[0]==0x30)
{
disdata[0]=0x20;//如果百位为0,不显示
if(disdata[1]==0x30)
{
disdata[1]=0x20;//如果百位为0,十位为0也不显示
}
}
write_com(0x80+2);
write_date(flagdat);//显示符号?
write_com(0xc1);
write_date(disdata[0]);//显示百位
write_com(0x80+3);
write_date(disdata[1]);//显示十位
write_com(0x80+4);
write_date(disdata[2]);//显示个位
write_com(0x80+5);
write_date(0x2e);//显示小数点
write_com(0x80+6);
write_date(disdata[3]);//显示小数位
}
/********************时间设置***********************************/
voidtimer0_init()
{
TMOD=0x01;
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);
}
voidkeyscan()
{
rw=0;
if(s1==0)
{
delay(5);//消除抖动
if(s1==0)
{s1num++;
while(!
s1);
if(s1num==1)
{
TR0=0;
//EA=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);//时的位置
//delay(500);
//s1num=0;
}
if(s1num==4)
{
s1num=1;
write_com(0x80+0x40+10);
//write_com(0x0c);
//TR0=1;
}
}
}
if(s1num!
=0)//k1不按时候,k2,k3,k4,无作用
{
if(s2==0)
{
delay(5);//防抖
if(s2==0)
{
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);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);//防抖
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);