提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文介绍一下蓝桥杯单片机数码管考点,以总结的角度去讲解,对底层不做过多介绍,对底层有疑问可以看底层讲解文章或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) ? 16 : 17;//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柳离风
学习交流群
总结
以上就是蓝桥杯单片机考过的所有数码管考点,一定要全部掌握,第十四届国赛中全部考到。