蓝桥杯单片机数码管(考点总结)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文介绍一下蓝桥杯单片机数码管考点,以总结的角度去讲解,对底层不做过多介绍,对底层有疑问可以看底层讲解文章或b站up柳离风视频。


提示:以下是本篇文章正文内容,下面案例可供参考

一、数码管控制代码

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

这些都是之前讲过的数码管底层代码

二、考点

1.显示数字

以num = 1234为例:

SMG[4] = num/1000;
SMG[5] = num/100%10;
SMG[6] = num/10%10;
SMG[7] = num%10;

2.显示小数点

以显示adc采样电压,保留两位小数为例:

uint adc;
adc = (PCF8591_read(0x03)/51.0)*100;//因为定义的类型时unsigned int类型,保存不了小数,需要放大100倍
SMG[5] = adc/100%10;
SMG[6] = adc/10%10;
SMG[7] = adc%10;
dot[5] = 1;

3.显示特殊字符

最近几年比赛会提供A-F断码,需要自己写的断码有:-、P、n、H、U、L等,以P为例:
开发板上数码管为共阳极数码管,io口给低电平会点亮
在这里插入图片描述
写成二进制就是10001100;对应十六进制0x8c

4.多界面

以:
在这里插入图片描述

多界面需要定义显示状态码,根据题目分为三个主界面,其中一个主界面分为三个子界面
所以定义一个state_display1,定义一个state_display2 

5.数码管闪烁

有两种写法:1、用DS1302的秒控制(只能以秒为单位闪烁、并且题目使用了DS1302,否则0分),2、用定时器中断产生标志位:

//DS1302写法为例
SMG[0] = Time[2]/16;
SMG[1] = Time[2]%16;
SMG[2] = (Time[0]%2) ? 17 :16;//16为-的索引、17为熄灭索引
SMG[3] = Time[1]/16;
SMG[4] = Time[1]%16;
SMG[5] = (Time[0]%2) ? 17 :16;//16为-的索引、17为熄灭索引
SMG[6] = Time[0]/16;
SMG[7] = Time[0]%16;
//定时器中断标志为例
void timer1()  interrupt 3
{
	if(++count_1000ms == 1000)
	{
		count_1000ms = 0;
		flag_flash ^= 1;
	}
 	systick_ms++;
	key_dly++;
 	display_dly++;
    collect_dly++;
	smg(SMG,dot,pos);
	led(LED,pos);
	if(++pos == 8) pos = 0;
}
SMG[0] = Time[2]/16;
SMG[1] = Time[2]%16;
SMG[2] = (flag_flash) ? 17 :16;//16为-的索引、17为熄灭索引
SMG[3] = Time[1]/16;
SMG[4] = Time[1]%16;
SMG[5] = (flag_flash) ? 17 :16;//16为-的索引、17为熄灭索引
SMG[6] = Time[0]/16;
SMG[7] = Time[0]%16;

6.高位熄灭

以频率测量为例:

SMG[0] = 17;
SMG[1] = 17;
SMG[2] = 17;
SMG[3] = (fre < 10000) ? 17 :fre/10000;
SMG[4] = (fre < 1000) ? 17 :fre/1000%10;
SMG[5] = (fre < 100) ? 17 :fre/100%10;
SMG[6] = (fre < 10) ? 17 :fre/10%10;
SMG[7] = fre%10;

7.负数显示

以第十四届国赛为例:
在这里插入图片描述

char par = -100;//因为题目同时考到了负数显示及高位熄灭,只能按正负分类讨论,否则嵌套逻辑太复杂
if(par >= 0)//大于0需要高位熄灭
{
	SMG[5] = (par < 100) ? 17 : par/100;
	SMG[6] = (par < 10) ? 17 : par/10%10;
	SMG[7] = par%10;
}
else if(par < 0)
{
	SMG[5] = (par < -10) ? 1617;//17为熄灭索引,16为-索引
	SMG[6] = (par > -10) ? 16 : (-par)/10;
	SMG[7] =  (-par)%10;
}

8.单位切换

以第十三届国赛为例:
在这里插入图片描述

