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

news/2024/11/24 3:31:43/

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

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

但因为电路上添加了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;    //LEDcase 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);       //清除LEDP0=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;  //LEDcase 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.ppmy.cn/news/187362.html

相关文章

股票买卖篇(II,III,IV)--基础,详细!状态机简单应用

目录 股票买卖II 本题思路 关于异常值的解释 代码 股票买卖III 本题思路 (包括对交易过程的理解&#xff0c;需认真理解) 代码 股票买卖 IV 本题思路 代码 股票买卖II 输入样例 6 7 1 5 3 6 4 输出样例 7 输入样例 5 1 2 3 4 5 输出样例 4 本题思路 该题是最…

android+p+华为手机,小米之后 华为与荣耀多款手机开启Android P内测

原标题&#xff1a;小米之后 华为与荣耀多款手机开启Android P内测 集微网消息(文/罗明)昨天我们报道了在谷歌发布Android P正式版之后&#xff0c;国内手机厂商小米率先开启Android P的内测&#xff0c;目前已知的机型仅限小米MIX2S&#xff0c;同为竞争对手的华为自然不会无动…

一加6 android p测试,一加6更新Android P有什么新功能 目前仍有这些问题

8月7日&#xff0c;谷歌正式推送第九个Android大版本&#xff0c;也就是Android P&#xff0c;拥有全新的操作手势和界面。之前小米MIX 2S已经能升级到基于Android P的MIUI 10 8.8.7内测版&#xff0c;成为国内首款升级到Android P的手机。   8月14日深夜&#xff0c;一加官方…

一加6 android p测试,一加发布Android P公测版 一加手机6可升级

Android P正式版已经发布&#xff0c;国内手机厂商也开始了测试阶段&#xff0c;其中&#xff0c;一加手机今日公布消息&#xff0c;已经为旗下的一加手机6提供了Android P公测版升级。 【PChome手机频道资讯报道】Android P正式版已经发布&#xff0c;国内手机厂商也开始了测试…

小米6 android p是什么,小米6什么配置参数?小米6标配有什么?

小米6什么配置参数 小米6的配置参数是配备5.15英寸1080P显示屏&#xff0c;4搭载满血版的高通骁龙835处理器&#xff0c;以及配备6GB运行内存。此外&#xff0c;小米6跟进了双摄的设计&#xff0c;配备“广角长焦”的双摄像头。版本方面&#xff0c;小米6提供了三个版本&#x…

荣耀v8 android os,华为荣耀V8的手机系统是什么

华为荣耀V8的手机系统是什么 华为荣耀V8的手机系统是Android 6.0。 摄像头方面&#xff0c;华为荣耀V8前置800W像素自拍镜头&#xff0c;拥有F2.4光圈&#xff0c;后置两颗平行设计的1200W像素摄像头&#xff0c;一颗黑白一颗彩色&#xff0c;黑白镜头可以加强细节表现力&#…

题目:P5638 【CSGRound2】光骓者的荣耀

题目&#xff1a;【CSGRound2】光骓者的荣耀 - 洛谷 题目大意 用最少时间要将所有城市全部访问完&#xff0c;若有传送器可使用传送器。 坑点 1.需要考虑传送器数量与城市的数量 &#xff0c;若传送器大于城市输出0 2.需要考虑数据范围较大&#xff0c;long long int 数据范围…

华为荣耀20s云服务_荣耀20s参数

展开全部 荣耀211320pro参数&#xff1a; 1、屏幕规5261格&#xff1a;6&#xff0e;26英寸1080PLCD魅眼全面屏。4102 2、机身颜色&#xff1a;幻影1653蓝、幻夜黑、冰zhi岛白内、蓝水翡翠和容幻夜星河(dao四曲面3D玻璃机身)。 3、处理器&#xff1a;麒麟980处理器。 4、操作系…