蓝桥杯 模板Template Part6:数码管 定时器动态驱动

九层妖塔 起于垒土



改编自国信长天蓝桥杯官方蓝皮书例程,按照自己的习惯进行了补充和修改


数码管基础知识


一、流程图

在这里插入图片描述


二、基本模板

头文件

//-----------------------------SEG-------数码管------------------------------------//
extern uchar puc_SEG_Buf[9];   //数码管段码缓冲数组
extern uchar puc_SEG_Code[8];  //数码管段码
extern uchar uc_SEG_Position; //数码管位选
extern uint ui_SEG_flag;      //tim定时器,数码管扫描频率标志位

extern void SEG_Tran(uchar *puc_SEG_Buf,uchar *puc_SEG_Code);   //动态数码段码示转换
extern void SEG_Disp(uchar *puc_SEG_Code,uchar uc_SEG_Position); //动态数码管显示
extern void SEG_Proc(void);        //数码管处理函数

SEG.c

#include <STC15F2K60S2.h>
#include <stdio.h>
#include <intrins.h>

#include <main.h>

//------------------------------------数码管段码转换-------------------//
void SEG_Tran(uchar *puc_SEG_Buf,uchar *puc_SEG_Code)
{
	uchar i;
	uchar j=0;
	uchar temp;
	
	for(i=0;i<8;i++,j++)
	{
		switch(puc_SEG_Buf[j])
		{
			case '0': temp = 0xc0; break;
			case '1': temp = 0xf9; break;
			case '2': temp = 0xa4; break;
			case '3': temp = 0xb0; break;
			case '4': temp = 0x99; break;
			case '5': temp = 0x92; break;
			case '6': temp = 0x82; break;
			case '7': temp = 0xf8; break;
			case '8': temp = 0x80; break;
			case '9': temp = 0x90; break;   
			
			case 'A': temp = 0x88; break;
			case 'b': temp = 0x83; break;
			case 'C': temp = 0xC6; break;
			case 'd': temp = 0xA1; break;
			case 'E': temp = 0x86; break;
			case 'F': temp = 0x8E; break;
			case 'H': temp = 0x89; break;
			case 'L': temp = 0xC7; break;
			case 'N': temp = 0xC8; break;
			case 'P': temp = 0x8C; break; 
			case 'U': temp = 0xC1; break;
			case '-': temp = 0xBF; break;
			case ' ': temp = 0xFF; break; 
			default: temp = 0XFF;
	  }
		if(puc_SEG_Buf[j+1] == '.')    //小数点
		{
			temp = temp&0X7F;
			j++;
		}
		puc_SEG_Code[i] = temp;  // 数码管段码数组
  }
}


//-----------------------------------------动态数码管显示---------------------//
void SEG_Disp(uchar *puc_SEG_Code,uchar uc_SEG_Position)
{		
 	//消隐
	P0 = 0xff;
	P2 = P2 & 0x1f | 0xE0;   //开数码管段选573 
	P2 &= 0x1f;              //关573
	
	//数码管位选
	P0  = 1<<uc_SEG_Position; //开数码管位选573 
	P2 = P2 & 0x1f | 0xC0;
	P2 &= 0x1f;
	
	//数码管段选
	P0  = puc_SEG_Code[uc_SEG_Position]; //开数码管段选573 
	P2 = P2 & 0x1f | 0xE0;
	P2 &= 0x1f;
}


//-----------------------------------------数码管处理函数---------------//
void SEG_Proc(void)     //数码管处理函数
{
	if(ui_SEG_flag) return;   //刷新频率
	ui_SEG_flag = 1;
	
    sprintf(puc_SEG_Buf,"%01c%02u",uc_Key_state,(uint)uc_Key_Value);
		
	SEG_Tran(puc_SEG_Buf,puc_SEG_Code);   //数码管段码转换
}


数码管处理函数的调用

	while(1)
	{
	   Key_Proc();      //按键扫描与处理
	   SEG_Proc();      //数码管处理与显示
	   LED_Proc();      //LED处理与显示
	}

数码管显示函数的调用

//1ms定时器1的中断服务函数
void Timer1_ISR(void) interrupt 3
{
  ul_ms++;
  …………
 
	SEG_Disp(puc_SEG_Code,uc_SEG_Position);   //数码管显示
	if(++uc_SEG_Position == 8) uc_SEG_Position = 0;
	
	LED_Disp(uc_LED);  //LED显示
}


在这里插入图片描述


修改记录:
2021.5.4:五四青年节,写下了第一条修改记录,
自作聪明的改编了官方例程的初始化代码,加上对消隐理解的不到位,最后导致数码管微亮(消隐没做好)。改进了 动态数码管显示 函数,如下👇:
锁存器 的工作原理可以理解为 数据透传,数码管的点亮受 段选 和 位选 的控制,对于数码管来说 位选端 和 段选端 指的是 直接控制数码管引脚的端口,在蓝桥杯开发板上也就是573锁存器的输出引脚。 而P2 和 P0 是锁存器的控制引脚。


因此,消隐 是清空 段选端 的上一次数据,保证本次打开 位选 的时候不会 受到上次段选端数据的影响。
消隐 是清空 段选端 的上一次数据,并不是清空控制引脚P0的数据。

在这里插入图片描述

//-----------------------------------------动态数码管显示---------------------//
void SEG_Disp(uchar *puc_SEG_Code,uchar uc_SEG_Position)
{		
 	//消隐
	P0 = 0xff;
	P2 = P2 & 0x1f | 0xE0;   //开数码管段选573 
	P2 &= 0x1f;              //关573
	
	//数码管位选
	P0  = 1<<uc_SEG_Position; //开数码管位选573 
	P2 = P2 & 0x1f | 0xC0;
	P2 &= 0x1f;
	
	//数码管段选
	P0  = puc_SEG_Code[uc_SEG_Position]; //开数码管段选573 
	P2 = P2 & 0x1f | 0xE0;
	P2 &= 0x1f;
}

  
  
  
  
彩 蛋

  • 4
    点赞
  • 2
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

#法外狂徒张三

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者