《Stm32CubeMX+Proteus仿真入门》第5章--数码管显示
数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP),这个小数点可以更精确的表示数码管想要显示的内容;按能显示多少个可分为 1位、 2位、 3位、 4位、6位、8位等数码管。按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。
Stm32CubeMX+Proteus仿真入门
第 五 章
本章节资料下载链接:
我用夸克网盘给你分享了「第5章 数码管显示」,点击链接或复制整段内容,打开「夸克APP」即可获取。
/f4b73M6B4U😕
链接:https://pan.quark.cn/s/9802ba84d838
1、数码管
1.1 数码管介绍
数码管按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP),这个小数点可以更精确的表示数码管想要显示的内容;按能显示多少个可分为 1位、 2位、 3位、 4位、6位、8位等数码管。按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。

共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极 COM 接到电源正极,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。
共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极 COM 接到地线 GND 上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮
对共阴极数码来说,其 8 个发光二极管的阴极在数码管内部全部连接在一起,所以称“共阴”,而它们的阳极是独立的,通常在设计电路时一般把阴极接地。当我们给数码管的任意一个阳极加一个高电平时,对应的这个发光二极管就点亮了。如果想要显示出一个 8 字,并且把右下角的小数点也点亮的话,可以给 8个阳极全部送高电平,如果想让它显示出一个 0 字,那么我们可以除了给第“g,dp” 这两位送低电平外,其余引脚全部都送高电平,这样它就显示出 0 字了。需注意,共阴极数码管需要驱动端提供稳定电流,单片机一般提供不了,一般需要驱动电路才能稳定驱动,比如 74HC573、74HC245 等。
编码:需要共阴极数码管显示一个2,需要ABGED两个发光二极管点亮,对应数值为1,其IGFE CDBA的二进制数值0101 1011,对应16进制为0x5B。反观共阳极显示一个2,对应的IGFE CDBA的二进制为1010 0100,对应16进制为0xA4。其他数字和部分字母显示如下所示。
共阴数码管表
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,
0 1 2 3 4 5
0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c,
6 7 8 9 A B
0x39, 0x5e, 0x79, 0x71, 0x00,
C D E F 无显示
共阳数码管表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92,
0 1 2 3 4 5
0x82, 0xF8, 0x80, 0x90, 0x88, 0x83,
6 7 8 9 A B
0xC6, 0xA1, 0x86, 0x8E, 0xFF,
C D E F 无显示
1.2 数码管动态显示
多位数码管内部的公共端是独立的,而负责显示什么数字的段线(a-dp)全部是连接在一起的,独立的公共端可以控制多位一体中的哪一位数码管点亮,而连接在一起的段线可以控制这个能点亮数码管亮什么数字,通常我们把公共端叫做“位选线”,连接在一起的段线叫做“段选线”。下图的ABCDEFG DP引脚是段选,1234是位选。

动态显示数码管并不是同时点亮的,而是以非常快的速度轮流点亮。比如,先点亮第一个数码管一秒的几十分之一,然后迅速切换到第二个数码管,再切换到第三个、第四个,之后又回到第一个,如此循环。这个切换速度足够快,以至于人眼无法察觉到它们是交替亮起的,看起来就像是所有数码管同时亮着一样。
1.3 74HC245 和 74HC138 芯片介绍
74HC245芯片介绍
74HC245是一种三态输出、八路信号收发器

真值表

OE和DIR引脚控制输出方向。OE低电平是输出模式,DIR为高电平时,A出入B输出。
仿真图
仿真和原理图相比取少量了VDD和GND,其他一致。选用的输出方向是A输入,B输出。

可以理解为,引入74HC245是增强驱动能力,A是什么电平,B就是什么电平但是驱动能力更强,LED更亮,如果取消掉74HC245直连到数码管的话,实物的数码管不够亮。
74HC138芯片简介
74HC138D是一种三通道输入、八通道输出译码器。

真值表:
一般固定E1 E2和E3的值为LLH。通过控制A0 A1和A2的值控制输出位置。

仿真图:

控制通过LSA LSB LSC的电平,控制输出端Y0-Y7,通过代码控制选择不同的位选,从而显示动态显示。A0、A1、A2 输入就相当于 3 位 2 进制数,A0 是低位,A1 是次高位,A2 是高位。而 Y0-Y7 具体哪一个输出有效电平,就看输入二进制对应的十进制数值。比如输入是 101(A2,A1,A0),其对应的十进制数是 5,所以 Y5 输出有效电平(低电平)。
1.4 代码工程配置
stm32cubemx:用Part01_LEDBIT复制修改命名为Part02_LEDSEG,PA0-PA7选择输出模式分别取别名为LED0-LED7,PB3-PB5输出模式,分别取别名为LSC,LSB,LSA


