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

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


前言

本文介绍一下蓝桥杯单片机数码管考点,以总结的角度去讲解,对底层不做过多介绍,对底层有疑问可以看底层讲解文章或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柳离风
学习交流群
在这里插入图片描述


总结

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

### 蓝桥杯数码管模板代码与解题思路 在蓝桥杯竞赛中,数码管的应用通常涉及硬件电路设计以及软件编程实现。以下是基于已知引用内容和专业知识整理的数码管相关代码模板及其解释。 #### 数码管工作原理概述 蓝桥杯使用的数码管为共阳极结构,其位选端用于指定点亮的是哪一个数码管,而段选端则决定具体显示的内容。为了使某个数码管上的特定数字亮起,需将该数码管的位选设置为高电平,同时将其对应的段选设为低电平[^1]。 --- #### 数码管驱动代码模板 以下是一个完整的数码管驱动程序模板: ```c #include <stc15f2k60s2.h> // 使用STC单片机头文件 #define uchar unsigned char // 定义数码管字模表 (对应0~9) uchar code tab[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; void delay() { int i, j; for (i = 0; i < 600; i++) // 延时函数 for (j = 0; j < 600; j++); } void display_digit(uchar digit) { P2 = 0xC0; // 设置位选信号,选择第一个数码管 DS1 P0 = ~tab[digit]; // 将字模取反后送至段选口(因共阳极) delay(); // 添加延时以便观察效果 P0 = 0xFF; // 清除段选数据 } ``` 上述代码实现了通过`display_digit()`函数动态更新数码管显示的功能。其中,`P2`负责控制位选信号,`P0`负责发送段选数据。由于采用共阳极数码管,因此需要对字模值进行按位取反处理后再输出到段选接口[^3]。 --- #### 主循环逻辑示例 如果希望让数码管从0到9依次滚动显示,则可以编写如下主函数: ```c void main() { uchar i; P2 = 0xA0; // 初始化操作:关闭继电器、蜂鸣器等外设 P0 = 0x00; P2 = 0x80; P0 = 0xFF; P2 = 0xC0; // 初始状态:选择数码管DS1的第一个位置 P0 = 0x01; P2 = 0xFF; P0 = 0xFF; while (1) { // 循环显示0~9 for (i = 0; i < 10; i++) { display_digit(i); } } } ``` 此部分代码展示了如何利用无限循环来不断刷新数码管显示内容,并调用了之前定义好的子函数完成具体的数值转换过程。 --- #### 注意事项 - **代码范围限制**:按照比赛规定,在实际提交作品时应严格遵循官方给出的框架格式,仅允许修改`Begin`和`End`之间的区域[^2]。 - **硬件连接确认**:确保开发板上各引脚连线无误,特别是对于共阳极型数码管而言,务必注意高低电平关系。 - **优化建议**:可以通过查表方式进一步简化编码复杂度;另外还可以引入中断机制提高效率并减少资源占用率。 --- ###
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柳离风

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

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

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

打赏作者

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

抵扣说明:

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

余额充值