用51单片机和1602液晶做的数字钟

用51单片机和1602液晶做的数字钟
用51单片机和1602液晶做的数字钟

课程设计报告

数字钟

姓名:

学号:

班级:

指导教师:高雪飞

目录

一、设计题目和要求 (1)

二、设计原理与实现功能 (1)

三、元器件介绍………………………………………………

四、电路设计…………………………………………………

五、软件设计…………………………………………………

六、设计总结…………………………………………………

一、设计题目和要求

题目:用STC89C52单片机和1602液晶做的数字时钟

要求:

1.准确计时,以数字形式显示时、分、秒的时间;

2.小时的计时要求为“24翻1”,分和秒的计时为60进制。

二、设计原理与实现功能

设计原理:

控制芯片采用STC89C52RC单片机,晶振频率为11.0592MHZ,采用C语言编程,显示模块采用通用型1602液晶,发声模块采用无源蜂鸣器。

参考资料:51单片机C语言编程,1602datasheet,网络。

本装置使用的1602液晶为5v电压驱动,带背光,可显示两行,每行16个字符,不能显示汉字,内置含128个字符的ASCII字符集字库,只有并行接口,无串行接口,关于1602液晶的接口信号说明,主要技术参数,基本操作时序,RAM地址映射图,数据指针设置,初始化设置,写操作时序和其他设置请查阅1602的相关资料。

计时部分采用T0计时器中断方式1,TO定时器既有定时功能又有计数功能,通过设置与它们相关的特殊功能寄存器可以选择启用定时功能或计数功能。当定时器的计数器计满后,会产生中断,通知CPU该如何处理。关于51单片机的寄存器和中断功能及操作说明请查阅相关资料。

蜂鸣器的发声为单片机的一个引脚加一个三极管控制。

(1.要画出结构框图;2.数字钟的实现方法不止一种,因此必须说明自己

所设计的数字钟采用何种方法、何种原理)

实现功能:

开启装置,则在1602液晶上有左向右划过“hello world I love programing”文字,之后上下两行显示年月日,星期和时间,其中年月日星期只能通过程序更改,时分秒自动从0开始计时,按秒更新,时分秒可用装置的两个按键进行调节,分别为时间设置键,数值增大键,闹钟的时间设置只能通过程序进行更改,一旦液晶显示时间和程序设定时间完全一致,蜂鸣器发声。

(1.基本功能必须实现,在基本要求的基础上可以拓展功能,如报时、校时等;2.具体介绍所实现功能,例如用什么显示等等)

三、元器件介绍

STC89C52单片机X1,通用型1602液晶X1,无源蜂鸣器X1,8055型PNP 型三极管X1,弹性小按键X3,5V电源X1,10K电阻X3,2K电阻X1,万能板或PCB板X1,30PF无极性电容X2,10μF有极性电容X1,10K滑动变阻器X1,发光二极管X1。

其中单片机和1602液晶是重点。

(1.选取的元器件名称、型号、功能等;2.对重点的几个芯片要详细介绍。)

四、电路设计

原理图由单片机最小系统模块,液晶模块,蜂鸣器模块,按键部分组成。

(1.画出电路原理图;2.功能讲解。)

五、软件设计

#include//导入reg52.h头文件,该头文件中定义了52系列单片机内部所有的功能寄存器

#define uchar unsigned char //宏定义

#define uint unsigned int

uchar code table1[]=" hello word! ";//系统开机时显示的界面

uchar code table2[]="Ilove Programing";//系统开机时显示的界面

uchar code table3[]="2015-12-6 sunday ";//定义日期

uchar code table4[]=" 00:00:00 ";//定义初始时间

uchar num,count,hour,minute,sound,key1num;

sbit lcden=P3^4;//液晶使能端

sbit lcdrs=P3^5;//液晶数据/命令选择端

sbit key1=P3^6;//时间设置按键

sbit key2=P3^7;//时间增大键

sbit beep=P2^3;//蜂鸣器信号

void delay(uint k);//延时函数

void write_command(uchar command);//向液晶写命令函数

void write_data(uchar date);//向液晶写数据函数

void write_time(uchar time,uchar x);//向液晶写时间

void init();//初始化函数

void keyscan();//键盘扫描函数

void alarm(uchar hours,uchar minutes,uchar sounds);//设置闹钟函数void main()//主函数

{

init();//首先初始化

while(1)//死循环

{

keyscan();//轮询的方式键盘扫描,一切的轮询都可用中断来处理

alarm(21,45,0); //设定闹钟的定时时刻,参数依次为时分秒,如21:45:00

}

}

void timer()interrupt 1//T0定时器/计数器中断,目的是精准设定一秒的实现

{

TH0=(65536-50000)/256;//重装初值,

TL0=(65536-50000)%256;

count++;

if(count==20)//如果到了20次,说明一秒时间已到

{

count=0; //把count清零重新计时

sound++;

if(sound==60) //秒到了60则进位一分钟

{

sound=0;

minute++;

if(minute==60)//分到了60则进位一小时

{

minute=0;

hour++;

if(hour==24)//新的一天开始

{

hour=0;

}

write_time(hour,4);//写入小时的变化到液晶

}

write_time(minute,7);//写入分钟的变化到液晶

}

write_time(sound,10);//写入秒的变化到液晶

}

}

void delay(uint k) //延时函数

{

uint x,y;

for(x=k;x>0;x--)

for(y=110;y>0;y--);

}

