51单片机数码管显示60秒倒计时(C语言)
2021/7/2 6:24:33
本文主要是介绍51单片机数码管显示60秒倒计时(C语言),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
51单片机数码管显示60秒倒计时(C语言)
基于普中51单片机开发板,运用定时器/计数器0和1,实现60秒的倒计时和LED灯0.5s间隔闪烁
文章目录
- 51单片机数码管显示60秒倒计时(C语言)
- 前言
- 一、数码管动态扫描
- 二、中断、定时器/计数器
- 现象视频
- 二、代码
- 1.MAIN
- 2.中断定时相关程序代码
- 3.数码管LED灯相关程序代码
- 4.相关H文件程序代码
- 总结
前言
本程序涉及中断,定时器的配置,数码管动态扫描知识。程序基于模块化编写。程序里有详细的注解。
一、数码管动态扫描
数码管分为静态和动态两种显示方法一般多为数码管选用动态显示,这样可以节约单片机的端口资源。但是需要外加数码管驱动电路。在此用的是138译码器。可以简称为3 8译码器,三通道输入,八通道输出。通过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
代码如下:
/***** "hardware.h"自创的头文件、hardware翻译为:五金器具; 计算机硬件; 武器装备; “”用于自己创建的头文件、<>反之 例:<reg51.h> ******/ #include "hardware.h" //此头文件已包含了<reg51.h>头文件 void main() { TMOD = 0X11; //设置定时器1和定时器0为工作方式1,16位定时器/计数器 /**** 0X11>0001 0001 0X11 设置的全部内容为:设置定时器/计数器的启动停止只由寄存器TRX(X=0或1)控制 >>> TRX为定时器X运行控制位 设置定时器/计数器为定时器模式 设置定时器0和定时器1为工作方式1,16位定时器/计数器 *****/ TH0 = (65536-45872)/256; //装初值,11.0592M晶振,定时50ms,计数个数 N = 45872(在计数时需要预先填装初始计数个数) TL0 = (65536-45872)%256; //... TH1 = (65536-45872)/256; //... TL1 = (65536-45872)%256; //同上 /***** THX、TLX为高八位和低八位寄存器。用来储存计数次数 X=0或1 计数个数 N = 中断时间 / 机器周期 机器周期 = 12 * (1/时钟频率) 例 ;时钟频率为11.0592MHz 机器周期 = 12 * (1/110592) = 1.09 us (约) 计数个数 N = 50 * 1000 / 1.09 = 45872 (约)<需要换算单位 * 1000> 1秒=1000毫秒(ms) 1秒=1,000,000 微秒(μs) 1毫秒=1000微秒 ******/ EA = 1; //全局中断允许位 | 打开总中断(相当于中断的总开关,打开之后其他中断发生时才能有效) ET0 = 1;//定时器/计数器0中断允许位 | 打开 ET1 = 1;//定时器/计数器1中断允许位 | 打开 TR0 = 1;//定时器0运行控制位 | 允许定时器0运行 TR1 = 1;//定时器1运行控制位 | 允许定时器1运行 while(1) //主循环 不断对数码管服务函数扫描 { tube();//数码管服务函数(不断对数码管进行扫描) } }
2.中断定时相关程序代码
代码如下:
/***** "software.h"自创的头文件、software.h翻译为:(计算机)软件; ******/ #include "software.h" uchar num , num1; //定义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 //中断号 定时器/计数器0中断 1为定时器/计数器0的中断号(重要) { TH0 = (65536-45872)/256; //方式1需要重装初值 TL0 = (65536-45872)%256; num++; //mun变量自加1 if(num == 10) //判断定时时间是否等于0.5s 为真之后 LED灯的电平状态转换 { num = 0; //清零,好判断下次计时 LED =~ LED;//电平状态取反 } } void TimerI_Routine(void) interrupt 3 //中断号 定时器/计数器1中断 1为定时器/计数器0的中断号 (重要) { TH1 = (65536-45872)/256; //方式1需要重装初值 TL1 = (65536-45872)%256; num1++; //mun1变量自加1 if(num1 == 20) //判断定时时间是否等于1s { num1 = 0; //清零,好判断下次计时 num2--; //mun2变量自减1 mun2的初始值为60 if(num2 == 0) //判断是否计时结束 num2 = 60; //重新赋值,以便重新计时 } }
3.数码管LED灯相关程序代码
代码如下:
/***** "hardware.h"自创的头文件、hardware翻译为:五金器具; 计算机硬件; 武器装备; “”用于自己创建的头文件、<>反之 例:<reg51.h> ******/ #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; //定义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; } // P0 = block[num%10]; 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 的模块化编程详解
总结
首先我也是一个单片机入门的小白,编写文章不易。如果我的文章对大家有所帮助,我感到很开心。其次有很多的不足之处,希望大家多多包涵。另外,如果大家有什么好的意见,欢迎大家留言讨论。一起共同进步!
这篇关于51单片机数码管显示60秒倒计时(C语言)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26小白家庭 nas 搭建方案-icode9专业技术文章分享
- 2024-06-23AI大模型企业应用实战(14)-langchain的Embedding
- 2024-06-23AI大模型企业应用实战(15)-langchain核心组件
- 2024-06-23AI大模型企业应用实战(16)-langchain核心组件
- 2024-06-23AI 大模型企业应用实战(06)-初识LangChain
- 2024-06-19EntBot.ai: AI Website Chatbot for Product Guides and Development Doc
- 2024-06-17zero-shot-learning-definition-examples-comparison
- 2024-06-06Package Easy(基于 NSIS 的打包exe安装包工具)使用方法-icode9专业技术文章分享
- 2024-06-06基于 casdoor 的 ELK 开源登录认证解决方案: elk-auth-casdoor-icode9专业技术文章分享
- 2024-05-29Elasticsearch慢查询日志配置