【蓝桥杯单片机】三、数码管

1、数码管的基本介绍

在这里插入图片描述
在这里插入图片描述

数码管显示的三步

  1. 清屏 (清除上一次显示内容)
  2. 段选 (输送断码值)
  3. 位选 (选择哪一位)

我们需要记住常见数码管断码值
共阴跟共阳取反即可转换

显示的数据断码值(共阳)
00xc0
10xf9
20xa4
20xa4
30xb0
40x99
50x92
60x82
70xf8
80x80
90x90
A0x88
B0x83
C0xc6
D0xA1
E0x86
F0x8E
H0x89
L0xC7
N0xC8
P0x8c
U0xC1
-0xbf
空格0xff
加小数点&= 0x7f

0-9代码考试会给出

uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管段选

2、数码管的显示代码(第一套方案)


uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar dsp_show[8]={0xff,0xff,0xff} //要显示的内容

void Time0_init(void) 
{
    AUXR |= 0x80; 
    TMOD &= 0xF0; 
    TL0 =0xCD;    
    TH0 = 0xD4;
    TR0=1;        
    ET0=1;        
    EA= 1; 
}

void Time0_isr() interrupt 1
{
  static unchar dsp_com = 0; //静态全局变量
  
  P0 = 0;  //清屏  (清楚上一次显示内容)
  P2=0xc0; //打开锁存器控制数码管位选 
  P2=0; //关闭锁存器
  
  P0=dsp_Show[dsp_com];//段选的内容,即要显示的数字
  P2 = 0xe0; //打开锁存器控制数码管段选
  P2=0;      //关闭锁存器 
  
  P0= 1<<dsp_com; //位选左移1位
  P2 =0xc0; //打开锁存器控制数码管位选
  P2=0; //关闭锁存器
  
  if++dsp_com == 8//位选变量自加
  {
    dsp_com=0;
  }
}

3、数码管的显示代码(第二套方案)

数码管显示处理函数

