蓝桥杯
小蜜蜂
#include "stc15f2k60s2.h"
// 段选
#define COM(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xc0; \
P2 &= 0x1F; \
}
// 位选
#define SEG(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xE0; \
P2 &= 0x1F; \
}
typedef unsigned char u8; // 自定义类型
u8 TimerCounter = 0; // 时间计数
u8 TimerHalfOneSecond = 0; // 0.5s标识
u8 PortEnabled; // 选中的位选端口
u8 NumDisplayed; // 要显示的数字
u8 segStatus; // 数码管状态机
// 共阳
code unsigned char Seg_Table[] =
{
0xc0, // 0
0xf9, // 1
0xa4, // 2
0xb0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xf8, // 7
0x80, // 8
0x90, // 9
0x88, // A
0x83, // b
0xc6, // C
0xa1, // d
0x86, // E
0x8e // F
}; // 表不用记,官方提供资源包里面有。
void Timer0_Init(void) // 5毫秒@12.000MHz
{
AUXR |= 0x80; // 定时器时钟1T模式
TMOD &= 0xF0; // 设置定时器模式
TL0 = 0xA0; // 设置定时初始值
TH0 = 0x15; // 设置定时初始值
TF0 = 0; // 清除TF0标志
TR0 = 1; // 定时器0开始计时
ET0 = 1; // 使能定时器0中断
EA = 1;
}
void OneSegDisplay(u8 ShowNum, u8 ShowPort) // 仅显示某个位选上的某个数字
{
SEG(Seg_Table[ShowNum]); // 数字通过数组下标直接调用
COM(ShowPort); // 开启位选端口
}
void InitSeg()
{
NumDisplayed = 0; // 显示数字从0开始
PortEnabled = 0x01; // 位选端口从最左边开始
segStatus = 0; // 状态机从0开始
}
void SegDisplay()
{
switch (segStatus)
{
case 0:
NumDisplayed = 0; // show num start from 0
PortEnabled = 0x01; // port start from left 1
segStatus = 1; // 初始状态配置完,进入状态1
break;
case 1:
OneSegDisplay(NumDisplayed, PortEnabled); // 从状态0 开始的初始数字及位选端口显示
NumDisplayed++; // 要显示的数字自增
if (NumDisplayed == 10) // 显示0—9,所以到10时截止
{
PortEnabled = PortEnabled << 1; // 位选端口左移
NumDisplayed = 0; // 显示数字归0
}
if (PortEnabled == 0x00) // 8个数码管从左到右全部调用完后
{
segStatus = 2; // 进入状态机2
}
break;
case 2: // 从这里开始是所有数码管一起同时显示0—F。
NumDisplayed = 0; // 显示数字从0开始
PortEnabled = 0xFF; // 8个位选全部打开
segStatus = 3; // 进入状态3
break;
case 3:
OneSegDisplay(NumDisplayed, PortEnabled); // 将状态2 配置的数字显示
NumDisplayed++; // 数字自增
if (NumDisplayed == 0x10) // 显示到F,所以下一个为0x10,即(F+1)
{
segStatus = 0; // 回到状态0
}
break;
default:
segStatus = 0; // 默认状态为0
break;
}
}
void main()
{
InitSeg();
Timer0_Init();
while (1)
{
if (TimerHalfOneSecond)
SegDisplay();
TimerHalfOneSecond = 0;
}
}
void Timer0_Isr(void) interrupt 1
{
if (TimerCounter++ == 100) // 0.5s
{
TimerHalfOneSecond = 1;
TimerCounter = 0;
}
}