//假设频率 为245HZ那么切换后为0.2KHZ,切换后发现数码管带小数的这位高位不熄灭
unsigned long fre;   //显示六位,已经大于65535了,不能用uint
unsigned long fre_khz
if(mode_fre)//单位HZ
{
	SMG[0] = 15; //F 
	SMG[1] = 17;
	SMG[2] = (fre < 100000) ? 17 :fre/100000;
	SMG[3] = (fre < 10000) ? 17 :fre/10000%10;
	SMG[4] = (fre < 1000) ? 17 :fre/1000%10;
	SMG[5] = (fre < 100) ? 17 :fre/100%10;
	SMG[6] = (fre < 10) ? 17 :fre/10%10;
	SMG[7] = fre%10;
	dot[6] = 0;
}
else//单位KHZ
{
	fre_khz = (fre/1000.0)*10;//保留几位小数就×10的几次方
	SMG[0] = 15; //F 
	SMG[1] = 17;
	SMG[2] = (fre_khz < 100000) ? 17 :fre/100000;
	SMG[3] = (fre_khz < 10000) ? 17 :fre/10000%10;
	SMG[4] = (fre_khz < 1000) ? 17 :fre/1000%10;
	SMG[5] = (fre_khz < 100) ? 17 :fre/100%10;
	SMG[6] = fre_khz/10%10;  //高位不熄灭
	SMG[7] = fre_khz%10;
	dot[6] = 1;
}

在这里插入图片描述

简单分析一下会发现单位为m时只是最高位多了个0,并且小数点位置不变,所以单位为m时高位不熄灭

uchar distance;
if(mode_distance)//单位cm
{
	SMG[0] = 10; //A 
	SMG[1] = 17;
	SMG[2] = 17;
	SMG[3] = 17;
	SMG[4] = 17;
	SMG[5] = (distance < 100) ? 17 :distance/100;
	SMG[6] = (distance < 10) ? 17 :distance/10%10;
	SMG[7] = distance%10;
	dot[5] = 0;
}
else//单位m
{
	SMG[0] = 10; //A 
	SMG[1] = 17;
	SMG[2] = 17;
	SMG[3] = 17;
	SMG[4] = 17;
	SMG[5] = distance/100;//带小数点高位不熄灭
	SMG[6] = distance/10%10;
	SMG[7] = distance%10;
	dot[5] = 1;
}

十二届省赛第二场
在这里插入图片描述

unsigned long fre; //七位已经大于65535了,不能用uint
unsigned long T;
if(mode_fre)//显示频率
{
	SMG[0] = 15; //F 
	SMG[1] = (fre < 1000000) ? 17 :fre/1000000;;
	SMG[2] = (fre < 100000) ? 17 :fre/100000%10;
	SMG[3] = (fre < 10000) ? 17 :fre/10000%10;
	SMG[4] = (fre < 1000) ? 17 :fre/1000%10;
	SMG[5] = (fre < 100) ? 17 :fre/100%10;
	SMG[6] = (fre < 10) ? 17 :fre/10%10;
	SMG[7] = fre%10;
}
else//显示周期 T= 1/F,注意单位是us;要×10的6次
{
	T=(1.0/fre) *1000000;//因为要保留小数所以1要变成1.0
	SMG[0] = 18; //n
	SMG[1] = (T < 1000000) ? 17 :T/1000000;;
	SMG[2] = (T < 100000) ? 17 :T/100000%10;
	SMG[3] = (T < 10000) ? 17 :T/10000%10;
	SMG[4] = (T < 1000) ? 17 :T/1000%10;
	SMG[5] = (T < 100) ? 17 :T/100%10;
	SMG[6] = (T < 10) ? 17 :T/10%10;
	SMG[7] = T%10;
}

更多资料关注b站up柳离风
学习交流群
在这里插入图片描述


总结

以上就是蓝桥杯单片机考过的所有数码管考点,一定要全部掌握,第十四届国赛中全部考到。

  • 21
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
这里提供一份蓝桥杯单片机数码管定时器动态扫描的参考代码,供大家参考。 ```c #include <reg51.h> //头文件 // 数码管位选信号 unsigned char code LED_W[] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}; // 数码管段选信号 unsigned char code LED_D[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71 }; // 定时器中断服务函数 void Timer0_ISR() interrupt 1 { static unsigned char count = 0; // 计数器 static unsigned char index = 0; // 位选信号索引,表示当前显示的是哪一位数码管 count++; // 计数器加1 if (count >= 100) { // 计数器达到100时,表示100ms已经过去了 count = 0; // 计数器清零 P0 = LED_W[index]; // 先将位选信号输出到P0口 P2 = LED_D[index]; // 再将对应的段选信号输出到P2口 index = (index + 1) % 8; // 索引加1,循环显示8个数码管 } } void main() { TMOD = 0x01; // 定时器0工作在模式1,16位定时器 TH0 = 0xFC; // 定时器初值,定时1ms TL0 = 0x66; ET0 = 1; // 允许定时器0中断 EA = 1; // 允许总中断 TR0 = 1; // 启动定时器0 while(1); // 主函数空循环,等待中断触发 } ``` 该代码中,通过定时器0产生1ms的中断,然后在中断服务函数中动态扫描8个数码管。其中,`LED_W`为数码管的位选信号,`LED_D`为数码管的段选信号。在每次中断服务函数中,先输出位选信号,再输出对应的段选信号,就可以实现数码管的动态扫描了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳离风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值