蓝桥杯单片机基础模板一:动态数码管显示

news2024/11/17 5:41:37

蓝桥杯单片机有一些基础模块的写法,他是没有一定的公式模板的。

好比动态数码管扫描显示,原理就是快速地 传输段选和位选。

但因为电路上添加了74HC573芯片,导致了我们移植别处 51单片机的动态扫描代码

会出现诸多问题,比如闪烁,鬼影,甚至崩溃不显示了......

备赛14届省赛时,我花费数日不断调整程序结构,结合芯片速率,尝试各种

段选位选上的延时,最终调试出来了一个比较稳定可靠的数码管动态扫描函数。

此篇文章将围绕我调试出的 数码管动态扫描函数来进行讲解,欢迎大佬批评指正!

为使讲解更完善,我会循序渐进地从硬件底层开始分析,

如果急于想看代码,可以点目录进行传送:

目录

电路图与数码管动态扫描原理简要介绍:

定时器的配置与使用:

数码管显示函数的编写与介绍:

整体工程代码:

显示效果展示:


电路图与数码管动态扫描原理简要介绍:

 我们先看一位数码管是怎么点亮和操作的:

下图中有四位数码管,我们先只看最左边的就行了:

 我们看到,每一位数码管上八个段,每一个段都标有专属的a,b,c,d,e,f,g,dq.

(其中dq是右下角的小数点)

这八个字母分别对应着八根连在74hc573芯片上的线a,b,c,d,e,f,g,dq.

对应着的线打低电平(0)过去,就能使数码管对应段点亮了,

比如我想让数码管显示1,那只要让b和c亮,其余灭即可,端口读取的顺序是

dq g f e d c b a  所以对应段码为 1111 1001 ,转换为16进制数即为:0xf9

照这样,我们将0~9,甚至一些字母的显示段码推算出来,

就获得了常用字库,我们可以将其存在数组中:

此处贴出常用字库:

/*//数码管字库数组:
数组下标对应数字 字符段码速查:(PS:0~9数字和下标一致,0~9的下标 +20 就能加上小数点)
	0_0  1_1  2_2  3_3  4_4  5_5  6_6  7_7  8_8  9_9  10_a 
  11_b 12_c	13_d 14_e 15_f 16_空 17_根线 18_H 19_P 
	20_0. 21_1. 22_2. 23_3. 24_4. 25_5. 26_6. 27_7. 28_8. 29_9. 30_L 31_n
*/
u8 code smgZK[35]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xbf,0x89,0x8c,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xc7,0xc8};

我们开发板板载了四片74hc573芯片,都是读取的单片机端口P0的高低电平情况,

其中有俩片是与我们数码管有关的,一片用于段选,一片用于位选。

位选很容易理解,就是com1~com8,对应74hc573芯片的引脚打高电平就能使

当前被选中位的数码管按照之前传过来的段码进行显示

而该如何选择哪片74hc573芯片来锁存 P0端口数据呢?

我们查阅原理图:

 发现还有74hc138芯片(8选1)与或非门进行运算后,才能使能进行对应

Y6C_74hc573芯片 ,Y7C_74hc573芯片来锁存P0端口数据。

此处贴出74hc138使能74hc573芯片开启锁存函数:

//74HC138\74hc573芯片片选	函数
//传入一个参数,用来选择打开哪个74HC573锁存芯片									
void inint_port(u8 select)
{
	switch(select)
	{
		case 4:	P2=(P2&0X1F)|0X80;break;    //LED
		case 5:	P2=(P2&0X1F)|0XA0;break;	//蜂鸣器继电器
		case 6:	P2=(P2&0X1F)|0XC0;break;	//数码管位选
		case 7:	P2=(P2&0X1F)|0XE0;break;	//数码管段选
	}
}

 可见我们开发板P0端口的强大,可以给许多模块传输控制信号。

 从以上电路原理图可见,八位数码管连接着俩片74HC573芯片:

