蓝桥杯单片机(三)——动态数码管显示

单片机开发板要实现动态数码管的显示首先是要判断数码管是共阴极还是共阳极,共阴极数码管字段为低电平时,点亮;共阳极数码管字段为高电平时,点亮。本开发板所使用的数码管是共阴极数码管。
在这里插入图片描述
共有八个数码管,八个数码管采用2个74HC573锁存器对单片机P0口的输出信号进行锁存,并增强信号驱动能力进而驱动8个数码管,其中U7的锁存输入Y7C是段选,U8的锁存输入Y6C是位选。
每个数码管共有8个字段:dp g f e d c b a, 控制数码管的显示实际上就是控制数码管字段的高低电平显示,通过控制字段的发光来表示字符。这是共阴极数码管,比如:要使数码管显示为0,则数码管段表示为:1100 0000 ,十六进制为0xc0,要表示其他数字亦然。
因为这是用两个锁存器来控制的,在段选之前,我们要先通过U8锁存器进行位选,也就是选择对应的几号数码管亮起,当然,如果需要全部亮起,只需要把延时时间变短即可(只是肉眼看不出来的频率)。
位选是通过锁存器把需要用到的某一个数码管打开,也就是在74HC573上将P0口的某一个引脚的电位拉高,输入高电平信号1。

P2 = P2 & 0x1f | 0xc0;//打开锁存器U8
P0 = 0x01;//打开com1

位选完成之后开始进行段选:

P2 = P2 & 0x1f | 0xe0;//打开锁存器U7
P0 = 0xc0;//第一个数码管显示0

要想实现数码管的动态显示,可以先将要显示的字符的二进制码放入一个数组里面,通过循环和延时程序来实现动态操作。

#include "STC15F2K60S2.h"
#include "intrins.h"

typedef unsigned int u16;
typedef unsigned char u8;

u8 code smgduan[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};//段选
u8 code com[8]={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};//位选
void Cls_P()
{
	P2 = P2 & 0x1f | 0xa0; P0 = 0x00; // 1010 0000 打开锁存器Y5C, 关闭蜂鸣器
	P2 = P2 & 0x1f | 0x80; P0 = 0xff; // 1000 0000 打开锁存器Y4C, 关闭LED
	
}

//延时函数,最小为1ms
void Delay(u16 num)
{
	u16 i;
	while(num--){
		for(i=0; i<628; i++);
	}
}
//LED流水灯
void Display_Led()
{
	u16 i;
	P2 = 0x80;
	P0 = 0xfe;
	Delay(100);
	while(1){
		for(i=0; i<7; i++)
		{
			P0 = _crol_(P0, 1);//移位,循环左移
			Delay(500);
		}
		for(i=0; i<7; i++)
		{
			P0 = _cror_(P0, 1);//循环右移
			Delay(500);
		}
		break;
	}
}

//数码管
void ShuMaGuang()
{
	u16 i,j;
	u16 num;
	//for(j=0; j<8; j++)
	while(num<8)
	{
		P2 = P2 & 0x1f | 0xc0;
		P0 = com[num];
	
		
		P2 = P2 & 0x1f | 0xe0;
		for(i=0; i<16; i++)
		{
			P0 = smgduan[i];
			Delay(500);
		}
		num++;
	}
}

void main()
{
	Cls_P();//关闭外设
	Display_Led();//流水灯
	ShuMaGuang(); //动态数码管
}

这个程序是使动态数码管从第一个开始显示0~F,显示完成后跳到第二个数码管从0开始显示,直到显示到最后一个数码管。

### 蓝桥杯单片机定时器动态数码管驱动实现方法 在蓝桥杯比赛中,使用单片机通过定时器实现动态数码管显示是一种常见的技术需求。以下是基于提供的参考资料和专业知识整理的内容。 #### 初始化配置 为了使数码管能够正常工作并配合定时器完成动态扫描显示,通常需要先进行硬件接口初始化操作。例如,在引用中的 `init` 函数中可以看到对多个端口的设置: ```c void init(void) { Timer0Init(); // 定时器初始化 [^1] HC138(4); P0 = 0xFF; // 设置特定通道状态 HC138(5); P0 = 0x00; HC138(6); P0 = 0xFF; HC138(7); P0 = 0xFF; } ``` 上述代码片段展示了如何利用多路选择芯片(如HC138)控制不同设备的状态,并确保初始状态下所有外设处于默认模式。 #### 定时器中断机制 动态数码管显示依赖于快速切换各个位选信号的同时更新对应的段码数据。这种高频率的操作可以通过设定合适的定时器溢出周期来触发中断服务例程 (ISR),从而减少主循环负担并提高效率。 系统级初始化部分可以参考以下示例代码: ```c void systeminitial() { TimeInit(); // 定时器中断初始化 [^2] HC138(5); P0 = 0x00; // 关闭蜂鸣器、继电器及其他外围器件 HC138(4); P0 = 0xFF; HC138(6); P0 = 0xFF; HC138(7); P0 = 0xFF; } ``` 这里调用了 `TimeInit()` 方法用于启动定时器及其关联的中断源。另外需要注意的是,某些情况下可能还需要额外启用全局中断标志位以便响应外部事件请求。 #### 中断处理逻辑设计 当发生定时器超时时会进入相应的 ISR 进行进一步的数据刷新动作。下面给出了一种简单的实现思路: ```c unsigned char disp_data[] = {0xC0, 0xF9, 0xA4, 0xB0}; // 假定四位数码管待显数值分别为'1','2','3' unsigned char current_digit = 0; void timer_ISR(void) interrupt 1 using 0 { static unsigned char digit_index = 0; switch(digit_index){ case 0: HC138(4); break; case 1: HC138(5); break; case 2: HC138(6); break; case 3: HC138(7); break; } P0 = disp_data[digit_index]; // 输出对应字形编码 digit_index++; if(digit_index >= sizeof(disp_data)/sizeof(unsigned char)){ digit_index = 0; } TH0 = RELOAD_VALUE_HIGH; TL0 = RELOAD_VALUE_LOW; // 重载计数初值以维持固定延时长度 } ``` 此段伪代码描述了一个典型的轮询过程——依次点亮每一个单独的位置并通过改变其连接引脚上的电平高低达到视觉暂留效应的目的[^3]。同时为了避免出现所谓的“鬼影”现象,则需精确调整每一轮次之间的时间间隔以及合理安排各子任务之间的优先顺序关系[^4]。 #### 注意事项 - **抗干扰措施**:由于实际运行环境中可能存在噪声等因素影响最终呈现效果,因此建议适当增加滤波电路或者软件去抖动算法。 - **功耗考量**:考虑到电池供电场景下的续航能力问题,应尽量降低不必要的能耗开销比如缩短亮灭转换周期等策略均可有效延长使用寿命。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值