STM32-GPIO数码管动态显示

目录

一、数码管原理

1、LED数码管的结构

2、LED数码管工作原理

3、数码管动态显示

1)动态显示的概念

2)动态显示的接口

二、代码的实现

三、仿真结果展示


 

本篇文章将继续进一步了解GPIO外设输出模式

一、数码管原理

知道这一部分的朋友可以直接点击目录部分跳过这段跳过,这里介绍一下数码管的知识

1、LED数码管的结构

不管在嵌入式STM32中还是在单片机51中,我们经常采用LED数码管来显示我们系统的状态、运算结果等各种信息,LED数码管是机器和人对话的一种重要的输出设备。

9691ea0ef50f48c589805d8a64947ab1.png

单个LED数码管的外形和内部结构如上图所示。LED数码管由8个发光二极管组成,通过不同的发光字段组合可以显示数字(0~9)、字符(A~F、H、L、P、R、U、Y、符号"——"及小数点"."等)。

按照内部8个发光二极管的连接方式的不同,LED数码管可以分为共阳极与共阴极俩种,上图有结构图。

2、LED数码管工作原理

这里以共阳极LED数码管为例来阐述具体在单片机上的工作原理。

要使数码管显示数字或者字符,直接将相应的数字或者字符送入数码管的段控制端是不行的,必须使段控制端输出相应的字符编码。

如上图所示,八个发光二极管的阳极连接在一起,作为公共端(我们喜欢说位选端)阴极作为”段“控制端(我们说段选端)。

1)当公共端(位选端)接低电平时,所以二极管截止,不发光。

2)当公共端(位选端)接高电平时,当某段控制端为高电平,该段的发光二级管导通并点亮。通过点亮不同的段,显示不同的字符。如显示数字1时,b、c俩段接低电平其他段接高电平。

共阴极LED数码管与共阳极类似,这个里就不在进行介绍了。

这里给出共阳与共阴极数码的显示字形编码:

 共阳极共阴极
字形对应编码对应编码
0

0xc0

0x3f
10xf90x06
20xa40x5b
30xb00x4f
40x990x66
5 0x920x6d
60x820x7d
70xf80x07
80x800x7f
9(g)0x98(0x90)0x67(0x6f)
A0x880x77
B0x830x7c
C(c)0xc6(0xa7)0x39
d0xa10x5e
E0x860x79
F0x8e0x71
H(h)0x89(0x8b)0x76(0x74)
L0xc70x38
P0x8c0x73
U0xc10x3e
.0x7f0x80
——0xbf0x40

3、数码管动态显示

1)动态显示的概念

动态显示是一种按位轮流点亮各位数码管的显示方式,即在某一时段,只让其中一位数码管的位选端有效,并送出相对应的字形显示编码。此时其他位数码管因位选端无效而处于熄灭状态。下一时端按顺序选通另一位数码管,并送出相对应的字形编码显示,按照此规律进行下去,即可使各位数码管分别间断的显示出相应的字符。虽然在同一时刻只有一位数码管点亮,但利用人眼的视觉暂留效应和发光二极管熄灭时的余晖效应,看到的确是多为数码管同时点亮显示,这个过程被称为动态扫描显示。

2)动态显示的接口

数码管的所有段选端共用一个8位的I/O端口,而每个数码管的位选端要占用一根I/O线,因此,n位动态显示数码管只占用一个8位的I/O端口和n根I/O线。显示n位数码时,连接段选的8位I/O端口依次送出n位数码的段码数据。同时,依次控制相应位公共端,当公共端电平位”0“(共阴极)或者”1“(共阳极)时,该位数码管点亮。

到这预备知识介绍完了现在开始写代码了

二、代码的实现

我们使用固件库编程,首先我们需要一个工程模板,详情可以看STM32固件库点亮LED灯_学c入门到入土的博客-优快云博客

LED头文件

#ifndef _LED_H_         //判断标号_LED_H_是否被定义,如果没有则#ifndef到#endif代码有效
#define _LED_H_
 
#include <stm32f10x.h>
 
#define LED_GPIO_PORT        GPIOC                  
//数码管的GPIO端口

#define LED_GPIO_CLK         RCC_APB2Periph_GPIOC    
//数码管相对应的时钟端口开启

#define LED_GPIO_PIN         GPIO_Pin_All            
//数码管的GPIO引脚号,All表示当前GPIOx的全部引脚

#define uchar unsigned char                          //给无符号字符型宏定义一个别名
#define uint unsigned int                            //给无符号整型宏定义一个别名
 