分别是a1~dq1 控制段选 的 Y7C_74HC573芯片 (a~g决定七段码显示,dq表示要不要加小数点)

以及com1~com8控制位选的 Y6C_74HC573芯片    

数码管的动态扫描就是一位一位传送对应 位选 和 段选码,比如我想让八位数码管

显示1,2,3,4,5,6,7,8,那我就得:

打开com1 关闭其余com2~com8,然后传送1的段码                    

打开com2,关闭其余com1,com3~com8,然后传送2的段码

打开com3,关闭其余com1,com2,com4~com8,然后传送3的段码

以此类推到com8 完成一整个动态扫描。

其运用的原理就是快速的一位一位地扫描,运用肉眼的视觉暂留,

造成每一位都在显示的假象,其实本质是一位一位亮过去的。

定时器的配置与使用:

定时器在蓝桥杯单片机中是十分重要的外设,这里简要介绍我们如何配置使用它

具体基础知识还是要大家自己努力学习才是!

我们可以用STC_ISP软件直接生成驱动定时器的代码:

这在比赛中也是提供此软件可以使用的:

以下示例   定时器0开启,12T模式 ,定时1ms的设置细节:

 但它写的不是完整的开启定时器0,所以还需添加俩句来打开定时器0的中断:

 这个函数就是用来初始化定时器0的,在主函数while(1)循环之外调用一次就行了。

其次就是中断服务函数的编写,函数名不重要,主要是对应中断号写正确就行了:

void TIMER0_serv() interrupt 1 
{

}

这样,定时器0每计时1ms,就会进入中断函数一次,来执行里面的语句.

这样我们就能 精准、实时、快速、稳定 地刷新数码管了!

数码管显示函数的编写与介绍:

这是本人省赛以来一直使用的数码管打印函数,直接放在定时器中断中调用的

1~15ms为周期的刷新都十分稳定,只是15ms会变暗,建议5~8ms为周期刷新最好

一次性打印8位数码管,传送完位选,段选后先延时,再P0=0Xff;进行消除鬼影

nr1~nr8,不是直接传送的段码,而是作为字库数组的下标使用的,因为段码都

存在数组中,而且有些数值的运算用段码非常不方便。

//数码管打印函数
//传入八个参数u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8 进行打印
//一次性打印八位数码管
void smg_display(u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8)
{
	u8 i;
	i=0;
	for(i=0;i<=8;i++)     //循环扫描1~8位的数码管
	{
		inint_port(6);    //每一位先开启位选
		switch(i)
	    {
		case 1:P0=0X01;inint_port(7);P0=smgZK[nr1];Delay250us();P0=0Xff;break;			
		case 2:P0=0X02;inint_port(7);P0=smgZK[nr2];Delay250us();P0=0Xff;break;
		case 3:P0=0X04;inint_port(7);P0=smgZK[nr3];Delay250us();P0=0Xff;break;
		case 4:P0=0X08;inint_port(7);P0=smgZK[nr4];Delay250us();P0=0Xff;break;
		case 5:P0=0X10;inint_port(7);P0=smgZK[nr5];Delay250us();P0=0Xff;break;
		case 6:P0=0X20;inint_port(7);P0=smgZK[nr6];Delay250us();P0=0Xff;break;		
		case 7:P0=0X40;inint_port(7);P0=smgZK[nr7];Delay250us();P0=0Xff;break;			
		case 8:P0=0X80;inint_port(7);P0=smgZK[nr8];Delay250us();P0=0Xff;break;
		}
	}
}

其中还调用了延时函数Delay250us();这也可用STC_ISP软件生成:

//@12.000MHz  数码管函数 必要的250us打印延时
//各类延时函数可在软件生成,不用记忆
void Delay250us()
{
	unsigned char i, j;
	i = 3;j = 232;
	do{while (--j);} while (--i);
}

整体工程代码:

 此工程为8ms一周期扫描数码管,动态扫描显示1~8;

#include "stc15f2k60s2.h"

