51单片机点亮8位数码管

51单片机和数码管介绍:

     51单片机是一种常见的微控制器,它有足够的I/O端口来驱动8位数码管。下面是一种实现方式 首先,我们需要将8位数码管(也叫8段数码管)连接到一个I/O端口。通常情况下,我们需要对8位数码管的每个段 (a-g和 dp)进行控制。这样,我们需要7个1/0端口来控制这8个段。

数码管的基本原理:

数码管是一种能够显示数字和部分宇母的显示器件 ,它由多个发光二极管组成,可以显示 0-9 的数宇。数码管按照结构可以分为共阳数码管和共阴数码管两种类型。共阳数码管的显示原理是通过控制各个发二极管的通断状态来显示不同的数字 ,而共阴数码管则是通过控制对应的极性来实现数字的显示。

51单片机连接数码管的实现步骤:

由于 51 单片机有多个通用I/O口,因此可以连接多个数码管。连接数 I 码管的步骤如下:

1)确定数码管的类型,共阴还是共阳

2)连接数码管的正极和负极到单片机的对应I/O口

3)编写程序控制 51 单片机的I/O口输出状态,以显示所需的数字

硬件连接:

在硬件连接中,8位数码管由8个发光二极管组成,共8位,每一位都有对应的引脚。其中,数码管的共阴极和共阳极是需要特别注意的部分。
•共阴极数码管:共阴极数码管是指将所有发光二极管的负极接到一起形成公共阴极,即所有发光二极管的负极都连接到一个公共端。在这种情況下,位选接的是高电平,要想正常显示通过控制低电平来控制段选。
•共阳极数码管:共阳极数码管是指将所有发光二极管的正极接到一起形成公共阳极,即所有发光二极管的正极都连接到一个公共端。在这种情況下,位选接的是低电平,要想正常显示通过控制高电平来控制段选。

软件编程:
在软件编程中,主要是通过控制位选和段选来控制数码管的显示。位选是用来控制要显示的位数码管,段选则是用来控制显示的内容。
•静态显示:静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。
• 动态显示:动态显示的特点是可以同时显示多位数码管,但是品示的内容必须相同。当多位数码管应用于某一系统时,它们的“位选”是可独立控制的,而“段选”是连接在一起的,我们可以通过位选信号控制哪几个数码管亮,而在同一时刻,位选选通的所有数码管上显示的数字始终都是一样的。
以上就是51单片机8位数码管显示的基本方法,你可以根据实际需求选择静态显示或者动态显示,也可以根据具体的显示内容来选择共阴极或共阳极的数码管。

注:在程序中,需要使用数码管驱动程序来控制数码管的显示。通常,数码管驱动程序包括初始化、显示数据和清屏等函数。在初始化函数中,需要设置数码管的工作模式、端口映射和显示模式等参数。在显示数据函数中,需要将显示数据转换为数码管可识别的格式,并将其写入到数码管的显示缓冲区中。在清屏函数中,需要清空数码管的显示缓冲区,以便显示下一组数据。

一、8位数码管的原理图:

 通过原理图,我们可以知道,数码管和LED灯存在公用的线路。要使LED灯能亮,P2.3的引脚就要置1,但是P2.3引脚为1时,数码管是不能正常显示的,所以要使数码管正常显示,要对P2.3引脚置0。
同时P2.0、P2.1和P2.2引脚对数码管显示也很重要(位置选择),三个引1即的状态(0或1)对应的三位二进制数可以表示0~7(分别对应从左到右的数码管)。
与LED灯一样,只要通过对P0口赋不同的值就可以是示不同的字符。

二、多位数码管的驱动方式

1.IO 口直接驱动法:
直接使用单片机的 IO 口驱动数码管, 1 位数码管占用 8 IO 口,每个数码管都是专线专用。以 51 单片机为例,一共有4 IO 口,如果使用 IO 口直接驱动数码管则最多只能接 4 位数码管。
优点:所有数码管每时每刻都能得到显示信号,显示稳定不闪烁,编程简单。
缺点:非常占用单片机的 IO 口资源,驱动 4 位数码管后,单片机所有 IO 口被占用,无法实现其他功能。
2.专用驱动芯片驱动:
每位数码管使用 74LS164 芯片单独驱动,如图 2-2-1 所示,该芯片可以串联使用,驱动多位数码管,只需 占用单片机2 IO 口。
优点:所有数码管每时每刻都能得到显示信号,显示稳定不闪烁,占用极少的 IO 口,消耗很小的 CPU 资源。
缺点:电路元器件较多,编程较为复杂,硬件成本较大。

                                             如图,使用独立的驱动芯片驱动数码管 

