蓝桥杯单片机 数码管显示


第二章  数码管显示


文章目录

  • 第二章  数码管显示
  • 前言
  • 一、数码管原理图
  • 二、数码管静态显示与动态显示
    • 1.数码管知识点
    • 2.数码管段码
    • 3.数码管静态显示
    • 4.数码管动态显示
  • 三、代码实现
  • 总结


前言

 不管是省赛还是国赛,数码管显示是蓝桥杯“单片机设计与开发”赛项必考的内容之一。要掌握数码管显示这个内容需要分为两个步骤:首先弄清楚数码管的静态显示,然后再去掌握数码管的动态显示。



一、数码管原理图

蓝桥杯单片机 数码管显示_第1张图片


二、数码管静态显示与动态显示

1.数码管知识点

蓝桥杯单片机 数码管显示_第2张图片

例如:共阳数码管显示7,只需要认对应的a.b.c引脚为低电平(低电平点亮)

dpgfedcba

1     1   1   1    1    0   0    0     0XF8

2.数码管段码

蓝桥杯单片机 数码管显示_第3张图片


3.数码管静态显示

静态显示方式。所谓静态显示就是指无论是多少位数码管,同时处于显示状态。 当单片机系统中使用静态数码管显示时,需要在每一个数码管上添加一个锁存器,当需要某个数码管显示其他内容时,只需要修改与其相连的锁存器的值即可。 当数码管处于静态显示方式时,所有位选线(数码管的公共端)连接在一起,而各个数码管的段选线(数码管上各笔段的引出线)是相互分离的。

4.数码管动态显示

所谓动态显示,是指无论在任何时刻只有一个数码管处于显示状态,每个数码管轮流显示。 当数码管处于动态显示时,所有位选线分离,而每个数码管的各条段选线相连。动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。动态扫描,即是通过分时轮流送出字形码和相应的位选,使各个数码管轮流受控显示。在轮流显示过程中,每位元数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极体的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示,不会有闪烁感。

三、代码实现

seg.h

#ifndef __SEG_H
#define __SEG_H
#include "STC15F2K60S2.H"

void Seg_Tran(unsigned char *pucSeg_Buf, unsigned char *pucSeg_Code);
void Seg_Disp(unsigned char *pucSeg_Code, unsigned char ucSeg_Pos);
#endif

seg.c 

#include "seg.h"
// 显示转换
void Seg_Tran(unsigned char *pucSeg_Buf, unsigned char *pucSeg_Code)
{   
  unsigned char i, j=0, temp;

  for(i=0; i<8; i++, j++)
  {
    switch(pucSeg_Buf[j]) 
    { // 低电平点亮段,段码[MSB...LSB]对应码顺序为[dp g f e d c b a]
      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(pucSeg_Buf[j+1] == '.')
    {
      temp = temp&0x7f;
      j++;
    }
    pucSeg_Code[i] = temp;
  }
}
// 数码管显示
void Seg_Disp(unsigned char *pucSeg_Code, unsigned char ucSeg_Pos)
{
  P0 = 0xff; 						// 消隐
  P2 = P2 & 0x1F | 0xE0;			// P27~P25清零,再定位Y7C
  P2 &= 0x1F;						// P27~P25清零
  P0 = 1<

tim.h 

#ifndef __TIM_H
#define __TIM_H
#include "STC15F2K60S2.H"

void Cls_Peripheral(void);
void Led_Disp(unsigned char ucLed);
void Timer1Init(void);
void Timer0Init(void);
#endif

tim.c 

#include "tim.h"

void Cls_Peripheral(void)
{
  P0 = 0xFF;
  P2 = P2 & 0x1F | 0x80;			// P27~P25清零,再定位Y4C
  P2 &= 0x1F;						// P27~P25清零
  P0 = 0;
  P2 = P2 & 0x1F | 0xA0;			// P27~P25清零,再定位Y5C
  P2 &= 0x1F;						// P27~P25清零
}

void Led_Disp(unsigned char ucLed)
{ // IO模式(J13-2和J13-3相连)
  P0 = ~ucLed;
  P2 = P2 & 0x1F | 0x80;			// P27~P25清零,再定位Y4C
  P2 &= 0x1F;						// P27~P25清零
//XBYTE[0x8000] = ~ucLed;			// MM模式(J13-2和J13-1相连)
}

void Timer1Init(void)				// 1毫秒@12.000MHz
{
  AUXR &= 0xBF;						// 定时器时钟12T模式
  TMOD &= 0x0F;						// 设置定时器模式
  TL1 = 0x18;						// 设置定时初值
  TH1 = 0xFC;						// 设置定时初值
  TF1 = 0;		 					// 清除TF1标志
  TR1 = 1;			  				// 定时器1开始计时
  ET1 = 1;		  					// 允许定时器1中断
  EA = 1;		  					// 允许系统中断
}

main.c

// 运行程序时,将J13调整为io模式(1-2脚短接)
#include "tim.h"
#include "seg.h"
#include "stdio.h"

unsigned char ucSec, ucLed;
unsigned char pucSeg_Buf[9], pucSeg_Code[8], ucSeg_Pos;
unsigned long ulms;
// 注意:sprintf()会在字符串后面添加”\0”,所以pucSeg_Buf[]的长度应为9。
// 如果字符串中包含小数点,pucSeg_Buf[]的长度应为10。
void main(void)
{
  Cls_Peripheral();
  Timer1Init();

  while(1)
  {
    sprintf(pucSeg_Buf, "    %04u", (unsigned int)ucSec);
    Seg_Tran(pucSeg_Buf, pucSeg_Code);
  }
}

void Time_1(void) interrupt 3
{
  ulms++;
  if(!(ulms % 1000))
  {
    ucSec++;

    ucLed ^= 1;
    Led_Disp(ucLed);
  }
	
  Seg_Disp(pucSeg_Code, ucSeg_Pos);	
  if(++ucSeg_Pos == 8) ucSeg_Pos = 0;
}

总结

使用定时器实现数码管动态显示

你可能感兴趣的:(蓝桥杯,单片机,c语言,嵌入式硬件)