void Seg_Tran(unsigned char *seg_string, unsigned char *seg_buf)
{
	unsigned char i = 0;
	unsigned char j = 0;
	unsigned char temp;
	
	for(i = 0; i <= 7;i++,j++)
	{
		switch(seg_string[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; break;		//默认
		}
		
		if(seg_string[j+1] == '.')//判断小数点
		{
			temp &= 0x7f;
			j++;
		}
		
		seg_buf[i] = temp;
	}
}

显示函数

void Seg_Disp(unsigned char *seg_buf, unsigned char pos)
{	
	P0 = 1<<pos;
	P2 = P2 & 0X1F | 0xc0;//位码选通
	P2 &= 0X1F;

	P0 = 0xff;
	P2 = P2 & 0X1F | 0xe0;//段码选通,消隐
	P2 &= 0X1F;

	P0 = seg_buf[pos];
	P2 = P2 & 0X1F | 0xe0;//段码选通
	P2 &= 0X1F;
}

数码管处理函数

void Seg_Proc(void)
{
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	
	/***用户自定义代码区↓***/	
	sprintf(seg_string,"%1d",(unsigned int)state_flag);	
	
	Seg_Tran(seg_string, seg_buf);
}

//在定时器中加入如下代码
	Seg_Disp(seg_buf, pos);//用于数码管显示
	if(++pos == 8) pos = 0;

4、数码管操作练习

习题1:让数码管显示28428

#include <STC15F2K60S2.H>

typedef unsigned char uchar;
typedef unsigned int uint;


uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管段选
uchar dsp_show[8]={0xff,0xff,0xff};
uint number = 28428;

void Time0_init(void) 
{
    AUXR |= 0x80; 
    TMOD &= 0xF0; 
    TL0 =0xCD;    
    TH0 = 0xD4;
    TR0=1;        
    ET0=1;        
    EA= 1; 
}

void Time0_isr() interrupt 1
{
  static uchar dsp_com = 0; //静态全局变量
  
  P0 = 0;  //清屏  (清楚上一次显示内容)
  P2=0xc0; //打开锁存器控制数码管位选 
  P2=0; //关闭锁存器
  
  P0=dsp_show[dsp_com];//段选的内容,即要显示的数字
  P2 = 0xe0; //打开锁存器控制数码管段选
  P2=0;      //关闭锁存器 
  
  P0= 1<<dsp_com; //位选左移1位
  P2 =0xc0; //打开锁存器控制数码管位选
  P2=0; //关闭锁存器
  
  if(++dsp_com == 8) //位选变量自加
  {
    dsp_com=0;
  }
}
void main()
{
  P0=0xff;
  P2=0x80;
  P2=0x00;
  
  P0=0x00;
  P2=0xa0;
  P2=0x00;
  
  Time0_init();
  
  dsp_show[3]= dsp_code[number/10000];
  dsp_show[4]=dsp_code[number/1000%10];
  dsp_show[5]=dsp_code[number/100%10];
  dsp_show[6]= dsp_code[number/10%10];
  dsp_show[7]=dsp_code[number%10]; 
  while(1)
  {
  }

}

习题2:按下按键使数码管显示相应的矩阵按键值,且LED灯显示相应二进制值

#include <STC15F2K60S2.H>

typedef unsigned char uchar;
typedef unsigned int uint;


uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管段选
uchar dsp_show[8]={0xff,0xff,0xff,0xff,0xff,0xff};
uchar value,countkey;

void Time0_init(void) 
{
    AUXR |= 0x80; 
    TMOD &= 0xF0; 
    TL0 =0xCD;    
    TH0 = 0xD4;
    TR0=1;        
    ET0=1;        
    EA= 1; 
}

void Time0_isr() interrupt 1
{
  static uchar dsp_com = 0; //静态全局变量
  
  P0 = 0; P2=0xc0; P2=0; 
  P0=dsp_show[dsp_com];P2 = 0xe0; P2=0;      
  P0= 1<<dsp_com; P2 =0xc0; P2=0; 
  if(++dsp_com == 8) { dsp_com=0;}
  
  countkey++;
}

void scan_key()
{
  static uchar key_state=0;
  uchar key_val=0, key_x=0, key_y=0;
  //行扫描 
  P3=0x0f; P4=0x00;
  if(!P30)      key_x=3;
  else if(!P31) key_x=2;
  else if(!P32) key_x=1;
  else if(!P33) key_x=0;
  //X=3210 Y=4321 特别易记
  //列扫描 
  P3=0xf0; P4=0xff;
  if(!P34)     key_y=4;
  else if(!P35) key_y=3;
  else if(!P42)  key_y=2;
  else if(!P44) key_y=1;
  key_val=key_x+ key_y*4;//综合行、列扫描的结果,判断具体位置
  
  switch(key_state)
  {
    case 0:
      if(key_val!=0) key_state = 1; //第一次检测到有按键按下,状态为1
      break;  
    case 1:
      if(key_val==0) key_state=0;//第二次(10ms后)若检测到无按键按下,返回状态0
      else 
      {
        key_state = 2; //第二次(10ms 后)再次检测到有按键按下状态为2
        value = key_val; ///将按键值传给需要显示的变量
        switch(key_val)
        {
          case 4: P0=~0x04;P2=0x80;P2=0; break;//按下S4
          case 5: P0=~0x05;P2=0x80;P2=0; break;//按下S5
          case 6: P0=~0x06;P2=0x80;P2=0; break; //按下S6
          case 7: P0=~0x07;P2=0x80;P2=0; break; //按下S7
          case 8: P0=~0x08;P2=0x80;P2=0; break;//按下S8
          case 9: P0=~0x09;P2=0x80;P2=0; break;//按下S9
          case 10: P0=~0x0a;P2=0x80;P2=0; break;//按下S10
          case 11: P0=~0x0b;P2=0x80;P2=0; break; //按下S11
          case 12: P0=~0x0c;P2=0x80;P2=0; break;//按下S12
          case 13: P0=~0x0d;P2=0x80;P2=0; break; //按下S13
          case 14: P0=~0x0e;P2=0x80;P2=0; break;//按下S14
          case 15: P0=~0x0f;P2=0x80;P2=0; break;//按下S15
          case 16: P0=~0x10;P2=0x80;P2=0; break;//按下S16
          case 17: P0=~0x11;P2=0x80;P2=0; break;//按下S17
          case 18: P0=~0x12;P2=0x80;P2=0; break;//按下S18
          case 19: P0=~0x13;P2=0x80;P2=0; break;//按下S19
        }
      }
    case 2:if(key_val==0) key_state = 0;//第三次若检测到无按键按下,返回状态0。
  }
}
void main()
{
  P0=0xff;P2=0x80;P2=0x00;
  P0=0x00;P2=0xa0;P2=0x00;
  Time0_init();
  
  
  while(1)
  {
    if(countkey>9)
    {
      countkey=0;
      scan_key();
      
    if(value >9)dsp_show[6] = dsp_code[value / 10];
    else  dsp_show[6]=0xff;
    dsp_show[7] = dsp_code[value%10];
    }
  }
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值