单片机课程设计实验报告LCD电子时钟.docx
- 文档编号:10933386
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:21
- 大小:58.64KB
单片机课程设计实验报告LCD电子时钟.docx
《单片机课程设计实验报告LCD电子时钟.docx》由会员分享,可在线阅读,更多相关《单片机课程设计实验报告LCD电子时钟.docx(21页珍藏版)》请在冰豆网上搜索。
单片机课程设计实验报告LCD电子时钟
单片机原理与应丿
电子信息工程学院自动化0706全宏宇
指导教师:
设计目标
LCD显示电子钟的基本功能
LCD显示电子钟的基本要求
1,
掌握单片机幵发编程设计的基本流程;
2,
了解Keil及Proteus软件的基本使用;
3,
了解LCD的基本使用;
4,
学习单片机硬件制作。
具体实现
1,软件平台
1)Keil编程
Keil的幵发工具的使用的基本过程:
0创建C或汇编语言的源程序;
@编译或汇编源文件;
03纠正源文件中的错误;
04从编译器和汇编器连接目标文件;
05测试连接的应用程序。
2)Proteus仿真
Proteus软件不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。
它是目前最好的仿真单片机及外围器件的工具。
在编译方面,它也支持IAR,Keil,PLAB等多种编译器。
2,硬件开发平台
JD51幵发板的基本资料
01LED电路,8只独立LED发光管,可做指示或各种闪烁效果用。
02数码管电路,4只共阳一体8段数码显示管,可实现各种数据显示,如计数、时钟等。
03蜂鸣器电路,可用于设计各种提示音、演奏音乐等。
04键盘电路,学习按键控制相关编程。
05LCD显示电路,编程控制LCD显示。
06串口电路,学习编程实现JD51和PC或其他符合该通信协议的电路之间的通信。
JD51。
07红外电路,通过选配的红外遥控器,学习红外解码并可实现红外遥控
08温度模块电路,采用一线式温度传感器实现温度的采集并可显示在数码管或者LCD上,通过温度数据处理便可实现温度控制器功能。
09除了以上提到的可编程电路本学习板还有一些常用的不可编程电路,包括电
源电路、复位电路、晶振电路等。
3,总体设计
1)基本资源的使用
本次实验采用了89C52型单片机,1602LCD液晶显示屏,蜂鸣
器。
为了实现时钟,定时,闹钟,秒表的功能,用到了单片机的外部中断,
计时器中断,及
I/O端口.
资源
功能
外部中
断
外部中断INT1
模式选择(时钟,调时,秒表,闹
钟)
外部中断INTO
秒表的暂停,清零
定时器
定时器TO
秒表,时钟定时基准
定时器T1
音乐闹铃的音符产生
I/O端口
P1,P2
LCD接口,蜂鸣器
2)软件仿真
(1)程序设计的一些关键问题(具体参照后面的程序清单)
®建立Keil工程时,注意对程序编译环境进行设置;
设置内容包括器件,频率,产生hex文件等。
©LCD管脚及控制字;
LCD管脚的定义
控制字
1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。
指令1:
清显示,指令码01H,光标复位到地址00H位置指令2:
光标复位,光标返回到地址00H
指令3:
光标和显示位置设置I/D,光标移动方向,高电平右移,低电平左移,
S:
屏幕上所有文字是否左移或右移,高电平表示有效,低电平表示无效。
指令4:
显示幵关控制。
D:
控制整体的显示幵与关,高电平表示幵显示,低电平表示关显示。
C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:
光标或显示移位S/C:
高电平时显示移动的文字,低电平时移动光标指令6:
功能设置命令DL:
高电平时为4位总线,低电平时为8位总线N:
低
电平时为单行显示,高电平时为双行显示,F:
低电平时显示5X7的点阵字符,
高电平时显示5X10的显示字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址BF:
忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。
©LCD实现滚动显示;
方法一:
采用LCD1602控制命令,显示后画面移动一个字符;
方法二:
循环使用显示不同位置,形成滚动效果。
©5秒表主要是产生计时基准0.01秒,有了基准之后需要解决的问题是如何实现有效的暂停,清零(达到精准动作),采用中断是很不错的结果。
©6闹铃
主要是如何实现闹铃关闭的逻辑,if(f&&g)语句可以实现这一动作。
®提高计时精度
本程序除了调时模式外,其他模式的时候时钟都在跑动,提高了因模式转换而导致的时间精度降低。
2)Proteus仿真
在Proteus中画出如下电路图,添加hex文件,进行虚拟仿真。
2)开发板运行调试
在JD51板上烧制程序,根据实际的效果,对中断的反应时间,显示效果
做出了调整,整体效果不错,只是音乐的效果不佳,主要是由于如果将蜂鸣器换成扬声器效果会好些,还可以在程序中增加节拍来增加音乐效果。
4,硬件制作
根据仿真电路图购买元件进行焊接,下载程序效果后,液晶显示器显示乱码,
检查电路后已无连接错误,但功能依然没有实现,相关检查在进行中。
本次课程设计系统地学习了单片编程幵发及实际电路的制作。
学习了Ke的C语言编程的基本知识,Proteus仿真软件的模拟仿真,JD51幵发实验板的使用,本次课设,时间了较多的其他案例,比较全面的掌握了单片机的运营,包括编程,电路,LCD器件等,在知识上有了很多的长进。
本次课程设计还有很多其他收获,锻炼了自学的能力,特别是动手实践方面的东西,让我深深感受到理论与实际的差距,实际当中会有一些小的问题,这些问题是意想不到的,需要去思考,去解决,这是很锻炼人的。
四,程序
#include
#include
#defineucharunsignedchar
#defineulongunsignedlong
#defineuintunsignedint
ucharidata
welcome[16]={"
clock
"};
//定义第一行显
示数组
ucharidata
lwelcome[16]={"
clock
"};
//定义第一行显示数
ucharidata
llwelcome[16]={"
clock
"};
//
定义第一行显
示数组
ucharidata
lllwelcome[16]={"
clock"};
//
定义第一行显
示数组
ucharidatasslcdtimer[16]={"
00:
00:
00"};
ucharidatatsslcdtimer[16]={"
00:
00:
00"};
ucharidata
lcdtimer[16]={"
00:
00:
00
"};
//
定义第二行显
示数组
ucharidata
mlcdtimer[16]={"
00:
:
"};
//
定义第二行显
示数组
ucharidata
hlcdtimer[16]={"
:
00:
"};
//
定义第二行显
示数组
ucharidata
setlcdtimer[16]={"
00:
01:
00"};
uchartimecount;
uchartemps;
bittimeflag;
bitsstimeflag;
sbitring=PSO;//
蜂鸣闹铃
sbite=P2A7;//
LCD显示器E
sbitrw=P2八6;//
LCD显示器RW
sbitrs二P2八5;//
LCD显示器RS
sbitP1O=PMO;//
测试用闪灯
sbitKey二P3八2;//
秒表暂停,清零
sbitKeyO=卩3八3;//
调时,设定闹钟时间,秒表选择
sbitKey1=卩3八4;//
调时,设定闹钟时间改变
ucharth1_f;//
在中断中装载的TO的值高8位
uchartl1_f;//
在中断中装载的TO的值低8位
uintm=O;
uintn=O;
ulongi;
uintf=O,g=1;
uintj,k;
ucharcodefreq[3][14]=
{OxF2,Ox42,
0xF5,0x17,0xF5,0xB6,0xF6,0xD0,0xF7,0xD1,0xF8,0xB6},{0xF9,0x21,0xF9,0xE0,0xFA,0x8B,0xFA,0xD7,0xFB,0x68,0xFB,0xE8,0xFC,0x5B},{0xFC,0x8D,0xFC,0xEE,0xFD,0x44,0xFD,0x6D,0xFD,0xB4,0xFD,0xF4,0xFE,0x2D},
};//音乐频率表,低音,中音,高音,系统振荡频率11.0592MHz
3,23,23,26,23,22,21,25,23,22,21,16,21,15,26,25,23,25,31,26,25,26,23,25,26,25,23,22,21,16,25,23,22,22,23,23,23,26,23,22,21,25,23,22,21,16,21,15};
//编制音乐
//**************************************************//软件延时函数(系统晶振为11.0592MHz),延时时间约为40口s
//入口条件:
无符号整型变量del1,最终的延时时间为(del1*40)卩s
//**************************************************voiddelay(uintdell)
uchardel2;
for(;del1>0;del1--)
for(del2=10;del2>0;del2--);
//**************************************************//液晶显示器判忙函数
//**************************************************voidbusy()
uchartemp;
rs=0;
rw=1;
while((temp&0x80)==0x80)
P0=0xff;
e=1;
temp=P0;
e=0;
//**************************************************//向液晶显示器写命令函数
//**************************************************voidWR_Com(uchartemp)
busy();
rs=0;
rw=0;
P0=temp;
e=1;
e=0;
//**************************************************
//向液晶显示器写数据函数
//**************************************************voidWR_Data(ucharnum)
busy();
rs=1;
rw=0;
P0=num;
e=1;
e=0;
//**************************************************//向液晶显示器写入显示数据函数
//入口条件:
液晶显示器行首地址(指示第一行还是第二行)和待显示数组的首地址
//**************************************************//voiddisp_lcdchar(ucharaddr,uchartemp1)
//{
//}
voiddisp_lcd(ucharaddr,uchar*temp1)
uchari;
WR_Com(addr);
delay(100);
for(i=0;i<16;i++)
WR_Data(temp1[i]);
delay(100);
//**************************************************//液晶显示器初始化函数
//**************************************************voidlcd_ini()
chari;
for(i=3;i>0;i--)
P0=0x30;
rs=0;
rw=0;
e=1;
e=0;
delay(100);
P0=0x38;
rs=0;
rw=0;
e=1;
e=0;
delay(100);
//**************************************************//液晶显示器复位函数
//**************************************************voidlcd_Reset()
WR_Com(0x01);
delay(100);
WR_Com(0x06);
delay(100);
WR_Com(0x0c);
delay(100);
//**************************************************//外部中断函数,秒表暂停,清零
//**************************************************voidmodess()interrupt0using0
delay(10000);
n++;
if(n==3)
n=0;
//**************************************************//外部中断函数,模式选择
//**************************************************voidmodepp()interrupt2using1
delay(30000);
m++;
if(m==6)
n=0;
if(m==7)
m=0;
//**************************************************//定时/计数器中断函数,1S及0.01S//**************************************************voidtimer0()interrupt1using2
TH0=0xdc;
TL0=0x23;
sstimeflag=1;
if(--timecount==0)
timecount=100;
timeflag=1;
//**************************************************//定时/计数器中断函数,装入音乐频率计数初值
//**************************************************voidtimer1()interrupt3using3
TL1=tl1_f;TH0=th1_f;//
调入预定时值
//**************************************************//主函数
//**************************************************voidmain()
P10=1;
lcd_ini();
lcd_Reset();
/*for(i=0;i<10;i++)
单字符从左到右显示
temps=welcome[i];
disp_lcdchar(0x80+1,temps);//LCD
delay(10000);
}*/
disp_lcd(0x80,welcome);
delay(10000);
disp_lcd(0x80,lwelcome);
delay(10000);
disp_lcd(0x80,llwelcome);
delay(10000);
disp_lcd(0x80,lllwelcome);
delay(10000);
disp_lcd(0x80,llwelcome);
delay(10000);
disp_lcd(0x80,lwelcome);
delay(10000);
disp_lcd(0x80,welcome);
//LCD滚动显示
delay(10000);
disp_lcd(0xc0,lcdtimer);
P10=0;
TMOD=0x11;
TH0=0xdc;
TL0=0x23;
TR0=1;
IE=0x86;
timeflag=0;//1秒计时标志
sstimeflag=0;//0.01秒计时标志
timecount=100;
while
(1)
while(m==6)//秒表
IE=0x87;
if(sstimeflag==1)
sstimeflag=0;
sslcdtimer[11]+=1;
if(sslcdtimer[11]>=0x3a)
sslcdtimer[11]=0x30;
sslcdtimer[10]+=1;
if(sslcdtimer[10]>=0x3a)
sslcdtimer[10]=0x30;
sslcdtimer[8]+=1;
if(sslcdtimer[8]>=0x3a)
sslcdtimer[8]=0x30;
sslcdtimer[7]+=1;
if(sslcdtimer[7]>=0x36)
disp_lcd(0xc0,sslcdtimer);
if(n==1)//秒表暂停
disp_lcd(0xc0,sslcdtimer);
if(n>=2)//秒表清零
disp_lcd(0xc0,tsslcdtimer);
for(i=0;i<16;i++)
sslcdtimer[i]=tsslcdtimer[i];
while(m==0||m>=3)//时钟程序,只要不是调时,就一直运行
IE=0x86;
if(timeflag==1)
timeflag=0;
lcdtimer[11]+=1;
if(lcdtimer[11]>=0x3a)
lcdtimer[11]=0x30;
lcdtimer[10]+=1;
if(lcdtimer[10]>=0x36)
lcdtimer[10]=0x30;
lcdtimer[8]+=1;
if(lcdtimer[8]>=0x3a)
lcdtimer[8]=0x30;
lcdtimer[7]+=1;
if(lcdtimer[7]>=0x36)
lcdtimer[7]=0x30;
lcdtimer[5]+=1;
if(lcdtimer[5]>=0x3a)
lcdtimer[4]+=1;
if(lcdtimer[4]>=0x33&&lcdtimer[5]>=0x35)
lcdtimer[5]=0x30;
lcdtimer[4]=0x30;
if(m==0)
disp_lcd(0xc0,lcdtimer);
if(!
Key1)//关掉闹钟
g=0;
if(lcdtimer[8]==setlcdtimer[8]&&lcdtimer[7]==setlcdtimer[7]&&lcdtimer[
if(f&&g)
/*ring=1;
delay(10000);
ring=0;
f=0;*/
IE=0x8e;
j=song1[i]/10-1;
//取
k=2*(song1[i]%10-1);
th1_f=freq[j][k];
出对应的定时值送给T0
tl1_f=freq[j][++k];
TR1=1;
for(n=0;n<50000;n++);//
音符间延
i++;
TR1=0;
f=0;
if(!
Key1)
delay(10000);
timeflag=0;
lcdtimer[8]+=1;
if(lcdtimer[8]>=0x3a)
lcdtimer[8]=0x30;
lcdtimer[7]+=1;
if(lcdtimer[7]>=0x36)
lcdtimer[7]=0x30;
disp_lcd(0xc0,lcdtimer);
delay(8000);
mlcdtimer[11]=lcdtimer[11];
mlcdtimer[4]=lcdtimer[4];
disp_lcd(0xc0,mlcdtimer);
while(m==2)//调时时
if(!
Key1)
delay(10000);
lcdtimer[5]+=1;
if(lcdtimer[5]>=0x3a)
lcdtimer[5]=0x30;
lcdtimer[4]+=1;
if(lcdtimer[4]==0x32&&lcdtimer[5]>=0x34)
lcdtimer[5]=0x30;
lcdtimer[4]=0x30;
disp_lcd(0xc0,lcdtimer);
delay(8000);
hlcdtimer[10]=lcdtimer[10];
hlcdtimer[8]=lcdtimer[8];
hlcdtimer[7]=lcdtimer[7];
disp_lcd(0xc0,hlcdtimer);
while(m==3)//显示闹铃时间
if(!
Key1)
delay(10000);
disp_lcd(0xc0,setlcdtimer);
while(m==4)//调闹铃分
if(!
Key1)
delay(10000);
setlcdtimer[8]+=1;
setlcdtimer[7]+=1;
if(setlcdtimer[7]>=0x36)
setlcdtimer[7]=0x30;
disp_lcd(0xc0,setlcdtimer);
delay(8000);
mlcdtimer[11]=setlcdtimer[11];
mlcdtimer[10]=setlcdtimer[10];
mlcdtimer[5]=setlcdtimer[5];
mlcdtimer[4]=setlcdtimer[4];
disp_lcd(0xc0,mlcdtimer);
while(m==5)//调闹铃时
if(!
Key1)
delay(10000);
setlcdtimer[5]=0x30;
setlcdtimer[4]+=1;
if(setlcdtimer[4]==0x32&&setlcdtimer[5]>=0x34)
setlcdtimer[5]=0x30;
setlcdtimer[4]=0x30;
disp_lcd(0xc0,setlcdtimer);
delay(8000);
hlcdtimer[11]=setlcdtimer[11];
hlcdtimer[10]=setlcdtimer[10];
hlcdtimer[8]=setlcdtimer[8];
hlcdtimer[7]=setlcd
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 课程设计 实验 报告 LCD 电子 时钟
![提示](https://static.bdocx.com/images/bang_tan.gif)