这次实验是上一个实验在的基础上,添加了中断模块,显示时钟
一、实验目的:
(一)进一步熟悉 LCD1602 与单片机的电路连接;
(二)进一步熟悉 LCD1602 的引脚功能;
(三)进一步掌握 LCD1602 的时序;
(四)进一步掌握单片机对 LCD1602 的控制方法;
(五)进一步掌握定时器的工作原理及各种寄存器的应用。
二、主要仪器设备及耗材:
(一)电脑一台;
(二)单片机开发板一套。
三、实验原理
-----利用所学的单片机知识LCD1602的知识及电路知识编程实现单片机I/O 口控制 LCD1602 的显示时钟。
四、实验内容及步骤
(一)实验内容 编程实现 LCD1602 显示时钟,显示格式为:00:00:00,并让时间走 起来。
(二)实验步骤 1.根据实验七 LCD1602 的电路原理图编写 C 程序,调试并烧写入单片机
#include <reg51.h>
/*
1.基本操作时序
(1) 读状态:输入:RS=L, RW=H, E=H 输出:D0~D7=状态字
(2) 写指令:输入:RS=L, RW=L,D0D7=指令码, E=高脉沖 输出:无
(3) 读数据:输入:RS=H, RW=H, E=H 输出:D0~D7=数据
(4) 写数据:输入:RS=H, RW=L, D0~D7=数据, E=高脉冲 输出:无
*/
#define DB P0
sbit RS=P2^6;
sbit RW=P2^5;
sbit EN=P2^7;
int t=0,h=23,m=59,s=50; //初始化显示的时间h,m,s
char number[] = "0123456789";//用于显示时钟的时分秒的数
void delay(unsigned int ms)
{
char i;
while(ms--)
for(i=0; i<110; i++);
}
void write_com(char data_)//写指令
{
EN=0; //
RS=0; //1表示数据,0表示指令,通过芯片告诉LCD1602,我要使用指令了
RW=0; //1表示读取,0表示写入,在告诉LCD1602,我要用写的方式使用指令了,即写入指令
//LCD1602,收到指令没有立即执行,还要等另外一个信号,就是EN使能信号
DB=data_; //写入指令
delay(5);
EN=1;
delay(5); //给予EN 5ms的脉冲宽度,LCD1602才开始执行
EN=0; //置零
}
void write_data(char data_)
{
EN=0;
RS=1; //1表示数据,0表示指令,通过芯片告诉LCD1602,我要使用数据了
RW=0; //1表示读取,0表示写入,在告诉LCD1602,我要用写的方式使用数据了,即写入数据
//LCD1602,收到指令没有立即执行,还要等另外一个信号,就是EN使能信号
DB=data_; //写入数据
delay(5);
EN=1;
delay(5); //给予EN 5ms的脉冲宽度,LCD1602才开始执行
EN=0; //置零
}
void init_com()
{
write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
write_com(0x0c); //
write_com(0x06); //读写一个字符后,地址指针+1,光标+1
write_com(0x01);
}
void init_timer()
{
TMOD = 0x00;
TH0 = (8192-5000)/32;
TL0 = (8192-5000)%32;
EA=1;
ET0=1;
TR0=1;
}
void time0() interrupt 1
{
//5000个机械周期,一个机械周期为1us,所以溢出需要5ms
//计时到达5ms时,即高8位和低五位填充满时,计数器溢出,自动向CPU发送溢出中断请求
TH0 = (8192-5000)/32; //填充高8位
TL0 = (8192-5000)%32; //填充低5位
t++; //hh-mm-ss
if(t==200) //t=200后达到一秒,s++;
{
t=0;
s++;
if(s==60)
{
s=0;
m++;
if(m==60)
{
m=0;
h++;
if(h==24)
{
h=0;
}//先判断是否到达24小时,到达则清零,然后在显示
write_com(0x80+0x04);
write_data(number[h/10]);
write_com(0x80+0X05);
write_data(number[h%10]);
}//先判断是否到达60分,到达则时进一,分清零,然后在显示
write_com(0x80+0x07);
write_data(number[m/10]);
write_com(0x80+0X08);
write_data(number[m%10]);
}//先判断是否到达60秒,到达则分进一,秒清零,然后在显示
write_com(0x80+0x0A);
write_data(number[s/10]);
write_com(0x80+0X0B);
write_data(number[s%10]);
}
}
void init_display()//初始化显示时钟的时间
{
write_com(0x80+0x04);
write_data(number[h/10]);//h
//write_data(0x05);
write_data(number[h%10]);//h
write_data(':'); //-
write_data(number[m/10]);//m
write_data(number[m%10]);//m
write_data(':'); //-
write_data(number[s/10]);//s
write_data(number[s%10]);//s
}
int main()
{
init_timer();
init_com();
//write_com(0x80);
init_display();
while(1);
}