void LED_GPIO_Config(void);                             //数码管GPIO端口初始化函数

void delay_ms(uint ms);
//延时函数
 
#endif

LED.C文件

#include "led.h"
 
void LED_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
        /*定义一个GPIO_InitTypeDef类型的结构体*/
 
	  RCC_APB2PeriphClockCmd(LED_GPIO_CLK,ENABLE);
        /*开启数码管相关的GPIO外设时钟*/
 
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        /*设置引脚模式为通用推挽输出*/
 
	  GPIO_InitStructure.GPIO_Pin=LED_GPIO_PIN;
        /*选择要控制的引脚*/
 
	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        /*设置引脚速率为50MHz*/
 
	  GPIO_Init(LED_GPIO_PORT,&GPIO_InitStructure);
        /*调用库函数初始化GPIO*/
}

void delay_ms(uint ms)  //延时函数
{
	unsigned int i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
}

main.C文件

#include "led.h"
uchar LED_AC_table1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//共阳极数码编码
int main()
{
	LED_GPIO_Config();   //调用数码管GPIO外设初始化
	uint j=0x0100;       //这里是个算法变量的函数,这里就不展开讨论
	while(1)
	{
		for(int i=0;i<6;i++)   //循环选段
		{
			delay_ms(50);        //延时
			GPIO_Write(LED_GPIO_PORT,LED_AC_table1[i]+j);  //固件库函数选位输出相对应的字符
			if(j==0x2000)                                  //算法
			{
				j=0x0100;
			}
			else
			{
				j<<=1;
			}
		}
	}	
}

在仿真之前我们看一下我们又一个新的固件库函数

函数名    

GPIO_Write()

函数原型  

void GPIO_Write(GPIO_TypeDef* GPIOx, u16 PortVal)
功能描述向指定的GPIO端口写入数据
输入参数1GPIOx:x可以是A,B,C,D,来选择GPIO外设
输入参数2PortVal:待写入端口数据寄存器的值

三、仿真结果展示

接下来让我们看看Proteus 仿真的结果吧

ef4fea5d9e4844a1a8b02cebc243de7a.png

 关注我下面我会继续更新GPIO外设输入输出的实际小程序,来帮助大家更好的理解GPIO外设的功能,后面还会更新STM32的所有特色外设。

 

好的,我来为您讲解一下 STM32 数码管动态显示的实现方法。 首先,您需要准备一个 STM32 单片机开发板,以及一个数码管模块。然后,您需要将数码管模块连接到 STM32 开发板上,并且在代码中定义数码管的引脚。 在动态显示数码管的过程中,我们需要使用到定时器来定时刷新数码管的显示。以下是一个简单的数码管动态显示的示例代码: ``` #include "stm32f10x.h" #include "delay.h" #define LED_GPIO GPIOB #define LED_PIN GPIO_Pin_5 uint8_t num[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; void LED_Show(uint8_t num1, uint8_t num2, uint8_t num3, uint8_t num4) { GPIO_SetBits(LED_GPIO, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); GPIO_ResetBits(LED_GPIO, GPIO_Pin_0); GPIO_Write(LED_GPIO, num[num1]); delay_ms(5); GPIO_ResetBits(LED_GPIO, GPIO_Pin_1); GPIO_Write(LED_GPIO, num[num2]); delay_ms(5); GPIO_ResetBits(LED_GPIO, GPIO_Pin_2); GPIO_Write(LED_GPIO, num[num3]); delay_ms(5); GPIO_ResetBits(LED_GPIO, GPIO_Pin_3); GPIO_Write(LED_GPIO, num[num4]); delay_ms(5); } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_GPIO, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 1000-1; TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { } } void TIM3_IRQHandler(void) { static uint8_t num1=0, num2=0, num3=0, num4=0; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update); num4++; if (num4 > 9) { num4 = 0; num3++; if (num3 > 9) { num3 = 0; num2++; if (num2 > 9) { num2 = 0; num1++; if (num1 > 9) { num1 = 0; } } } } LED_Show(num1, num2, num3, num4); } } ``` 在这个示例代码中,我们定义了一个 LED 的引脚和端口,并且通过调用 GPIO_Init() 函数进行了初始化设置。然后,我们使用一个 while 循环来等待定时器中断,并且在定时器中断中依次显示数码管的数字。 以上是一个简单的数码管动态显示的示例代码,您可以根据需要进行修改。希望这个回答可以帮助您完成 STM32 数码管动态显示的实现。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值