基于蓝桥杯的单片机模块练习——数码管动态显示
功能概述
数码管动态显示。显示格式为2021–0X。X为1到12,以一定间隔流转。
C代码
#include "reg52.h"
unsigned char code SMG_duanma[] = {0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e,
0xbf,0x7f
};
void Delay(unsigned int t)
{
while(t--);
//while(t--);
} //不推荐此延时方式,既不灵活,也容易出现BUG,具体原因见Debug总结。
void SelectHC573(unsigned char channel)
{
switch(channel)
{
case 0 : P2 = (P2 & 0X1F) | 0X00;break;
case 4 : P2 = (P2 & 0X1F) | 0X80;break;
case 5 : P2 = (P2 & 0X1F) | 0Xa0;break;
case 6 : P2 = (P2 & 0X1F) | 0Xc0;break;
case 7 : P2 = (P2 & 0X1F) | 0Xe0;break;
}
}
void InitSystem()
{
SelectHC573(5);
P0 = 0x00;
SelectHC573(0);
P0 = 0xFF;
}
// 函数:某一指定数码管显示某一字符
void DispalySMG_Bit(unsigned char pos, unsigned char num)
{
/**********消隐效果最佳******************/
SelectHC573(7);
P0 = 0xff;//消隐操作;在打开位选前关闭所有段选,防止P0口以前存在的数值被显示到数码管中,而影响我们原本想要显示的字符。
SelectHC573(6);
P0 = 0x01 << pos;
SelectHC573(0);
P0 = 0xff; //在位选锁存后,要把P0口全部置1,防止位选代码影响到接下来的段选代码,这样会造成显示效果不佳。
SelectHC573(7);
P0 = SMG_duanma[num];
/**********消隐效果最佳******************/
}
unsigned char month = 1;
void SMG_Dynamic()
{
DispalySMG_Bit(0,2);
Delay(250);//数码管的动态刷新时间,如果太短,则会造成数码管亮度过低,如果太长,会造成闪烁明显。经验值大概是1ms左右。
DispalySMG_Bit(1,0);
Delay(250);
DispalySMG_Bit(2,2);
Delay(250);
DispalySMG_Bit(3,1);
Delay(250);
DispalySMG_Bit(4,16);
Delay(250);
DispalySMG_Bit(5,16);
Delay(250);
DispalySMG_Bit(6,month/10);
Delay(250);
DispalySMG_Bit(7,month%10);
Delay(250);//整个一轮的刷新总时间尽可能不超过10ms
}
void main()
{
unsigned int n = 600;
InitSystem();
while(1)
{
//unsigned int n = 600;
SMG_Dynamic();
if(month > 12)
{
month = 1;
}
while(n--)
{
SMG_Dynamic();//从2之后,月份146s显示一次。
} //因为,n减到0之后变为65535,而每一个循环里面又有250*8个指令,合起来共有
month++; //65535*250*8个指令,而900个大约需要1ms。
}
}
知识点总结
Debug 总结:
unsigned int型的变量减到0之后,再往下减就变成0xffff了,而unsigned char型变量减到0之后,再往下减就变成了255(0xff).
这涉及到补码的知识。