typedef unsigned char u8;

//蜂鸣器引脚
sbit buzz=P0^6;

/*//数码管字库数组:
数组下标对应数字 字符段码速查:(PS:0~9数字和下标一致,0~9的下标 +20 就能加上小数点)
	0_0  1_1  2_2  3_3  4_4  5_5  6_6  7_7  8_8  9_9  10_a 
  11_b 12_c	13_d 14_e 15_f 16_空 17_根线 18_H 19_P 
	20_0. 21_1. 22_2. 23_3. 24_4. 25_5. 26_6. 27_7. 28_8. 29_9. 30_L 31_n
*/
u8 code smgZK[35]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xbf,0x89,0x8c,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xc7,0xc8};

u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8;//数码管八位打印内容,对应字库数组下标

void give_nr();
void inint_port(u8 select);
void Delay250us();
void smg_display(u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8);
void Timer0Init(void);


void main()
{
	
	inint_port(5);       //清除蜂鸣器
	buzz=0;
	inint_port(4);       //清除LED
	P0=0XFF;
	
	Timer0Init();
	
	while(1)
	{
		
		
	}
}

//为nr1~nr8赋值为1~8
void give_nr()
{
	nr1=1;nr2=2;nr3=3;nr4=4;
	nr5=5;nr6=6;nr7=7;nr8=8;
}

//74HC138\74hc573芯片片选	函数
//传入一个参数,用来选择打开哪个74HC573锁存芯片									
void inint_port(u8 select)
{
	switch(select)
	{
		case 4:	P2=(P2&0X1F)|0X80;break;  //LED
		case 5:	P2=(P2&0X1F)|0XA0;break;	//蜂鸣器继电器
		case 6:	P2=(P2&0X1F)|0XC0;break;	//数码管位选
		case 7:	P2=(P2&0X1F)|0XE0;break;	//数码管段选
	}
}

//@12.000MHz  数码管函数 必要的250us打印延时
//各类延时函数可在软件生成,不用记忆
void Delay250us()
{
	unsigned char i, j;
	i = 3;j = 232;
	do{while (--j);} while (--i);
}

//数码管打印函数
//传入八个参数u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8 进行打印
//一次性打印八位数码管
void smg_display(u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8)
{
	u8 i;
	i=0;
	for(i=0;i<=8;i++)
	{
			inint_port(6);
			switch(i)
			{
				case 1:P0=0X01;inint_port(7);P0=smgZK[nr1];Delay250us();P0=0Xff;break;			
				case 2:P0=0X02;inint_port(7);P0=smgZK[nr2];Delay250us();P0=0Xff;break;
				case 3:P0=0X04;inint_port(7);P0=smgZK[nr3];Delay250us();P0=0Xff;break;
				case 4:P0=0X08;inint_port(7);P0=smgZK[nr4];Delay250us();P0=0Xff;break;
				case 5:P0=0X10;inint_port(7);P0=smgZK[nr5];Delay250us();P0=0Xff;break;
				case 6:P0=0X20;inint_port(7);P0=smgZK[nr6];Delay250us();P0=0Xff;break;				
				case 7:P0=0X40;inint_port(7);P0=smgZK[nr7];Delay250us();P0=0Xff;break;			
				case 8:P0=0X80;inint_port(7);P0=smgZK[nr8];Delay250us();P0=0Xff;break;
			}
	}
}

//1毫秒@12.000MHz 定时器0 初始化函数
//此函数可在软件生成,别忘了添加 EA=1; ET0=1;这俩句
//此函数初始化定时器0为 1ms 中断一次,满足普遍要求
void Timer0Init(void)
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x18;		  //设置定时初始值
	TH0 = 0xFC;		  //设置定时初始值
	TF0 = 0;		    //清除TF0标志
	TR0 = 1;		    //定时器0开始计时
	
	EA=1;           //打开总中断
	ET0=1;					//打开定时器0中断
}


