蓝桥杯单片机数码管放定时器中刷新

一、数码管为什么要放定时器中刷新?

数字管的显示需要周期性地进行刷新,以保证数字能够持续地显示在数码管上,并且刷新需要按照一定的时间间隔进行。为了实现周期性的刷新,需要使用定时器对刷新时间进行控制,定时器能够定时产生中断,中断时触发刷新操作,从而实现数字管的周期性刷新。同时,将刷新操作放在定时器中可以提高程序的实时性和精度,因为定时器的中断响应时间比较精确,可以提高数字管显示的稳定性和准确性。

二、使用步骤

首先我们将固定部分,像断码表,定时器初始化以及要定义的变量等写出,然后再在中断函数里面写入逻辑,程序还是比较简单,很容易理解。

#include <STC15F2K60S2.H>

code unsigned char Duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
//0123456789-
code unsigned char Duanmadot[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//0123456789(带小数点)

unsigned char Smgnum[8];     //定义一个数组接受段码表
unsigned char i_smg,count_smg;  //放定时器中刷新的轮询值,计数值
//定时器初始化这里我们直接在ISP中复制就可
void Timer1Init()		//100微秒@12.000MHz
{
	AUXR &= 0xBF;			//定时器时钟12T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x9C;				//设置定时初始值
	TH1 = 0xFF;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1=1;
	EA=1;
}
//这里锁存器我们进行先打开后关闭的过程,这样我们在给端口赋值后就不会影响其他地方了
void hc138(unsigned char n)   //锁存器选择
{
	switch(n)
	{
		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;
	}
	P2 = ( P2 & 0x1f ) | 0x00;
}
void SMGbit(unsigned char n,unsigned char m)   //数码管位选
{
	P0=0xff;hc138(7);
	P0=0x01<<n;hc138(6);
	P0=m;hc138(7);
}
//在这里可以定义一个函数对数码管接收到的值改变,然后将其放入while里面
void Smg_GetDuanma()
{
//2023-614
Smgnum[0]=Duanma[2];Smgnum[1]=Duanma[0];Smgnum[2]=Duanma[2];Smgnum[3]=Duanma[3];
Smgnum[4]=Duanma[10];Smgnum[5]=Duanma[6];Smgnum[6]=Duanma[1];Smgnum[7]=Duanma[4];
}

//然后就是中断服务函数
void T1Service() interrupt 3   //100us
{
	count_smg++;
	if(count_smg==20)    //一般每2ms刷新一次就够了
	{
		count_smg=0;
		SMGbit(i_smg,Smgnum[i_smg]);    //下面三行代码就是轮询的过程了
		i_smg++;
		if(i_smg==8) i_smg=0;
		P0=0xff;
	}
}

void main()
{
	Timer1Init();
	while(1)
	{
		Smg_GetDuanma();
	}
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了数码管放定时器中刷新的使用,采用传统的方法会有大量的延时以阻塞我们在while中不断循环,导致程序效率较低,同时数码管也会因为外设延时的影响导致数码管不亮,偏暗,或者数码管最后一位过亮等。采取放定时器中刷新的方法简单高效,稳定,建议大家都可以采用这种方法,定时器作为一个宝贵的资源我们一定要高效的利用起来。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
这里提供一份蓝桥杯单片机数码定时器动态扫描的参考代码,供大家参考。 ```c #include <reg51.h> //头文件 // 数码管位选信号 unsigned char code LED_W[] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}; // 数码管段选信号 unsigned char code LED_D[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71 }; // 定时器断服务函数 void Timer0_ISR() interrupt 1 { static unsigned char count = 0; // 计数器 static unsigned char index = 0; // 位选信号索引,表示当前显示的是哪一位数码管 count++; // 计数器加1 if (count >= 100) { // 计数器达到100时,表示100ms已经过去了 count = 0; // 计数器清零 P0 = LED_W[index]; // 先将位选信号输出到P0口 P2 = LED_D[index]; // 再将对应的段选信号输出到P2口 index = (index + 1) % 8; // 索引加1,循环显示8个数码管 } } void main() { TMOD = 0x01; // 定时器0工作在模式1,16位定时器 TH0 = 0xFC; // 定时器初值,定时1ms TL0 = 0x66; ET0 = 1; // 允许定时器0断 EA = 1; // 允许总断 TR0 = 1; // 启动定时器0 while(1); // 主函数空循环,等待断触发 } ``` 该代码,通过定时器0产生1ms的断,然后在断服务函数动态扫描8个数码管。其,`LED_W`为数码管的位选信号,`LED_D`为数码管的段选信号。在每次断服务函数,先输出位选信号,再输出对应的段选信号,就可以实现数码管的动态扫描了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值