#include "reg52.h"
#include "intrins.h"
unsigned char LedChar[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳极数码管从0到9的真值
unsigned char LedBuff[] = {0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //数码管显示缓冲区,初值0xFF确保启动时都不亮
unsigned char flags = 1; //1秒定时标志
unsigned char sec = 0;
unsigned char minutes = 0;
unsigned char hours = 0;
unsigned char days = 0; //定义记录秒,分,时,天的变量
unsigned char value = 0x80;
sfr AUXR=0X8E; //NOTES:sbit是位操作,用于将某个sfr中具体位赋值给一个变量
void TimeInit(); //定时器中断初始化函数
void HC138(unsigned char channel); //138译码器通道选择函数
void ShowSMG_Bit(unsigned char date,unsigned char pos); //数码管显示函数
void systeminitial();
void count_Buff();
sbit LED = P0^0;
void main()
{
value = ~value;
P0 = value;
systeminitial();
while(1)
{
}
}
void systeminitial()
{
HC138(5);P0=0X00;HC138(0); //ULN2003A非门输出,关闭继电器、蜂鸣器
HC138(4);P0=0Xff;HC138(0); //P0口给高电平,8个LED小灯全部熄灭
HC138(6);P0=0X00;HC138(0);
HC138(7);P0=0Xff;HC138(0);
HC138(4);
value = ~value;
P0 = value;
HC138(0);
TimeInit(); //定时器中断初始化
count_Buff();
ShowSMG_Bit(LedBuff[0],7);
ShowSMG_Bit(LedBuff[1],6);
ShowSMG_Bit(LedBuff[2],5);
ShowSMG_Bit(LedBuff[3],4);
ShowSMG_Bit(LedBuff[4],3);
ShowSMG_Bit(LedBuff[5],2);
ShowSMG_Bit(LedBuff[6],1);
ShowSMG_Bit(LedBuff[7],0);
}
void TimeInit() //定时器定时设置为1毫秒,每到1毫秒则进入定时器中断服务函数
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;
ET0 = 1;
}
void HC138(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 ShowSMG_Bit(unsigned char date,unsigned char pos)
{
HC138(6); //Y6模块工作,数码管进行位选
P0=0x01<<pos; //数码管的位选传到P0口
HC138(7); //Y7模块工作,数码管进行段选
P0=date; //当前数码管要显示数值对应的真值传到P0口
}
void InterruptTimer0() interrupt 1
{
static unsigned char i = 0; //动态扫描的索引
static unsigned int cnt = 0; //用来记录中断次数,设置的中断定时为1ms,中断1000次即一秒钟
cnt=cnt+1; //中断次数计数值加1
if(cnt == 125) //中断次数达到1000次即为1秒
{
cnt = 0; //清零,重新记录中断次数
flags = 1; //设置1秒定时标志位1
}
else
{
flags = 0; //设置1秒定时标志位1
}
HC138(6); //Y6模块工作,数码管进行位选
P0 = 0xff; //消隐
if(flags == 1) //判断1秒定时标志
{
value = _crol_(value,1); //_crol_(a,b)函数的作用是循环左移函数,a是要位移的目标数据,b是要位移的位数。
HC138(4);
P0 = ~value;
flags = 0; //标志位清零
sec++; //秒加1
if(sec == 60) //判断秒变量到达60秒
{
sec = 0; //清0零
minutes++; //分钟位加1
if(minutes == 60) //判断达到60分
{
minutes = 0; //清零
hours++; //小时位加1
if(hours == 24) //判断达到24小时
{
hours = 0; //清零
days++; //天数加1
}
}
}
count_Buff();
}
switch(i) //根据动态索引i的值进行位选,依次点亮八个数码管
{ //最右边一位数码管(com8)对应P0^7口
case 0 :i++;ShowSMG_Bit(LedBuff[0],7);break;
case 1 :i++;ShowSMG_Bit(LedBuff[1],6);break;
case 2 :i++;ShowSMG_Bit(LedBuff[2],5);break;
case 3 :i++;ShowSMG_Bit(LedBuff[3],4);break;
case 4 :i++;ShowSMG_Bit(LedBuff[4],3);break;
case 5 :i++;ShowSMG_Bit(LedBuff[5],2);break;
case 6 :i++;ShowSMG_Bit(LedBuff[6],1);break;
case 7 :i=0;ShowSMG_Bit(LedBuff[7],0);break;
default:break;
}
}
void count_Buff()
{
LedBuff[0]= LedChar[sec%10]; //秒的低位
LedBuff[1]= LedChar[(sec/10)%10]; //秒的高位
LedBuff[2]= LedChar[minutes%10]; //分钟的低位
LedBuff[3]= LedChar[(minutes/10)%10]; //分钟的高位
LedBuff[4]= LedChar[hours%10]; //小时的低位
LedBuff[5]= LedChar[(hours/10)%10]; //小时的高位
LedBuff[6]= LedChar[days%10]; //天数的低位
LedBuff[7]= LedChar[(days/10)%10]; //天数的高位
}
蓝桥杯开发板数码管定时+8个LED小灯循环左移
于 2023-05-12 16:53:07 首次发布