//定时器0中断服务函数
void TIMER0_serv() interrupt 1 
{
	u8 i;
	i++;
	if(i==8)
	{
		i=0;
		give_nr();
		smg_display(nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8);
	}
}

 

显示效果展示:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/604972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

期末学习总结模板

期末学习总结精选篇1 转眼间研究生的生活已经有一学期了&#xff0c;感觉才参加复试没多久&#xff0c;回头想想&#xff0c;这一年过的真快&#xff0c;因为生病&#xff0c;耽误了很多时间&#xff0c;收获太少&#xff0c;遗憾太多。 本学期的收获&#xff1a; 1、暑假里看了…

Elasticsearch文件存储

分析Elasticsearch Index文件是如何存储的&#xff1f; 主要是想看一下FST文件是以什么粒度创建的&#xff1f; 首先通过kibana找一个索引的shard&#xff0c;此处咱们就以logstash-2023.05.30索引为例 查看下shard分布情况 GET /_cat/shards/logstash-2023.05.30?vindex …

AtCoder Beginner Contest 303——A-E题讲解

蒟蒻来讲题&#xff0c;还望大家喜。若哪有问题&#xff0c;大家尽可提&#xff01; Hello, 大家好哇&#xff01;本初中生蒟蒻讲解一下AtCoder Beginner Contest 303这场比赛的A-E题&#xff01; A - Similar String 原题 Problem Statement Two characters x x x and y…

Python IDLE介绍

目录 IDE&#xff08;集成开发环境&#xff09;是什么 Python IDLE使用方法详解 Python IDLE常用快捷键 IDE&#xff08;集成开发环境&#xff09;是什么 IDE 是 Integrated Development Environment 的缩写&#xff0c;中文称为集成开发环境&#xff0c;用来表示辅助程序员…

一、Fuzzing速成之AFL实战

文章目录 一、Fuzzing基本知识1、什么是Fuzzing?2、Fuzzing运行流程 二、Fuzzing实战1、下载AFL压缩包2、安装AFL3、Fuzzing 一、Fuzzing基本知识 1、什么是Fuzzing? 维基百科将模糊测试定义为&#xff1a;     模糊测试 &#xff08;fuzz testing, fuzzing&#xff09;…

【Python 文本挖掘】零基础也能轻松掌握的学习路线与参考资料

Python文本挖掘是利用Python语言和相关文本挖掘工具对大量文本数据进行分析和挖掘的过程。Python在文本挖掘方面广泛应用于自然语言处理、情感分析、主题建模、关键词提取等领域。 学习Python文本挖掘需要掌握Python编程基础、数据分析和可视化、自然语言处理、机器学习等知识…

Flutter:功能型组件(3)- 拖拽组件、缩放平移组件

拖拽组件 拖拽组件包含 Draggable、LongPressDraggable 和 DragTarget。 Draggable、LongPressDraggable 为可拖拽的组件&#xff0c;LongPressDraggable 继承自Draggable&#xff0c;因此用法和 Draggable 完全一样&#xff0c;唯一的区别就是 LongPressDraggable 触发拖动的…

nginx添加nginx-sticky-module模块步骤

nginx-sticky-module模块是nginx实现负载均衡的一种方案,和ip_hash负载均衡算法会有区别的 ip_hash 根据客户端ip将请求分配到不同的服务器上.sticky 根据服务器个客户端的cookie,客户端再次请求是会带上此cookie,nginx会把有次cookie的请求转发到颁发cookie的服务器上. 安装…

AI工具合集!一共600+覆盖全行业,除了ChatGPT,那你也会喜欢这些其他的AI工具

如果你喜欢ChatGPT&#xff0c;那你也会喜欢这些其他的AI工具。 AI正在改变我们的工作方式&#xff0c;我不想错过充分利用它的机会&#xff0c;所以我尝试了一系列AI工具来节省时间&#xff0c;提高我的工作效率。 这里有个集合了600ai工具的合集包。 序号AI工具名称AI分类A…

