填空 (1)为了实现定时器/计数器功能,51单片机内部具有相应的__寄存器,它进行__计数。定时器/计数器0即T/CO的计数寄存器由__构成的。 (12)定时器/计数器启动后,单片机内部时钟或者 __引脚接收到的__将引起计数寄存器加1。 (13)定时器/计数器的内部计数寄存器是从__开始加1计数的,当计数溢出时,特殊功能寄存器__中的中断请求标志位 __自动置“1”。 (14)当特殊功能寄存器TMOD中的GATE位设置为1时,定时器/计数器的启动受__和__的共同控制。 (15定时器/计数器工作方式__具有初值自动重载功能。选择定时器/计数器1即T/C1的工作方式,应设置特殊功能寄存器__的__(高/低)4位。 程序设计 写一段程序实现,制作一个采用LCD1602液晶显示模块的电子时钟,显示当前的时间。显示格式为“星期×时时:分分:秒秒”。同时设置4个功能按键K1~K4。K1使分钟数加,K2使小时数加,K;k3使星期几加1,K4使所有字位显示信息清零。
时间: 2024-01-24 21:17:34 浏览: 78
(1)为了实现定时器/计数器功能,51单片机内部具有相应的定时器/计数器寄存器,它进行定时或计数。定时器/计数器0即T/CO的计数寄存器由TH0和TL0构成的。
(12)定时器/计数器启动后,单片机内部时钟或者外部引脚接收到的脉冲信号将引起计数寄存器加1。
(13)定时器/计数器的内部计数寄存器是从0开始加1计数的,当计数溢出时,特殊功能寄存器TCON中的中断请求标志位TF自动置“1”。
(14)当特殊功能寄存器TMOD中的GATE位设置为1时,定时器/计数器的启动受外部引脚和软件的共同控制。
(15)定时器/计数器工作方式2具有初值自动重载功能。选择定时器/计数器1即T/C1的工作方式,应设置特殊功能寄存器TMOD的高4位。
程序设计:
```c
#include <reg52.h>
#include <intrins.h>
#define LCD1602_DB P0 //定义1602数据口
sbit LCD1602_RS = P2 ^ 6; //定义1602命令/数据选择端口
sbit LCD1602_RW = P2 ^ 5; //定义1602读/写选择端口
sbit LCD1602_EN = P2 ^ 7; //定义1602使能端口
void InitLcd1602(); //初始化1602液晶
void WriteCommandToLcd1602(); //向1602写命令
void WriteDataToLcd1602(); //向1602写数据
void DisplayStringOnLcd1602(); //在1602上显示字符串
void Delay1ms(); //1ms延时函数
unsigned char time[8] = {0}; //存储时间信息
unsigned char week[7][4] = { //存储星期信息
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"};
unsigned char k1 = 0, k2 = 0, k3 = 0, k4 = 0; //功能按键状态变量
void main()
{
TMOD = 0x01; //定时器/计数器1工作方式1,16位计数器模式
TH1 = 0x4C; //定时器初值,1ms中断一次
TL1 = 0x00;
TR1 = 1; //启动定时器
InitLcd1602(); //初始化1602液晶
while (1)
{
if (k1) //按下K1,分钟数加1
{
k1 = 0;
time[1]++;
if (time[1] == 60)
{
time[1] = 0;
time[0]++;
if (time[0] == 24)
{
time[0] = 0;
}
}
}
if (k2) //按下K2,小时数加1
{
k2 = 0;
time[0]++;
if (time[0] == 24)
{
time[0] = 0;
}
}
if (k3) //按下K3,星期数加1
{
k3 = 0;
time[6]++;
if (time[6] == 7)
{
time[6] = 0;
}
}
if (k4) //按下K4,所有字位显示信息清零
{
k4 = 0;
for (int i = 0; i < 8; i++)
{
time[i] = 0;
}
}
DisplayStringOnLcd1602(); //在1602上显示时间和星期信息
}
}
void InitLcd1602()
{
WriteCommandToLcd1602(0x38); //8位数据总线,双行显示,5×7点阵字符
WriteCommandToLcd1602(0x08); //关显示
WriteCommandToLcd1602(0x06); //地址自动加1,不移位
WriteCommandToLcd1602(0x0C); //开显示,光标不显示
WriteCommandToLcd1602(0x01); //清屏
}
void WriteCommandToLcd1602(unsigned char command)
{
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_EN = 1;
LCD1602_DB = command;
Delay1ms();
LCD1602_EN = 0;
}
void WriteDataToLcd1602(unsigned char data)
{
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_EN = 1;
LCD1602_DB = data;
Delay1ms();
LCD1602_EN = 0;
}
void DisplayStringOnLcd1602()
{
unsigned char i;
for (i = 0; i < 8; i++)
{
WriteCommandToLcd1602(0x80 + i); //设置显示位置
WriteDataToLcd1602(time[i] / 10 + '0'); //显示十位
WriteDataToLcd1602(time[i] % 10 + '0'); //显示个位
if (i == 1 || i == 3) //冒号
{
WriteDataToLcd1602(':');
}
if (i == 6) //星期信息
{
WriteDataToLcd1602(' ');
WriteDataToLcd1602(week[time[6]]);
}
}
}
void Delay1ms()
{
unsigned char i, j;
_nop_();
i = 10;
j = 130;
do
{
while (--j);
} while (--i);
}
void Timer1() interrupt 3
{
TH1 = 0x4C;
TL1 = 0x00;
time[7]++;
if (time[7] == 20) //20ms中断一次,计数器加1
{
time[7] = 0;
time[2]++;
if (time[2] == 60)
{
time[2] = 0;
time[1]++;
if (time[1] == 60)
{
time[1] = 0;
time[0]++;
if (time[0] == 24)
{
time[0] = 0;
}
}
}
}
if (!P3_0) //K1按下,k1标志位置1
{
Delay1ms();
if (!P3_0)
{
k1 = 1;
while (!P3_0);
}
}
if (!P3_1) //K2按下,k2标志位置1
{
Delay1ms();
if (!P3_1)
{
k2 = 1;
while (!P3_1);
}
}
if (!P3_2) //K3按下,k3标志位置1
{
Delay1ms();
if (!P3_2)
{
k3 = 1;
while (!P3_2);
}
}
if (!P3_3) //K4按下,k4标志位置1
{
Delay1ms();
if (!P3_3)
{
k4 = 1;
while (!P3_3);
}
}
}
```
阅读全文