时分复用动态显示:
这种显示方式 8 位数码管共用一组信号线, 8 位数码管轮流显示,同一时刻只有 1 位数码管得到显示信号,未得到显示信号的数码管都处于熄灭状态,因为8 位数码管的轮流显示速度是非常快的(间隔 3ms 左右),因为人眼的视觉残留效应,看起来就是8 位同时显示,连接图如下图 所示。
优点:占用 IO 口较少,电路简单,基本不用增加额外的器件。
缺点:编程较为复杂;需要 CPU 每时每刻轮流显示 8 个数码管,占用 CPU 资源多;数码管不能同时得到显示信号,有可能会出现闪烁。

时分复用动态显示 的原理可得,其关键是如何单独给每位数码管发送显示信号。以显 “12345678” 为例:其显示步骤如下:
1. 打开第 1 位数码管的显示开关,关闭其余数码管显示开关
2. 在数据线上发送数字 “1” 的字码
3. 维持一小段时间(大约 2ms
4. 发送消隐的字码,此时第 1 位数码管关闭显示
5. 打开第 2 位数码管的显示开关,关闭其余数码管显示开关
6. 在数据线上发送数字 “2” 的字码
7. 维持一小段时间(大约 2ms )如  74HC138 译码器的逻辑图和真值表
8. 发送消隐的字码,此时第 2 位数码管关闭显示
9. 从步骤 5 开始重复,直到 8 个数字显示完成
从显示步骤中可以看到,实际上每个位只显示了 2ms 后就熄灭了,为了维持显示效果,需要不断的重复步骤1-9 ,这样就需要 CPU 一直执行显示代码,如果 CPU 没能及时的执行显示代码,会出现数码管闪烁的情况,严重时无法正常显示内容。

三、动态显示驱动方案选择

 如何实现动态数码管?通过数码管电路图可以知道需要满足2个条件:

一)是 LED 的正极有高电平,二)是LED 的负极为低电平,两个条件同时满足时 LED 点亮。因为 8 个数码管的正极都是共用一组驱动信号,所以正极有高电平的时候8 个数码管都有高电平。要想独立控制只能从条件二入手,只要负极不是低电平,那么不管正极什么情况,数码管都不会点亮,由此就得到控制方案:控制阴极电平的高低( GND 之间的通断)
使用译码器减小 IO 口占用:
按照上图动态数码管 的连接方式, 8 位数码管,则需要 8 IO 口控制其阴极的通断,为了进一步减少 IO的使用,可以使用译码器芯片。 可以使用 38 译码器“74HC138 ,通过 3 IO 口控制 8 路信号的选中状态,达到减小 IO 口占用的的,如下图 所示:

因为开发板中使用了 74HC138 译码器,所以需要结合译码器的真值表进行编写,开发板的连接原理图如图 所示:

最后可以编译数字代码进去,现以12345678为例:(整体代码)

 定义管脚:

#include "regx52.h"
#include "intrins.h"
unsigned char meg_code[10] =
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
sbit HC_A0 = P2^2; //对应74HC138的A口
sbit HC_A1 = P2^3; //对应74HC138的B口
sbit HC_A2 = P2^4; //对应74HC138的C口

 数码管位选择函数:

//n 需要选择导通的位,1表示LED1导通,2表示LED2导通,以此类推
void SMG_Select(unsigned char n)
{
switch(n)
{
case 1: //LED1导通(由原理图可知LED1和Y0连接,由真值表可知
A0、A1、A2都为L的时候,Y0为L)
HC_A0 = 0;
HC_A1 = 0;
HC_A2 = 0;
break;
case 2:
HC_A0 = 1;
HC_A1 = 0;
HC_A2 = 0;
break;
case 3:
HC_A0 = 0;
HC_A1 = 1;
HC_A2 = 0;
break;
case 4:
HC_A0 = 1;
HC_A1 = 1;
HC_A2 = 0;
break;
case 5:
HC_A0 = 0;
HC_A1 = 0;
HC_A2 = 1;
break;
case 6:
HC_A0 = 1;
HC_A1 = 0;
HC_A2 = 1;
break;
case 7:
HC_A0 = 0;
HC_A1 = 1;
HC_A2 = 1;
break;
case 8:
HC_A0 = 1;
HC_A1 = 1;
HC_A2 = 1;
break;
}
}

