[STM32从0开始]GPIO基本输入输出初步认识,从0开始点亮LED灯,简单详细

//如果你是新手,请按时间顺序查看我的[STM32从0开始]文章,跟着我的步骤入门,因为我也是新手,这是我写给我自己的新手向入门教程,阅读本问需要C语言基础

工程创建

如果你是新手,请从工程创建这一片博文开始看[STM32从0开始]STM32F10x系列工程创建 ,在这里,我们直接复制之前创建并备份的原工程。

GPIO的基本知识

STM32单片机的基本输入输出大致可分为开漏和推挽两种模式,开楼又因涉及到上拉电阻,又可细分为强上拉与弱上拉,按照手册上的描述,推挽模式0激活N管,1激活P管,而开漏0与推挽是一样的,区别在于开漏1的时候是高阻态,P管不会被激活,请各位根据自己的单片机查看对应手册。

我们的目的主要是了解输出部分的代码,所以我们主要看输出部分,更详细的原理这里不再赘述。

开漏本身是无法输出逻辑高电频的,如果需要开漏模式点亮led需要外接一个上拉电阻

按照我的理解简单来说,如果使用推挽模式点亮led灯,可直接连接,否则需要增加一个电阻。关于这方面我不是很理解,如果有错请大佬纠正。

推挽控制LED灯,LED文件编写

将GPIO设置成推挽的方式,在任意IO口连接上任意数量的LED灯,我们将学习如何初始化并控制其亮灭。

在工具栏点击该图标或者按住Ctrl+N创建新的文件,点击保存按钮或者使用Ctrl+S保存文件并命名为led.c与led.h,将其存在工程的User目录下。

在工程左侧右键单击User文件夹,选择Add Existing...将刚刚创建的led.c文件导入到工程中,

双击打开编辑led.c,加入头文件

#include "stm32f10x.h"
#include "led.h"

创建LED灯初始化函数

void LED_Init(void)
{
	
}

STM32是一款非常强大的芯片,大部分功能默认是关闭的以便于节省功耗,所以我们需要打开相应的时钟阀门以使得需要的功能正常运行,通过stm32f10x_rcc.c中的我们可以看到,如果我们想要使用GPIOA~G,就需要使用RCC_APB2PeriphClockCmd来开启相应的时钟阀门。

为了方便大家理解,我这里使用3个led灯,分别放置在ABC3组,其中C组是最小系统板板载LED灯PC13,我们初始化GPIOA、GPIOB、GPIOC的时钟阀门为开启。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| \
	RCC_APB2Periph_GPIOB| \
	RCC_APB2Periph_GPIOC,ENABLE);

对led的操作本质上是对GPIO的操作,在基础库中找到相应的函数即可 stm32f10x_gpio.c,可以看到GPIO函数需要两个参数,一个是GPIO的所属分组,一个是结构体,GPIO的模式配置,包括引脚、模式、频率三个部分。

根据需要,我们初始化GPIOA、GPIOB、GPIOC的具体引脚,为了方便大家少走弯路,我这里初始化每个组的所有引脚。

下表为你可以操作的所有引脚,每组16个,在复杂的工程中要考虑端口复用的问题,这里不需要。

这个引脚怎么来的呢?在上图中的注释中有@ref样式,说明你可以通过搜索搜索到相对应的资源,按Ctrl+F调出搜索,搜索GPIO_pins_define,即可得到下图。

同理,结构体中所需要的其他数据也可通过搜索得到。下图为mode表与speed表,参数具体含义请自行百度,这里调用推挽输出模式,最高速度。

结构体完整配置如下

	GPIO_InitTypeDef GPIO_InitType; //GPIO配置结构体声明
	GPIO_InitType.GPIO_Mode = GPIO_Mode_Out_PP;//设置为输出模式
	GPIO_InitType.GPIO_Pin = GPIO_Pin_All;//所有引脚
	GPIO_InitType.GPIO_Speed = GPIO_Speed_50MHz;//最高速度
	

在配置完成后,我们需要将其初始化,提交给初始化函数让系统知道我们要什么模式。还记得这张图吗?可以看到我们需要的两个参数都已经整理完毕。


	GPIO_Init(GPIOA,&GPIO_InitType);
	GPIO_Init(GPIOB,&GPIO_InitType);
	GPIO_Init(GPIOC,&GPIO_InitType);