I.MX RT1170加密启动详解(4):OTFAD XIP加密运行代码

本节将介绍基于AES加密的OTFAD引擎&#xff0c;它可以在不影响AES-128-CTR性能的情况下实时解密数据。OTFAD包括对AES密钥展开机制的完整硬件支持&#xff0c;它可以解密最多4个唯一的AES上下文。每个上下文都有一个用户定义的128位的Image Encryption Key(IEK)、一个64位的计数…

uniapp的movable-view、movable-area

uniapp的movable-view、movable-area movable-view&#xff1a; 可以在页面中拖拽滑动必须在movable-area组件中&#xff0c;并且必须是直接子节点必须设置width和height属性&#xff0c;不设置默认为10px提供特殊事件&#xff1a;htouchmove和vtouchmove movable-area&#xf…

用于ECharts的全国省市区县乡镇街道级的行政区划边界数据(GeoJSON格式)

https://map.vanbyte.com 提供了免费的省市县3级行政边界数据(GeoJSON格式)、省市县乡4级联动数据。 至于行政区划边界数据的来源&#xff0c;网络上有各种教程。授人以鱼不如授人以渔&#xff0c;下面记录一下各类方法的具体步骤。 来源1&#xff1a;阿里云的数据可视化平台…

听劝 不要盲目的学网络安全。

听劝 不要盲目的学网络安全。 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多 google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答. 4.遇到实在搞不懂的,可…

webpack-dev-server 不是内部或外部命令,也不是可运行的程序 或批处理文件

一、问题描述 webpack-dev-server 不是内部或外部命令,也不是可运行的程序 或批处理文件 出现上述问题 一般是node.js的版本不一致造成。 二、解决方法&#xff1a;换成低版本的node.js node.js换成12或11版本即可 2.1.先卸载高版本node.js 在控制面板中卸载node.js,并删除安…

【算法】常见的加密算法及实现

文章目录 前言1. 数字签名2. 加密和解密2.1. 加密2.2. 解密 3. 对称加密和非对称加密3.1. 对称加密3.2. 非对称加密 4. 常见的签名加密算法4.1. MD5算法4.2. SHA1算法4.3. HMAC算法4.4. AES/DES/3DES算法4.4.1. DES算法4.4.2. 3DES算法4.4.3. AES算法 4.5. RSA算法4.6. ECC算法…

hbase简介与安装

Hbase简介 HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统&#xff0c;利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。 HBase是Google Bigtable的开源实现&#xff0c;类似Google Bigtable利用GFS作为其文件存储系统&#xff0c;HBase利用Had…

安装Linux-SUSE操作系统

文章目录 一、安装Linux-SUSE系统1、环境准备2、SUSE 镜像的下载2.1、下载企业服务器2.2、ARM和桌面的ISO 3、安装SUSE4、配置本地 yum 源5、SUSE常用安装命令6、在 SUSE系统上安装mysql数据库步骤&#xff1a;7、破解SUSE系统root密码 一、安装Linux-SUSE系统 1、环境准备 操…

7月蓄势待发,2023上海内部物流展,预登记全面启动!

观众预登记通道现已全面开放 展会时间 2023年7月5日 9:00-17:00 2023年7月6日 9:00-17:00 2023年7月7日 9:00-15:00 展会地点 上海新国际博览中心&#xff08;浦东新区龙阳路2345号&#xff09; 同期展会 2023上海国际AGV机器人产业展 2023上海国际电商物流包装产业展 2…

外包干了4年,今天分手了...

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

gcc-g++使用编译链接理解

在讲gcc/g使用之前我们先讲一下背景&#xff0c;编译链接 编译链接我们之前讲过一次&#xff0c;但是这里在深入理解一下编译链接&#xff0c;以及我们看一下现象 编译链接 首先&#xff0c;编译链接可以分为四步&#xff1a; 1.预处理 2.编译 3.汇编 4.链接 预处理 我…