延时函数: 

void Delay1_ms(unsigned int a) //@11.0592MHz
{
unsigned char i, j;
for(a;a>0;a--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} 
while (--i);
}
}

显示数字主函数: 

void main()
{
while(1)
{
//显示数字“1”
SMG_Select(8); //选中LED8导通,其余的关闭
P0 = meg_code[1]; //传送数字“1”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“2”
SMG_Select(7); //选中LED7导通,其余的关闭
P0 = meg_code[2]; //传送数字“2”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“3”
SMG_Select(6); //选中LED6导通,其余的关闭
P0 = meg_code[3]; //传送数字“3”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“4”
SMG_Select(5); //选中LED5导通,其余的关闭
P0 = meg_code[4]; //传送数字“4”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“5”
SMG_Select(4); //选中LED4导通,其余的关闭
P0 = meg_code[5]; //传送数字“5”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“6”
SMG_Select(3); //选中LED3导通,其余的关闭
P0 = meg_code[6]; //传送数字“6”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“7”
SMG_Select(2); //选中LED2导通,其余的关闭
P0 = meg_code[7]; //传送数字“7”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
//显示数字“8”
SMG_Select(1); //选中LED1导通,其余的关闭
P0 = meg_code[8]; //传送数字“8”的字码
Delay1_ms(2); //延时2ms
P0 = 0x00; //关闭显示
}
}