到此,LED初始化完成,在STM32中,1高电平熄灭,0低电平点亮,我是将led灯正级接到3.3,负极接io口的。如果你要初始化状态灯全灭请在初始化函数最后加入。

	GPIO_SetBits(GPIOA,GPIO_Pin_All);
	GPIO_SetBits(GPIOB,GPIO_Pin_All);
	GPIO_SetBits(GPIOC,GPIO_Pin_All);

led.c完整初始化代码

#include "stm32f10x.h"
#include "led.h"

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| \
	RCC_APB2Periph_GPIOB| \
	RCC_APB2Periph_GPIOC,ENABLE); //开启GPIO分组的时钟阀门
	
	GPIO_InitTypeDef GPIO_InitType; //GPIO配置结构体声明
	GPIO_InitType.GPIO_Mode = GPIO_Mode_Out_PP;//设置为输出模式
	GPIO_InitType.GPIO_Pin = GPIO_Pin_All;//所有引脚
	GPIO_InitType.GPIO_Speed = GPIO_Speed_50MHz;//最高速度
	
	//初始化组A、B、C所有引脚为输出模式
	GPIO_Init(GPIOA,&GPIO_InitType);
	GPIO_Init(GPIOB,&GPIO_InitType);
	GPIO_Init(GPIOC,&GPIO_InitType);
	
	//默认关闭LED灯
	GPIO_SetBits(GPIOA,GPIO_Pin_All);
	GPIO_SetBits(GPIOB,GPIO_Pin_All);
	GPIO_SetBits(GPIOC,GPIO_Pin_All);
}

为了在main.c中能正常调用,请在led.h文件中填入以下代码

#ifndef __LED_H
#define __LED_H

#endif

void LED_Init(void);

推挽控制LED灯,MAIN文件编写

C语言运行是从main函数开始的,你的main函数所在的.c文件无论是什么名字都是主文件,一个程序只能有一个main函数。

在main函数中如果想使用别的文件的函数,需要他在.h文件中有声明,就像我们刚刚的led.h一样,将其引用到main中

#include "stm32f10x.h"
#include "led.h"

要做闪烁效果,我们还需要自己编写一个延时函数

void delay(int t)
{
	int i;
	while(t--)
	{
		for(i=0;i<120;i++);
	}
}

在main中初始化调用LED初始化函数,系统时钟默认初始化函数

RCC_DeInit();
LED_Init();

在main.c中完整代码如下。其中if之内的函数是系统自带的库函数,功能是对led灯进行翻转,如果亮就灭,如果灭就亮,每隔一段时间判断一次,以达到闪烁效果。

#include "stm32f10x.h"
#include "led.h"


void delay(int t)
{
	int i;
	while(t--)
	{
		for(i=0;i<120;i++);
	}
}

int main()
{
	RCC_DeInit();
	LED_Init();

	while(1)
	{
		if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_All))
		{
			GPIO_ResetBits(GPIOB,GPIO_Pin_All);
      GPIO_ResetBits(GPIOA,GPIO_Pin_All);
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
		}
		else
		{
			GPIO_SetBits(GPIOB,GPIO_Pin_All);
      GPIO_ResetBits(GPIOA,GPIO_Pin_All);
			GPIO_SetBits(GPIOC,GPIO_Pin_13);
		}
		delay(555);
	}
}

最后

如果你看到了这里,恭喜你耐下心来看了3000多字,有人可能觉得话多又麻烦,我这个是自己记录学习历程并分享给仅有C语言的0单片机基础的人的,尽量做到每一步都详细且简单,到这里初步入门了STM32GPIO操作篇,本来想写个按钮控制的,但是身边没有按钮用,而且按钮也很简单,同样的初始化步骤,将io口输出改为输入罢了,不管是hal库还是什么,都可以在基库中找到类似的文件,这篇文章所用到的有stm32f10x_rcc.c、stm32f10x_gpio.c,所用到的函数都有具体且详细的注释解释,有良好的C语言基础基本只要理清他们的关系就会一通百通。

如果你是看我的文章从0开始,那么恭喜你迈出了从0到1的第一步,下一篇我将加上按钮,写按钮控制LED灯的基本写法。

红GPIOA、绿GPIOB、板载GPIOC。灯长正短负。

多用脑,多思考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Azhuo9527

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

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

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

打赏作者

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

抵扣说明:

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

余额充值