蓝桥杯之单片机学习(九)——定时器的进阶综合案例解析
一、训练任务
在CT107D单片机综合训练平台上,利用定时器T0、数码管模块和2个独立按键(J5的2-3短接),设计一个秒表,有清零、暂停、启动功能
- 显示格式为
分-秒-0.05秒(即50ms)
08-26-18表示:8分26秒900毫秒 - 独立按键S4为:暂停/启动
独立按键S5为:清零
按键均为按下有效
二、训练重点
- 定时器的精确定时应用
- 定时器的多时段计时应用
- 定时器、显示模块、独立按键多模块综合应用程序设计的思路与编码
三、代码展示
#include <reg52.h>
sbit S4 = P3^3;
sbit S5 = P3^2;
typedef unsigned int uint;
typedef unsigned char uchar;
uchar code SMG_duanma[18] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};//分别是0-9(对应下标),A-F,“-”,“.”
uchar t_m = 0;
uchar t_s = 0;
uchar t_005s = 0;
//配置HC138
void SelectHC138(uchar channel)
{
switch(channel)
{
case 4:
P2 = (P2 & 0X1F) | 0X80;
break;
case 5:
P2 = (P2 & 0X1F) | 0Xa0;
break;
case 6:
P2 = (P2 & 0X1F) | 0Xc0;
break;
case 7:
P2 = (P2 & 0X1F) | 0Xe0;
break;
}
}
//在pos位码上,显示value段码
void DisplaySMG_Bit(uchar pos, uchar value)
{
SelectHC138(6);
P0 = 0X01 << pos;
SelectHC138(7);
P0 = value;
}
void DelaySMG(uint t)
{
while(t--);
}
//数码管显示
void DisplayTime()
{
DisplaySMG_Bit(7,SMG_duanma[t_005s%10]);
DelaySMG(500);
DisplaySMG_Bit(6,SMG_duanma[t_005s/10]);
DelaySMG(500);
DisplaySMG_Bit(5,SMG_duanma[16]);
DelaySMG(500);
DisplaySMG_Bit(4,SMG_duanma[t_s%10]);
DelaySMG(500);
DisplaySMG_Bit(3,SMG_duanma[t_s/10]);
DelaySMG(500);
DisplaySMG_Bit(2,SMG_duanma[16]);
DelaySMG(500);
DisplaySMG_Bit(1,SMG_duanma[t_m%10]);
DelaySMG(500);
DisplaySMG_Bit(0,SMG_duanma[t_m/10]);
DelaySMG(500);
}
//********定时器相关函数*********
void InitTimer0()
{
TMOD = 0x01;
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void ServiceTimer0() interrupt 1
{
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
t_005s++;
if(t_005s == 20)
{
t_s++;
t_005s = 0;
if(t_s == 60)
{
t_m++;
t_s = 0;
}
if(t_m == 99)
{
t_m = 0;
}
}
}
//*******************************
//按键去抖延时(uchar就够用)
void DelayK(uchar t)
{
while(t--);
}
//按键扫描函数
void ScanKeys()
{
if(S4 == 0) //秒表启动/暂停
{
DelayK(100);
if(S4 == 0)
{
TR0 = ~TR0;
while(S4 == 0)
{
DisplayTime();
}
}
}
if(S5 == 0) //秒表清零
{
DelayK(100);
if(S5 == 0)
{
t_m = 0;
t_s = 0;
t_005s = 0;
while(S5 == 0)
{
DisplayTime();
}
}
}
}
//初始化系统
void Initsys()
{
SelectHC138(5);
P0 = 0X00;//关闭蜂鸣器和继电器
SelectHC138(4);
P0 = 0XFF;//关闭LED
}
void main()
{
InitTimer0();
Initsys();
while(1)
{
DisplayTime();
ScanKeys();
}
}
四、一些建议
如果自己的变量很多,可以写在一张纸上
可以画流程图
函数取名
全局变量与局部变量
这个题目多练几遍
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理