单元训练03:共阳数码管的静态显示

蓝桥杯

小蜜蜂

#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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值