51单片机数码管的使用

IO的使用2–数码管

本文主要涉及51单片机的数码管的使用

一、数码管的定义与类型

数码管是一种用于数字显示的电子元件,通常由多个LED(发光二极管)组成。它被广泛用于各种计数、测量和显示应用,如数字时钟、温度计、计数器等。

主要特点和结构如下:

  1. LED组成: 数码管的基本组成单元是LED,通常为七段共阳(Common Cathode)或共阴(Common Anode)的结构。七段代表数码管上的七个LED段,分别对应显示数字0到9的不同线段。

  2. 共阳和共阴: 共阳数码管表示LED的阳极连接在一起,共阴数码管表示LED的阴极连接在一起。在共阳数码管中,通过给定的线段点亮LED,而在共阴数码管中,通过接通的线段关闭LED。

  3. 多位数码管: 为了显示更多的数字或字符,可以将多个数码管连接在一起形成多位数码管,每一位数码管对应显示其中的一个数字或字符。

  4. 控制信号: 为了控制数码管的显示,需要提供适当的控制信号。这些信号通常包括电源、段选信号和位选信号,以确保正确的数字或字符在正确的数码管上显示。

  5. 常见的数码管类型:

    • 共阳七段数码管: 每个数字由7个LED段组成,共阳表示数字的阳极连接在一起。
    • 共阴七段数码管: 同样由7个LED段组成,共阴表示数字的阴极连接在一起。
    • 数码管显示器: 可以同时显示多个字符或数字,通常用于计算器、计数器等设备。

总体而言,数码管是一种简单、实用的数字显示设备,广泛应用于各种电子设备和嵌入式系统。

1.1 数码管的原理图

在这里插入图片描述

在这里插入图片描述

可以从上面原理图可以知道:

上图电路使用的是 2 个四位一体的共阴数码管组成,即 8 位数码管的段选数据 a-dp 全部并联一起引出,每位数码管的位选即公共端引出。数码管的段选 a-dp连接在 74HC245 驱动芯片输出口,由 P0 端口控制。由 P2.2、P2.3、P2.4 管脚控制 74HC138 译码器输入从而控制数码管位选.

二、 举个栗子

1-利用动态扫描方法在三位数码管上显示出稳定的321

思路:显示原理:

  1. 数码管类型: 数码管分为共阴极和共阳极两种类型。在共阴极数码管中,所有的LED的阴极(负极)都连接在一起,而阳极(正极)分别连接到不同的引脚。在共阳极数码管中,所有LED的阳极连接在一起,而阴极分别连接到不同的引脚。

  2. 动态扫描: 为了在有限的引脚上控制多个数码管,采用了动态扫描的方法。在一个很短的时间内,依次点亮每一个数码管,然后迅速切换到下一个数码管,以此类推。由于人眼的视觉暂留效应,看起来就像所有的数码管都在同时显示

  3. 数码管控制: 对于每个数码管,通过在段选信号上输出相应的二进制码,控制数码管的每一段LED的亮灭状态。例如,数字 0 对应的二进制码可以是 00111111,其中每一位对应数码管的一个段,1 表示点亮,0 表示熄灭。

  4. 显示数字: 在动态扫描的过程中,根据要显示的数字,依次输出相应的段选信号,将对应数码管的LED点亮,实现数字的显示。通过迅速切换并依次点亮每个数码管,就能够看到整个数字在数码管上的显示效果。

  5. 控制电平: 在具体的硬件连接中,控制数码管的LED点亮和熄灭需要通过控制相应的引脚输出高电平或低电平来实现。不同的数码管芯片和硬件连接可能存在一些差异,但基本的原理是类似的。

2.1 一个数码管的底层函数

下面的函数通过数码管显示一位数字,通过设置数码管的位选信号(Location参数)以及数码管的段选信号(NixieNumber数组中的对应数字),从而实现数字的显示。
其中:

  1. unsigned char smgNumber[] = {...}:定义了一个数组,用于存储共阳极数码管的七段编码。每个元素对应一个数字的七段编码,共阳极表示为1,点亮。

  2. void smg(unsigned char Location, Number):定义了一个函数smg,接收两个参数,Location表示选择哪一个数码管,Number表示要在该数码管上显示的数字。

  3. switch(Location):根据Location的值,选择要点亮的数码管。根据不同的Location值,设置对应的位选信号,即数码管的引脚。这样在多位数码管的情况下,可以选择具体点亮哪个数码管。

  4. P0 = smgNumber[Number];:将对应数字的七段编码写入P0口,通过具体的硬件连接和控制逻辑,实现数码管的段选。

  5. Delay(1);:通过调用Delay函数,延时一段时间,以使得数码管的LED能够被稳定点亮,确保显示效果。

  6. P0 = 0x00;:将P0口清零,熄灭数码管的LED,准备进行下一轮的显示。

这样,通过不断调用smg函数,可以在指定的数码管上显示相应的数字。

