【STM32】(一看就会)GPIO口输出---跑马灯实验(标准库)

前言:

本文详细的介绍了IO口的输出模式,并简单进行了跑马灯实验。本文使用的是STM32F103C8T6芯片,其他芯片的原理是相同的,可以在本实验的基础上进行修改。

本文需要有创建好的STM32F103C8T6的工程文件

如有需要可以从下方连接下载:
链接: https://pan.baidu.com/s/1Lmjp-e6ifl-AfZmAfuRxrQ 提取码: vk7y 

一、理论知识介绍

GPIO的输出模式共计四种推挽输出、开漏输出、复用推挽输出、复用开漏输出

1.1推挽输出

英文是Push-Pull Output(Output PP)

推挽输出模式是最常用的GPIO输出模式。在该模式下,引脚可以输出高电平或低电平,同时具有一定的驱动能力可以驱动外部电路

特点:可以输出高电平和低电平,具有一定的驱动能力。

应用场景:用于驱动外部电路,如控制LED灯、驱动其他逻辑电路等。

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;     // 推挽输出模式

1.2开漏输出

英文是Open-Drain Output(Output OD)

在该模式下,引脚只能输出低电平,要输出高电平需要通过外部上拉电阻或其他方式。常用于与外部器件连接,例如与开漏输出的I2C总线器件进行通信。

特点:只能输出低电平,需要外部上拉电阻将引脚拉高;具有一定的驱动能力。

应用场景:与外部器件连接时,如I2C总线,用于与其他设备进行通信。

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;  //开漏输出模式

1.3复用推挽输出

英文是AF Push-Pull Output(AF PP)

复用推挽输出模式允许将GPIO引脚用作特定外设功能。在该模式下,引脚可以输出高电平或低电平,并具有一定的驱动能力。

特点:具有推挽输出的特性,可用于将GPIO引脚用作特定外设的功能。

应用场景:连接到外设的特殊功能引脚,如UART串口通信引脚、PWM输出等。

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;          // 复用推挽输出模式

1.4复用开漏输出

英文是AF Open-Drain Output(AF OD)

复用开漏输出模式允许将GPIO引脚用作特定外设功能。在该模式下,引脚只能输出低电平,要输出高电平需要通过外部上拉电阻或其他方式。

特点:具有开漏输出的特性,可用于将GPIO引脚用作特定外设的功能。

应用场景:连接到外设的特殊功能引脚,如I2C总线通信引脚、故障信号输出等。

GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;          // 复用开漏输出模式

以上就是四种GPIO输出模式的介绍,本文控制LED灯亮灭使用推挽输出模式

二、硬件连接

STM32F103C8T36--->PA0----PA7依次连接八个LED灯,LED灯的引脚一端连接IO口,LED灯的引脚另一端接地。

三、软件编写

打开工程文件(如有需要在文章开头下载

3.1创建函数文件夹

本文使用定义库函数来进行编程,将会新建一个Hardwear文件夹用来存放LED显示函数,在主函数中直接调用定义的函数即可实现LED的亮灭。(也可以直接将函数定义到主函数中,但要进行部分修改)

首先打开工程文件所在的文件夹,创建"Hardwear"文件夹。

然后打开KILE5软件,点击“三个方块”,打开文件管理界面,在工程中新建“Hardwear”文件夹。

点击OK后再左侧工程文件管理处就显示了Hardwear文件夹。

然后要添加文件夹路径,让工程文件可以找到文件夹的地址。(这步前往别忘了)

依次点击"魔法棒"-->"C/C++"-->"..."即可添加文件路径了

添加之后如下图所示

然后添加LED.c和LEC.h文件

首先右键Hardwear文件夹”再点击“Add New item to Group “Hardwear” ”

弹出以下界面,先选择创建“.C”文件创建“LED.c”,再选择创建"LED.h“文件,创建"led.h”

要在工程文件夹中看一下LED.c与LED.h是否创建到了Hardwear文件夹,要确保LED.c和LED.h必须在Hardwera文件夹中。

创建函数文件夹就完成了(千万不要漏掉哪一步,不然就无法运行了)

3.2编写"LED.c"文件
 

首先在最上方引入标准库

#include "stm32f10x.h"                  // Device header

在LED.c中,先创建LED初始化函数(LED_Init),对PA0到PA7的引脚进行初始化

这是整体的代码,再下面进行解读

void LED_Init(void)
{	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	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_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

解读:

首先对RCC_APB2时钟进行启用

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

然后对GPIO口的参数进行定义

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
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_Speed = GPIO_Speed_50MHz;

最后对GPIO进行初始化

	GPIO_Init(GPIOA, &GPIO_InitStructure);

完成LED_Init函数的编写

在LED.c中,创建LED发光函数(LED_On),用来点亮LED。

void LED_On(int LED)
{
	GPIO_WriteBit(GPIOA,LED,Bit_SET);
	
}

在LED.c中,创建LED发光函数(LED_Off,用来熄灭LED。

void LED_Off(int LED)
{
	GPIO_WriteBit(GPIOA,LED,Bit_RESET);
	
}

完成对LED.c文件的配置

LED.c完整的代码如下

#include "stm32f10x.h"                  // Device header



void LED_Init(void)//LED初始化
{	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	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_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void LED_On(int LED)//LED亮
{
	GPIO_WriteBit(GPIOA,LED,Bit_SET);
	
}
void LED_Off(int LED)//LED灭
{
	GPIO_WriteBit(GPIOA,LED,Bit_RESET);
	
}

3.3编写"LED.h"文件

LED.h主要进行函数的声明,代码如下

#ifndef LED_H
#define LED_H

//函数声明
void LED_Init(void);
void LED_On(int LED);
void LED_Off(int LED);

#endif

3.4"main.c"文件的编写

想实现跑马灯效果,直接让LED灯依次亮灭即可。

首先在main.c文件中引入"LED.h”的头文件

#include "LED.h"

再进行LED初始化,调用LED_Init();函数

LED_Init();

再进行效果编写,完整代码如下

#include "stm32f10x.h"                  // Device header
#include "LED.h"

int main(void)
{
	LED_Init();
	int i =0;
	while (1)
	{
		
		LED_On(0);
		i =1000;
		while(i--);
		LED_Off(0);
		
		LED_On(1);
		i =1000;
		while(i--);
		LED_Off(1);
		
		LED_On(2);
		i =1000;
		while(i--);
		LED_Off(2);
		
		LED_On(3);
		i =1000;
		while(i--);
		LED_Off(3);
		
		LED_On(4);
		i =1000;
		while(i--);
		LED_Off(4);
		
		LED_On(2);
		i =1000;
		while(i--);
		LED_Off(5);
		
		LED_On(6);
		i =1000;
		while(i--);
		LED_Off(6);
		
		LED_On(7);
		i =1000;
		while(i--);
		LED_Off(7);

		
	}
}

因为本文没有定义延时函数,就使用while(i--)进行了简单的延时,如果需要进行精确的延时的话要定义正确的延时函数来进行延时

本文完--

以下是本文的例程文件,有需要可以下载
链接: https://pan.baidu.com/s/1v-xm7Paj1WEc_GfgF7npag 提取码: ef5w 
 

  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值