以上是完整代码,如有问题可留言探讨,谢谢!

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
51单片机基础应用设计C语言实例(400例)合集: 10-LED循环左移 100-24c02记忆开机次数 101-24c02存储上次使用中状态 102-DS1302 时钟原理 103-DS1302可调时钟 104-DS1302时钟串口自动更新时间 105-1602液晶显示DS1302时钟 106-字库ST7920 12864液晶基础显示 107-按键 12864显示 108-PCF8591 1路AD数码管显示 109-PCF8591 4路AD数码管显示 11-LED循环右移 110-PCF8591 DA输出模拟 111-PCF8591 输出锯齿波 112-PCF8591 1602液晶显示 113-串口通讯 114-串口通讯中断应用 115-RS485基本通讯原理 116-红外收原理 117-红外解码数码管显示 118-红外解码1602液晶显示 119-红外发射原理 12-查表显示LED灯 120-红外收发测试 121-双红外发射避障原理测试 122-1个18B20 温度传感器 数码管显示 123-1个18b20温度传感器1602液晶显示 124-多个18b20温度传感器1602液晶显示 125-超温报警测试 126-温度可调上下限1602 126-温度可调上下限1602显示 127-PS2键盘输入1602液晶显示 128-双色点阵1种颜色显示测试 129-双色点阵2种颜色显示测试 13-双灯左移右移闪烁 130-双色点阵显示特定图形 131-双色点阵交替图形显示 132-双色点阵双色交替动态显示 133-热敏电阻测试数码管显示 134-光敏电阻测试数码管显示 135-自动调光测试 136-串转并数字芯片测试 137-非门数字芯片测试 138-电子琴 139-实用99分钟倒计时器 14-花样灯 140-外部频率测试 141-定时做普通时钟可调 142-1602液晶显示的密码锁 143-实用密码锁 144-1602液晶显示的计算器 145-秒表 146-串口测温电脑显示 147-交通灯测试 148-点阵模拟电梯上行下行 149-点阵流动广告模拟 15-PWM调光 150-综合测试程序 151-12位AD_DS1621与12864液晶 152-闪烁灯一 153-闪烁灯二 154-流水灯A 155-51单片机12864大液晶屏proteus仿真 156-流水灯B 157-数码管显示 158-12864LCD显示计算器键盘按键实验 159-数码管显示(锁存器) 16-共阳数码管静态显示 160-数码管动态显示 161-数码管滚动显示 162-数码管字符显示 163-独立按键 164-矩阵键盘 165-矩阵键盘(LCD) 166-用DS1302与12864LCD设计的可调式中文电子日历 167-定时器的使用(方式1) 168-12864LCD图形滚动演示 169-用PG12864LCD设计的指针式电子钟 17-1个共阳数码管显示变化数字 170-定时器的使用(方式2) 171-外部中断的使用 172-定时器和外部中断 173-开关控制12864LCD串行模式显示 174-点阵显示 175-液晶1602显示 176-12864带字库测试程序 177-串行12864显示 178-遥控键值解码-12864LCD显示 179-液晶12864并行 18-单个数码管模拟水流 180-液晶12864并行2 181-串口发送试验 182-串口收试验 183-串口收(1602) 184-蜂鸣器发声 185-直流电机调速 186-蜂鸣器间断发声 187-lcd-12864应用 188-继电器控制 189-直流电机调速 19-按键控制单个数码管显示 190-步进电机 191-存储AT24C02 192-PCF8591T AD实验 193-PCF8591T芯片DA实验 194-温度采集DS18B20 195-EEPROM_24C02 196-12864LCD显示24C08保存的开机画面 197-红外解码 198-12864LCD显示EPROM2764保存的开机画面 199-时钟DS1302(LCD) 2-IO输出-点亮1个LED灯方法2 20-单个数码管指示逻辑电平 200-宏晶看门狗 201-SD卡 202-秒表 203-普通定时器时钟 204-彩屏控制 205-彩屏图片显示 206-12864+DS1302时钟+18B20温度计 207-12864测试程序 208-12864串行驱动演示 209-12864生产厂程序 21-8位数码管显示其中之一 210-12864中文显示测试 211-LCD12864 212-12864M液晶显示(有字库)程序(汇编) 213-超声波测距LCD12864显示 214-红外遥控键值解码12864液晶显示(汇编语言)
以下是51单片机DS1302万年历代码,供参考: ```c #include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit SCLK=P1^0; sbit RST=P1^1; sbit IO=P1^2; uchar code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共阴数码管显示0~F的值 uchar time[7]; //用来存储日期时间数据 void delay(uchar i) { while(i--); } void write_byte(uchar dat) { uchar i; for(i=0;i<8;i++) { SCLK=0; IO=dat&0x01; dat>>=1; SCLK=1; } } uchar read_byte() { uchar i; uchar dat=0; for(i=0;i<8;i++) { SCLK=0; dat>>=1; if(IO) { dat|=0x80; } SCLK=1; } return dat; } void ds1302_single_write(uchar reg,uchar dat) { RST=0; SCLK=0; RST=1; write_byte(reg); write_byte(dat); RST=0; } uchar ds1302_single_read(uchar reg) { uchar dat; RST=0; SCLK=0; RST=1; write_byte(reg|0x01); dat=read_byte(); RST=0; return dat; } void ds1302_init() { ds1302_single_write(0x8e,0x00);//禁止写保护 ds1302_single_write(0x80,0x00);//秒清零 ds1302_single_write(0x82,0x00);//分清零 ds1302_single_write(0x84,0x00);//时清零 ds1302_single_write(0x86,0x01);//日期设为1号 ds1302_single_write(0x88,0x01);//星期设为星期一 ds1302_single_write(0x8c,0x00);//年月日写保护打开 } void ds1302_read_time() { uchar i; for(i=0;i<7;i++) { time[i]=ds1302_single_read(0x81+i); } } void display_time() { uchar i; P2=0xff;//关闭所有数码管 for(i=0;i<6;i++) { if(i==0||i==2) { P2=table[time[i]/16];//显示十位数 P2=(P2<<1)|0x01;//点亮小数点 delay(5); P2=table[time[i]%16];//显示个位数 P2=(P2<<1)|0x01;//点亮小数点 } else if(i==4) { P2=table[time[i]/16];//显示十位数 P2=(P2<<1)|0x01;//点亮小数点 delay(5); P2=table[time[i]%16];//显示个位数 P2=(P2<<1)|0x01;//点亮小数点 } else { P2=table[time[i]/16];//显示十位数 delay(5); P2=table[time[i]%16];//显示个位数 } if(i==1||i==3) { P2=(P2<<1)|0x01;//点亮小数点 } delay(5); P2=0xff;//关闭所有数码管 } } void main() { ds1302_init();//DS1302初始化 while(1) { ds1302_read_time();//读取时间 display_time();//显示时间 } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值