SCLK:
串行时钟输入端,控制数据的输入与输出。
I/O:
三线接口时的双向数据线。
CE:
输入信号,在读、写数据期间必须为高
2.21602字符液晶以及显示模块介绍
2.2.11602液晶概述
工业字符型液晶,1602是指显示的内容为16*2,即能够同时显示两行,每行16个字符。
常见的1602字符液晶有两种,一种显示的是绿色背光黑色字体,另一种显示蓝色背光白色字体,目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的。
本课题所用1602液晶模块,显示屏是蓝色背光白色字体。
如图2-1所示
图2-21602字符液晶
Figure2-21602characterLCD
2.2.21602引脚介绍
编号
符号
引脚说明
编号
符号
引脚说明
1
GND
电源地
2
VCC
电源正极
3
V0
液晶显示对比度调节端
4
RS
数据/命令选择端
5
RW
读写选择
6
E
使能信号
7
D0
数据口
8
D1
数据口
9
D2
数据口
10
D3
数据口
11
D4
数据口
12
D5
数据口
13
D6
数据口
14
D7
数据口
15
BLA
背光电源正
16
BLK
背光电源负
表2-11602字符液晶引脚说明
Table2-11602characterLCDpin
各个引脚具体功能说明:
第1脚:
GND为地电源。
第2脚:
VCC接5V正电源。
第3脚:
VO为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生重影,使用一个1K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器,低电平时选择指令寄存器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
DB0~DB7为8位双向数据线。
第15~16脚:
背光灯电源。
3系统硬件设计
3.1电路设计框图
图3-1硬件框图
Figure3-1thehardwareblockdiagram
3.2系统硬件概述
电路以STC15F2K60S2单片机最小系统为控制核心,时钟电路由高精度低功耗的DS1302提供,采用三线接口与CPU进行同步通信,输入部分采用四个独立式按键S1、S2、S3、S4。
1602液晶显示部分,D0-D7口与单片机P0口相连。
3.3实验原理图见附录一
4系统的软件设计
4.1程序流程框图
图4-1主程序框图
Figure4-1themainprogramblockdiagram
5器件清单
名称
个数(个)
名称
个数(个)
LCD1602A显示屏
1
DS1302
1
触点按键
5
自锁开关
1
LED
2
蜂鸣器
1
电位器
1
三极管(8050)
1
电解电容
1
陶瓷电容
2
12MHz晶振
1
1K电阻
6
300
电阻
1
STC15F2K60S2单片机
1
表5-1器件表
Table5-1devicetable
6程序代码见附录二
7PCB图见附录三
8设计感想
通过本次论文设计,使我加深了对单片机的认识,并且熟悉了单片机系统的设计流程,收获丰硕。
功能上基本达标:
时钟与闹钟的显示,调时间和闹钟功能以及闹钟鸣叫功能。
时钟与闹钟显示功能,精确度完全可以满足日常生活显示时间的需要;
从这次的论文设计中,我真正的体会到,知识的重要性,特别是要理论联系实际,把我们所学的理论知识运用到实际生活当中。
通过本次课程设计,虽然仅有短短两周时间,却让我重新学到了很多知识。
不但很好地加强了自己寻找学习资源的能力,了解了DS1320时钟芯片的工作原理以及状态控制字,而且在很大程度上提高了我的编程和调试能力。
并且在这要感谢在这段生产实习中给予我帮助的老师和同学。
正因为有了大家的帮助我才能顺利完成生产实习。
参考文献
[1]李庆亮.C语言程序设计实用教程.北京:
机械工业出版社,2005.3(1——100)。
[2]康华光.电子技术基础数字部分.北京:
高等教育出版社,2008(1——560)。
[3]杨志忠.数字电子技术.北京:
高等教育出版社,2003.12(30——100)。
[4]杨欣.电子设计从零开始.北京:
清华大学出版社,2005(10——200)。
附录一:
系统原理图
附录二:
程序代码
#include//52单片机头文件,规定了52单片机的寄存器和IO口等
#include//_nop_空指令及左右循环移位子函数库
#defineucharunsignedchar//宏定义
#defineuintunsignedint//宏定义
sbitlcden=P2^2;//定义下面通过lcden来操作P2^7口,1602液晶使能控制端
sbitlcdwr=P2^1;//定义下面通过lcdrw来操作P2^5口,1602读写选择端
sbitlcdrs=P2^0;//定义选数据寄存器选指令寄存器控制端
sbitLED_R=P1^0;
sbitLED_G=P1^1;
sbitsda=P3^4;//定义DS1302数据总线
sbitrst=P3^5;//DS1320复位
sbitsck=P3^6;//定义时钟总线
sbits1=P2^7;//定义设置按钮
sbits2=P2^6;//定义调时按钮
sbits3=P2^5;//定义确定按钮
sbits4=P2^4;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitBELL=P2^3;
charfen,shi,miao,ri,yue,nian,zhou,s1num,s2num,s4num,flag1,flag2,lshi,lfen;
uchartable[]={"2015--"};//要写入1602液晶的数据
uchartable1[]={":
:
:
"};//字库中的字可直接以外加""号的形式直接写入
uchartable2[]={"hanxiao!
"};//欢迎界面
uchartable3[]={"HappyEveryDay!
"};//欢迎界面
/******************************************************************************
时函数,z的取值为这个函数的延时ms数,delay(200);大约延时200ms.delay(500);大约延时500ms
******************************************************************************
voidDelay1ms()//@12.000MHz
{unsignedchari,j;
i=12;
j=169;
do
{
while(--j);
}while(--i);
}
voiddelay(uintz)
{
while(z--)
{
Delay1ms();
}}
/******************蜂鸣器函数************************************************/
voiddidi()
{
uchari,j;
for(i=0;i<60;i++)
{
BELL=0;
for(j=0;j<255;j++);
BELL=1;
for(j=0;j<255;j++);
}
}
/***************向1602液晶中写一个指令**************************************/
voidwrite_com(ucharcom)
{
lcdwr=0;//lcdwr为读写控制端,lcdwr=0,这里可不写
lcdrs=0;//液晶rs接口为0时,写指令,rs为1时写数据
P0=com;//将要写的指令赋给P0口,
delay(5);//由1602读写操作时序图,先将指令赋给P0口,延时后将使能
lcden=1;//端lcden置高,再延时一段时间,然后将lcden置低,这样指令
delay(5);//就写入到LCD了
lcden=0;
}
/*************************向液晶写数据***************************************/
voidwrite_data(uchardate)//与写指令类似,这里lcdrs设为1
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/**************************初使化1602液晶************************************/
voidinit_1602()
{
lcdwr=0;
lcden=0;
write_com(0x38);//设置LCD为16*2显示、5*7点阵、8位数据接口模式
write_com(0x0c);//开显示、不显示光标
write_com(0x06);//写一个字符后,地址指针加1
write_com(0x01);//显示清0
}
/*****************************************************************************/
voidgudingtime_1602()
{
ucharnum;
write_com(0x80);//将指针指向初始位置
for(num=0;num<16;num++)//循环函数,用于将"2012--"写入液晶
write_data(table[num]);
write_com(0x80+0x40);//将指针指向1602液晶的第二行
for(num=0;num<16;num++)//功能与上同,用于将":
:
:
"写入
write_data(table1[num]);
}
/************************显示欢迎界面函数*************************************/
voiddisplaystar(void)
{
uchari;
write_com(0x80);
for(i=0;i<16;i++)
write_data(table2[i]);
write_com(0x80+0x40);
for(i=0;i<16;i++)
write_data(table3[i]);
}
/*************************显示时间、日期子函数*********************************/
voidwrite_sfm(ucharadd,uchartime)//用于在1602上显示年、月、日、时、分、秒。
Add为显示位置,time为要显示的内容
{
ucharshiwei,gewei;
shiwei=time/16;//将从DS1302中读取的BCD码数据转化成10进制个位和10
gewei=time%16;//进制十位
write_com(add+0x80);//定义显示在液晶的什么位置
write_data(0x30+shiwei);//由1602液晶字库可知,0~9的数据码分别对应0x30~0x39
write_data(0x30+gewei);//初使化中设定了写一个字符后,地址指针加1,因此这里
}//不用重新光标写位
/************************显示周子函数*****************************************/
voidwrite_zhou(uchartime1)//用于在1602上显示周信息,与显示
{//时间日期子函数类似
uchargewei;
gewei=time1%16;//一周七天,因此只需个位
write_com(0x80+13);
write_data(0x30+gewei);
}
/*************************写数据字节子函数************************************/
voidInput_1byte(ucharTD)//写一字节数据
{
uchari;
ACC=TD;
for(i=8;i>0;i--)
{
sda=ACC0;
sck=1;
sck=0;
ACC=ACC>>1;
}
}
/***********************读数据字节子函数**************************************/
ucharOutput_1byte(void)//读一字节数据
{
uchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=sda;
sck=1;
sck=0;
}
return(ACC);
}
/*************************写DS1302数据函数***********************************/
voidwrite_1302(ucharDS_ADD,ucharDS_DAT)//写操作
{
rst=0;
sck=0;
rst=1;
Input_1byte(DS_ADD);
Input_1byte(DS_DAT);
sck=1;
rst=0;
}
/*************************读DS1302数据函数***********************************/
ucharread_1302(ucharDS_ADD)//读操作
{
ucharDS_INF;
rst=0;
sck=0;
rst=1;
Input_1byte(DS_ADD);
DS_INF=Output_1byte();
sck=1;
rst=0;
return(DS_INF);
}
/***********************初始化DS1302子函数***********************************/
voidinital_1302()
{
write_1302(0x8e,0x00);//禁止写保护
write_1302(0x90,0xaa);//定义充电
write_1302(0x80,0x00);//秒
write_1302(0x84,0x00);//时
write_1302(0x82,0x00);//分
write_1302(0x8c,0x15);//年
write_1302(0x88,0x07);//月
write_1302(0x86,0x14);//日
write_1302(0x8a,0x02);//星期
write_1302(0xc0,0x00);//闹钟小时初始化
write_1302(0xfc,0x05);//闹钟分钟初始化
write_1302(0x8e,0x80);//开保护
}
/******************************************************************************
扫描函数
******************************************************************************/
voidkeyscan()
{
if(s1==0&&s4num==0)//按键1按下且s4再次之前未曾按过
{
delay(5);
if(s1==0&&s4num==0)
{
flag1=1;
s1num++;
while(!
s1);didi();
if(s1num==1)
{
write_com(0x80+0x40+8);//光标移动到**位置
write_com(0x0f);//显示光标
}
if(s1num==2)
{
write_1302(0x8e,0x00);//禁止写保护
write_1302(0x80,miao);//写入秒信息
write_1302(0x8e,0x80);//开写保护
write_com(0x80+0x40+5);
}
if(s1num==3)
{
write_1302(0x8e,0x00);
write_1302(0x82,fen);
write_1302(0x8e,0x80);
write_com(0x80+0x40+2);
}
if(s1num==4)
{
write_1302(0x8e,0x00);
write_1302(0x88,yue);
write_1302(0x8e,0x80);
write_com(0x80+13);
}
if(s1num==5)
{
write_1302(0x8e,0x00);
write_1302(0x84,shi);
write_1302(0x8e,0x80);
write_com(0x80+10);
}
if(s1num==6)
{
write_1302(0x8e,0x00);
write_1302(0x86,ri);
write_1302(0x8e,0x80);
write_com(0x80+7);
}
if(s1num==7)
{
write_1302(0x8e,0x00);
write_1302(0x8c,nian);
write_1302(0x8e,0x80);
write_com(0x80+4);
}
if(s1num==8)
{
flag1=0;
s1num=0;
write_1302(0x8e,0x00);
write_1302(0x8a,zhou);
write_1302(0x8e,0x80);
write_com(0x0c);//不显示光标
}
}
}
//}
/*****************************************************************************/
if(s1num!
=0&&s4num==0)//按键1按下*次且s4再次之前未曾按过
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);didi();
if(s1num==1)
{
intx1,x2;
x1=miao%16;
x2=miao/16;
x1++;
if(x1==10)
{
x1=0;
x2++;
if(x2>=6)
x2=0;
}
miao=x1+x2*16;
write_sfm(7+0x40,miao);//将修改的数送到1602显示
write_com(0x80+0x40+8);//挪回光标
}
if(s1num==2)
{
intx3,x4;
x3=fen%16;
x4=fen/16;
x3++;
if(x3==10)
{
x3=0;
x4++;
if(x4>=6)
x4=0;
}
fen=x3+x4*16;
write_sfm(4+0x40,fen);
write_com(0x80+0x40+5);
}
if(s1num==3)
{
intx5,x6;
x5=shi%16;
x6=shi/16;
x5++;
if(x6>=2&&x5>=4)
{
x5=0;
x6=0;
}
if(x5==10)
{
x5=0;
x6