//unsigned char smgNumber[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};  //共阳极编码,七位表示数字
//共阴极数码管显示 0~F 的段码数据
unsigned char smgNumber[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void smg(unsigned char Location,Number)     //第一个参数选择数码管,第二个参数表示显示数字
{
 //这一段swith代码是为了设置位选信号,选择数码管
 switch(Location)
 {
  case 1:P2_4=1;P2_3=1;P2_2=1;break;                  
  case 2:P2_4=1;P2_3=1;P2_2=0;break;
  case 3:P2_4=1;P2_3=0;P2_2=1;break;
  case 4:P2_4=1;P2_3=0;P2_2=0;break;
  case 5:P2_4=0;P2_3=1;P2_2=1;break; 
  case 6:P2_4=0;P2_3=1;P2_2=0;break;
  case 7:P2_4=0;P2_3=0;P2_2=1;break;
  case 8:P2_4=0;P2_3=0;P2_2=0;break;
 }
 
 //这一段代码是给开启之后的数码管显示数字
 P0=smgNumber[Number];
 Delay(1);//延时一段时间,等待显示稳定
 P0=0x00;//消音
}

2.2 调用上面的底层函数显示具体数字

要显示具体的数值,只需要在主函数中调用上述底层函数即可

//利用动态扫描显示稳定的321
void main()
{
 while(1)
 {
   smg(1,3);
   smg(2,2);
   smg(3,1 );
 }
}

上面代码中还使用到了延迟函数
如下:

void Delay(unsigned int xms)
{
 unsigned char i,j;
 while(xms)
 {
  i=2;
  j=239;
  do
  {
   while(j--);
   }
  while(i--);
   xms--;
 }
}

当然其他延迟函数也是适用的。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,如您所要求,我已经修改了代码,用于适配共阴极数码管,修改后的代码如下: ```c #include <reg51.h> #define uchar unsigned char #define uint unsigned int uchar code table[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; //共阴数码管显示0~9 uchar cnt = 0; //计数器 uchar time = 0; //倒计时时间(秒) uchar pause = 0; //暂停标志 uchar reset = 0; //复位标志 uint t = 0; //定时器计数器 uint cnt_ms = 0; //计数器计时器 uchar beep = 0; //蜂鸣器标志 void delay(uint t); void timer0_init(); void key_scan(); void main() { EA = 1; //总中断开关 timer0_init(); //定时器0初始化 while (1) { key_scan(); //按键扫描 if (reset) //复位 { cnt = 0; time = 0; pause = 0; reset = 0; } if (!pause) //未暂停 { if (cnt_ms >= 100) //1秒钟计数结束 { cnt_ms = 0; time--; if (time <= 5) //倒计时结束前5秒,蜂鸣器发出声音警告 beep = 1; if (time == 0) //时间到 pause = 1; } } P0 = 0x00; //关闭数码管显示 P2 = 0x80; //选择第一位数码管 P0 = table[time / 10]; //显示十位 delay(5); //延时5毫秒 P0 = 0x00; //关闭数码管显示 P2 = 0x40; //选择第二位数码管 P0 = table[time % 10] + (beep ? 0x80 : 0x00); //显示个位和蜂鸣器 } } void delay(uint t) { uint i; while (t--) for (i = 0; i < 1000; i++); } void timer0_init() { TMOD |= 0x01; //定时器0工作在模式1 TH0 = 0xfc; TL0 = 0x18; //定时器0初值为65536-5000=60536,即5000us ET0 = 1; //定时器0中断允许 TR0 = 1; //启动定时器0 } void key_scan() { if (P1 != 0xff) //有按键按下 { delay(5); //延时5毫秒 if (P1 != 0xff) //再次判断按键是否按下 { switch (P1) { case 0xfe: //按键1(倒计时时间增加1秒) time++; if (time >= 99) time = 99; cnt = 0; pause = 1; break; case 0xfd: //按键2(倒计时时间减少1秒) time--; if (time <= 0) time = 0; cnt = 0; pause = 1; break; case 0xfb: //按键3(倒计时开始/暂停) pause = !pause; break; case 0xf7: //按键4(倒计时复位) reset = 1; break; default: break; } while (P1 != 0xff); //等待按键释放 } } } void timer0() interrupt 1 { TH0 = 0xfc; TL0 = 0x18; //重新赋初值 t++; if (t >= 500) //5000us*500=2500000us=2500ms=2.5s { t = 0; cnt_ms++; if (beep) //蜂鸣器响1秒 { cnt++; if (cnt >= 100) //1秒钟计数结束 { cnt = 0; beep = 0; } P3 = 0x00; //蜂鸣器发声 } else P3 = 0xff; //蜂鸣器不发声 } } ``` 该代码在共阴数码管的显示方式上,仅需要将数码管的显示码表改为共阴数码管的显示码表即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写的什么石山代码

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值