重新生成初始化代码。添加两个文件smg.c和smg.h到工程文件,目录放在Public下,并添加.c和.h到工程。步骤如9.3工程配置。
smg.c的代码如下
#include "smg.h"
#include "system.h"
#include "gpio.h"
//共阴极数码管显示0~F的段码数据
uint8_t gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//数码管端口8位数据同时操作,不影响高位
//写入数据到8位端口,数据低位对应端口低引脚
//GPIO_Pin:8位端口低位引脚
//data:写入数据
void SMG_Write_Data(u8 data)
{
#if 1
uint16_t Set_Pins = 0, Rst_Pins = 0;
//DataDir('O');
if(data & 0x01) Set_Pins |= LED0_Pin;
else Rst_Pins |= LED0_Pin;
if(data & 0x02) Set_Pins |= LED1_Pin;
else Rst_Pins |= LED1_Pin;
if(data & 0x04) Set_Pins |= LED2_Pin;
else Rst_Pins |= LED2_Pin;
if(data & 0x08) Set_Pins |= LED3_Pin;
else Rst_Pins |= LED3_Pin;
if(data & 0x10) Set_Pins |= LED4_Pin;
else Rst_Pins |= LED4_Pin;
if(data & 0x20) Set_Pins |= LED5_Pin;
else Rst_Pins |= LED5_Pin;
if(data & 0x40) Set_Pins |= LED6_Pin;
else Rst_Pins |= LED6_Pin;
if(data & 0x80) Set_Pins |= LED7_Pin;
else Rst_Pins |= LED7_Pin;
HAL_GPIO_WritePin(GPIOA, Set_Pins, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, Rst_Pins, GPIO_PIN_RESET);
#else
GPIOA->ODR = gsmg_code[data];
#endif
}
//数码管显示
void SMG_Display(uint8_t dat[],uint8_t pos)
{
u8 i=0;
u8 pos_temp=pos-1;//从0开始
for(i=pos_temp;i<8;i++)
{
switch(i)//位选
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}
SMG_Write_Data(dat[i]);
//传送段选数据
HAL_Delay(2);//延时一段时间,等待显示稳定
SMG_Write_Data(0x00);//消隐
}
}
smg.h代码如下
#ifndef _smg_H
#define _smg_H
#include "system.h"
//位带定义
#define LSA PBout(5)
#define LSB PBout(4)
#define LSC PBout(3)
#define HCA0 PAout(0)
#define HCA1 PAout(1)
#define HCA2 PAout(2)
#define HCA3 PAout(3)
#define HCA4 PAout(4)
#define HCA5 PAout(5)
#define HCA6 PAout(6)
#define HCA7 PAout(7)
extern uint8_t gsmg_code[17];
//函数声明
void SMG_Display(uint8_t dat[],uint8_t pos);
void SMG_Write_Data(u8 data);
#endif
main.c添加头文件说明

/ USER CODE BEGIN Includes /
#include "smg.h"
#include "system.h"
#include "stm32f1xx_hal_gpio.h"
#include "string.h"
/ USER CODE END Includes /
添加变量声明

/ USER CODE BEGIN 1 /
u8 smgbuf[8];
u32 num = 87654321;
u8 qwan,bwan,swan,wan,qian,bai,shi,ge=0;
/ USER CODE END 1 /
main函数添加代码段
/ USER CODE BEGIN WHILE /
qwan=num/10000000%10;
bwan=num%10000000/1000000;
swan=num%1000000/100000;
wan=num%100000/10000;
qian=num%10000/1000;
bai=num%1000/100;
shi=num%100/10; /num先求余得到十位个位 再求整得到十位 数码管显示十位/
ge=num%10; /num求余 数码管显示个位/
while (1)
{
/ USER CODE END WHILE /
/ USER CODE BEGIN 3 /
memset(smgbuf, 0, sizeof(smgbuf));
smgbuf[0]=gsmg_code[qwan];
smgbuf[1]=gsmg_code[bwan];
smgbuf[2]=gsmg_code[swan];
smgbuf[3]=gsmg_code[wan];
smgbuf[4]=gsmg_code[qian];
smgbuf[5]=gsmg_code[bai];
smgbuf[6]=gsmg_code[shi];
smgbuf[7]=gsmg_code[ge];
SMG_Display(smgbuf,1);
}
/ USER CODE END 3 /

实验现象:
数码管显示87654321

更多推荐



所有评论(0)