51单片机数码管显示60秒倒计时(C语言)
基于普中51单片机开发板,运用定时器/计数器0和1,实现60秒的倒计时和LED灯0.5s间隔闪烁
文章目录
- 51单片机数码管显示60秒倒计时(C语言)
- 前言
- 一、数码管动态扫描
- 二、中断、定时器/计数器
-
- 二、代码
- 1.MAIN
- 2.中断定时相关程序代码
- 3.数码管LED灯相关程序代码
- 4.相关H文件程序代码
- 总结
前言
本程序涉及中断,定时器的配置,数码管动态扫描知识。程序基于模块化编写。程序里有详细的注解。
一、数码管动态扫描
数码管分为静态和动态两种显示方法。一般多位数码管选用动态显示。这样可以节约单片机的端口资源。但是需要外加数码管驱动电路。在此用的是138译码器。可以简称为38译码器,38译码器为三通道输入,八通道输出。通过3通道即可控制8位数码管。也就是说只用占用单片机的3个端口。
只用了解其真值即可 A为控制端 Y为数码管端。
数码管动态扫描的原理是利用人肉眼的视觉残留。在此需要说两个概念位选和段选。位选就是用来控制那个数码管显示的。段选是用来控制显示的内容的。在很短的时间内送出段码和控制未选来实现数码管的动态显示。
共阳数码管段码:
char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; 0~F
共阴数码管段码:
char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; 0~F
二、中断、定时器/计数器
中断、定时器/计数器。的难点就在于对各种相关寄存器。
定时器/计数器的相关寄存器,定时器/计数器的实质是加1计数器。可以对其选择是定时模式还是计数模式。
中断号格式,可以参照这个来。
中断号0 外部中断0中断号
中断号1 定时计数器0中断号
中断号2 外部中断1中断号
中断号3 定时计数器1中断号
中断号4 串行口中断序号
中断号5 定时计数器2中断号
有很多相关资料,我能力有限,对此我就不过多赘述了。程序里有详细的注解。
现象视频
下面是一个我上传到哔哩哔哩上十几秒的程序现象小视频 : https://b23.tv/IlFvwU
哔哩哔哩
程序文件
程序源文件:https://download.csdn.net/download/qq_54311788/19976902
程序文件
二、代码
1.MAIN
代码如下:
#include "hardware.h"
void main()
{
TMOD = 0X11;
TH0 = (65536-45872)/256;
TL0 = (65536-45872)%256;
TH1 = (65536-45872)/256;
TL1 = (65536-45872)%256;
EA = 1;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
while(1)
{
tube();
}
}
2.中断定时相关程序代码
代码如下:
#include "software.h"
uchar num , num1;
num2 = 60;
void delayms(uint xms)
{
uint a , b;
for(a=xms; a>0; a--)
for(b=110; b>0; b--);
}
void Timer0_Rountine(void) interrupt 1
{
TH0 = (65536-45872)/256;
TL0 = (65536-45872)%256;
num++;
if(num == 10)
{
num = 0;
LED =~ LED;
}
}
void TimerI_Routine(void) interrupt 3
{
TH1 = (65536-45872)/256;
TL1 = (65536-45872)%256;
num1++;
if(num1 == 20)
{
num1 = 0;
num2--;
if(num2 == 0)
num2 = 60;
}
}
3.数码管LED灯相关程序代码
代码如下:
#include "hardware.h"
#include "software.h"
uchar code block[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void tube()
{
uchar i;
for(i=0;i<2;i++)
{
switch(i)
{
case(0):
LSA=1;
LSB=1;
LSC=1;
P0 = block[num2/10];
break;
case(1):
LSA=0;
LSB=1;
LSC=1;
P0 = block[num2%10];
break;
}
delayms(5);
P0=0x00;
}
}
4.相关H文件程序代码
代码如下:
#ifndef __SOFTWARE_H__
#define __SOFTWARE_H__
#include <hardware.h> //包含此头文件,以便在此C文件中调用
extern void delayms(uint xms); // extern(外部的) 声明此函数给外部调用
extern num2; //声明此变量给外部函数调用
#endif
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
#include <reg51.h> //51单片机头文件
//#include <software.h>
//数码管 138译码器
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
//LED灯
sbit LED=P2^0;
typedef unsigned int uint; // typedef(类型定义) 用来给无符号整型类型数据 unsigned int 定义新名字 uint
typedef unsigned char uchar; //用来给无符号字符型类型数据 unsigned char 定义新名字 uchar
extern uint; //声明给外部函数使用
extern uchar; //声明给外部函数使用
extern void tube(void); // extern(外部的) 声明此函数给外部调用
#endif
以下是编译的结果:
Rebuild target ‘porject’
assembling STARTUP.A51…
compiling main.c…
compiling hardware.c…
compiling software.c…
linking…
Program Size: data=14.0 xdata=0 code=529
creating hex file from “.\Objects\porject”…
“.\Objects\porject” - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:01
提示:模块化编程很重要,如果有不了解的小伙伴推荐大家去看这篇文章写得很好:https://blog.csdn.net/weixin_30764137/article/details/96185151
keil5 的模块化编程详解
总结
首先我也是一个单片机入门的小白,编写文章不易。如果我的文章对大家有所帮助,我感到很开心。其次有很多的不足之处,希望大家多多包涵。另外,如果大家有什么好的意见,欢迎大家留言讨论。一起共同进步!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)