void write_command(uchar command)//写命令

{

lcdrs=0;//置以低电平设定为写命令模式

P1=command;//将要写的命令送到数据总线上

delay(5);//稍作延时以待数据稳定

lcden=1;//给液晶使能端一高电平才能将数据总线上的数据传入液晶delay(5);//稍作延时

lcden=0;//关闭使能端

}

void write_data(uchar date)//写数据到液晶

{

lcdrs=1;//低电平为写数据模式

P1=date;//将数据传入数据总线

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_time(uchar time,uchar x)//用于将时分秒写入液晶数据

{

uchar shi,ge;//定义十位和各位

shi=time/10;//取time的十位

ge=time%10;//取time的各位

write_command(0x80+0x40+x);//定位数据指针即液晶显示的位置,根据x 的不同写入的数据将在液晶上显示在不同的位置

write_data(0x30+shi);//0x30用于将整形的数字转化为字符型的数字,写入时分秒的十位

write_data(0x30+ge); //根据ascii码,从48即0x30起为数字,写入时分秒的个位

}

void init()//初始化函数

{

lcden=0;//关闭使能端

write_command(0x38);//设置液晶16X2显示,5X7点阵,8位数据接口write_command(0x0c);//设置液晶开显示,不显示光标

write_command(0x06);//设置液晶写一个字符后地址指针自动加1

write_command(0x01);//设置液晶显示清零,数据指针清零

write_command(0x80);//重新定义光标即数据指针

write_command(0x80+0x10);//将光标定位在第一行飞显示区域地址处

for(num=0;num<16;num++)

{

write_data(table1[num]);//将table1写入,必须一位一位的写

delay(5);

}

write_command(0x80+0x50);//将光标定位在第二行飞显示区域地址处

for(num=0;num<16;num++)

{

write_data(table2[num]);//将table2写入,必须一位一位的写

delay(5);

}

for(num=0;num<16;num++)

{

write_command(0x18);//液晶整屏左移指令

delay(200);//没200ms移动一位,共移动16位,刚好简要显示的数据全部移入液晶可显示区域

}

write_command(0x80);//将光标定位在第一行显示区域地址处

for(num=0;num<16;num++)

{

write_data(table3[num]);//将日期写入,必须一位一位的写

delay(5);

}

write_command(0x80+0x40);//将光标定位在第二行飞显示区域地址处

for(num=0;num<16;num++)

{

write_data(table4[num]);//将table2写入,必须一位一位的写

delay(5);

}

for(num=0;num<24;num++)//再次整屏左移,不过要移动24位液晶才能显示0x80地址所显示的数据

{

write_command(0x18);

delay(200);

}

TMOD=0x01;

TH0=(65536-50000)/256;//给定时器0装初值用于精确计时

TL0=(65536-50000)%256;

EA=1;//开总中断

ET0=1;//开定时器0中断

TR0=1;//启动定时器0

}

void keyscan()//键盘扫描函数

{

if(key1==0)

{

delay(5);//按键的延时去抖

if(key1==0)

{

key1num++;//时间设置键按下次数记录

while(!key1);//等待按键释放后才进行操作

switch(key1num)//根据key1num的不同值进行不同操作

{

case 1://第一次按下

TR0=0;//关掉定时器0使数字钟停止走时间

write_command(0x80+0x40+11);//光标定位到秒位置

write_command(0x0f);//光标开始闪烁提示用户调整时间

break;

case 2:

write_command(0x80+0x40+8);//光标定位到分钟位置

break;

case 3:

write_command(0x80+0x40+5);//光标定位到小时位置

break;

case 4:

TR0=1;//在小时位置后再一次按键,数字钟重新开始走时间,所以开定时器0中断

write_command(0x0c);//取消光标闪烁

key1num=0;//按键次数统计归零,用于下一次统计

break;

}

}

}

if(key1num!=0)//只有时间设置键被按下后,时间调整键才有效

{

if(key2==0)

{

delay(5);//延时去抖

if(key2==0)

{

while(!key2);//等待按键释放后才进行操作

switch(key1num)//根据key1num的值确定光标的位置,从而确定对时分秒的哪一个进行调整

{

case 1: //设置秒的值

sound++;

if(sound==60)

sound=0;

write_time(sound,10);

write_command(0x80+0x40+11);//将光标冲重新返回到秒的位置,因为写数据指针自动加

break;

case 2: //设置分钟的值

minute++;

if(minute==60)

minute=0;

write_time(minute,7);

write_command(0x80+0x40+8);

break;

case 3: //设置小时的值

hour++;

if(hour==24)

hour=0;

write_time(hour,4);

write_command(0x80+0x40+5);

break;

}

}

}

}

}

void alarm(uchar hours,uchar minutes,uchar sounds)//定义闹钟提示时间{

if(hour==hours&&minute==minutes&&sound==sounds)//当时分秒都满足时

beep=0;//蜂鸣器响

}

(1. 说明软件设计思路;2.主程序和主要的子程序要有程序流程图;3.各个子程序要有功能说明;4.列出全部程序代码;5关键代码部分要予以讲解说明。)

六、设计总结

优点:所用器件少,成本低廉。

缺点:计时不准确。

(1.此种方法设计的数字钟的优点、缺点;2.设计中遇到的问题和解决办法; 3.设计的心得体会。)

相关主题
相关文档
最新文档