stm32入门-----GPIO口输出的学习与使用(下)

 目录

前言

一、创建工程

二、时钟和GPIO口

1.RCC时钟

2.GPIO引脚

3.void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

4.void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

5.void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

三、项目实践

1.实现一个LED呼吸灯

2.实现LED流水灯

3.控制蜂鸣器响应


前言

        本期紧接着上一期的内容,是对上一期的理论进行代码编写操作,也是对GPIO口进行输出功能的实践,本期分为三个项目,分别是一个LED呼吸灯,8个LED流水灯、控制蜂鸣器的响应。(本文章内容是跟着江大科协一起做的,对应的视频内容:[3-2] LED闪烁&LED流水灯&蜂鸣器_哔哩哔哩_bilibili

一、创建工程

相较于51单片机,stm32创建工程相对比较麻烦的,细节是比较多的,因为不想51那样创建好了工程就可以去之间写代码了,stm32的需要引入相关文件,也就是前置文件。不过总体上还是差不多的。

 老规矩,打开keil5新建工程,选择芯片。这里学过51的就不多说了,stm32也是一样的。

下面这个点击叉掉就行了

然后就是打开你这个工程文件的根目录下,然后去创建三个文件夹,分别是:user、start、library

然后就是去找固键库里面的文件复制粘贴进去,详细可看这里(STM32的工程模版创建(保姆级教程)_stm32工程模板-CSDN博客

不过我这里的话就已经提前准备好了这三个文件夹里面的文件了,这里我会上传到本期的资源绑定上,你们可以去直接下载拿过来复制粘贴到你这个工程上就行了,到时候就不需要这么麻烦。解压后如下图:

然后就是点击这里

然后就在Groups这里去添加这三个文件夹到本工程上,注意user最好放到最下面,方便去使用。

添加好了文件夹之后,就点击右边去添加相关的文件,比如我这里是给start这个文件夹去添加文件,那我下面这里就点击进入到start这个文件夹里面,然后选择全部(包括.c和.h文件),去添加就行了。

结果如下图,添加完成:

其他两个也是一样的,直接去添加就行了。

最后添加完成了,你会看到这个工程的左边会出现上面你添加好了的文件夹

 还没完这里,点击魔术棒,然后选到C/C++这里。

 然后点击这里

 然后就是点击下面箭头指向的位置,把这三个文件夹添加上去就行了。

 后面回到原来的界面箭头指向的位置去填入USE_STDPERIPH_DRIVER,最后点击OK就行了。

不过到这里还没完,前置文件是添加好了,还有就是去设置keil5的环境。

 

老规矩,点击魔术棒。

然后点击下面箭头指向的位置,第一点击Debug,第二选择ST-Link Debugger。

再然后就点击旁边的Setting

进去之后点击 Debug,就按照下面箭头指向的位置选择即可。

最后一步就是点击Flash Download,然后勾选Reset and Run,就每次下载到stm32单片机后就继续复位操作。

 最后就是点击确定,点击OK就行了,没毛病。工程创建完成。

二、时钟和GPIO口

(下面相关内容来自:STM32标准库常用函数的使用和代码说明_stm32标准库函数手册-CSDN博客)本期引用了要用的函数进行解释说明,详细可查阅链接的内容或者去查看手册。

1.RCC时钟

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

RCC APB2外设时钟控制,使能或者失能APB2外设时钟。

功能: 

  • 第一个参数选择外设,下图是可选择的外设。
  • 第二个参数使能或使能。

在STM32中,所有的GPIO都是挂载在APB2外设总线上的,所以要给PA0端口低电平点亮LED,需要给RCC_APB2外设时钟使能,第一个参数就选择RCC_APB2Periph_GPIOA,第二个参数为ENABLE。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);		
//将APB2总线上挂着的外设GPIOA时钟打开

 RCC时钟不止这一个,其他我这里就没去讲了,不过一般情况下用到的RCC时钟也就只有三个。

2.GPIO引脚

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
这个函数的作用是,用结构体的参数来初始化GPIO口。

我们需要先定义一个结构体变量,然后再给结构体赋值,最后调用这个函数,这个函数内部就会自动读取结构体的值,然后自动把外设的各个参数配置好。

第一个参数是要初始化的GPIO口,第二个参数是一个结构体。

	GPIO_InitTypeDef GPIO_InitStructure;                //定义结构体变量
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //GPIO模式选择
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;           //GPIO引脚选择
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //GPIO传输速度选择
	GPIO_Init(GPIOA, &GPIO_InitStructure);              //调用Init函数

这里的结构体就是一个数据打包的过程,首先将参数写到结构体的三个变量里,然后统一打包,将结构体传递到初始化函数里,接着在初始化函数里面,再把这个结构体拆包出来,读取变量,这就是使用结构体的整个过程。

第一行中GPIO_InitTypeDef是结构体的类型,GPIO_InitStructure是结构体的名字,这里结构体实际上也是一种局部变量。

在第二行,复制结构体名字,然后用“.”把结构体的成员都引出来;

通过在GPIO_Mode右键跳转,可以看到参数说明,在参数GPIOMode_TypeDef选中,Ctrl+F搜索一下,就能看到GPIO的8种工作模式,这里我们选择GPIO_Mode_Out_PP推挽输出模式。

  GPIO_Mode_AIN = 0x0,                //模拟输入
  GPIO_Mode_IN_FLOATING = 0x04,       //浮空输入
  GPIO_Mode_IPD = 0x28,               //下拉输入
  GPIO_Mode_IPU = 0x48,               //上拉输入
  GPIO_Mode_Out_OD = 0x14,            //开漏输出
  GPIO_Mode_Out_PP = 0x10,            //推挽输出
  GPIO_Mode_AF_OD = 0x1C,             //复用开漏
  GPIO_Mode_AF_PP = 0x18              //复用推挽

第三行引脚选择,通过在GPIO_Pin右键跳转,在选中GPIO_pins_define 参数处Ctrl+F搜索,就能找到引脚定义,这里我们用的是GPIOA外设的0号引脚,所以选择GPIO_Pin_0。

 第四行同理,能找到引脚的输出速度定义,这里我们选则50MHz即可。

第5行就是调用GPIO_Init函数,然后第一个参数写GPIOA,然后GPIO初始化结构体的地址放到GPIO_Init的第二个参数,这样初始化就完成了,GPIO_Init函数执行完,这个GPIOA外设的0号引脚就自动被配置为推挽输出,50MHz的速度了。接下来就可以使用GPIO的这些输入输出函数了。

3.void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

这个函数可以把指定的端口设置为高电平。

第一个参数是GPIOx,第二个参数是GPIO_Pin。

GPIO_SetBits(GPIOA, GPIO_Pin_0);						
//将PA0口设置为高电平

4.void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

这个函数可以把指定的端口设置为低电平。

第一个参数是GPIOx,第二个参数是GPIO_Pin。

GPIO_ResetBits(GPIOA, GPIO_Pin_0);			
//将PA0口设置为低电平

5.void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

前两个参数都是指定端口,第三个参数是BitVal,根据第三个参数的值来设置指定端口。

第三个参数:

Bit_RESET:清除端口值,也就是置低电平;

Bit_SET:设置端口值,也就是置高电平。

GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);		
//给GPIOA中的0号引脚写入低电平(点亮LED)

想了解具体底层的话可自己查阅手册。 下面要用到的就是上面这些内容了。

三、项目实践

1.实现一个LED呼吸灯

这里的话要用到延时函数,所以这里需要在根目录下去创建一个system文件夹,然后把延时函数的文件跟导入进去。

然后同样的操作,在工程导入这个system文件夹。

 面包板上的连线图:

 main.c代码:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{	

	//设置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//定义结构体
	GPIO_InitTypeDef GPIO_initstruct;  
	
	//配置结构体的输入输出方式 8种之一
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出模式,高低电平都可以输出来,且有效
	
	//配置选定的引脚IO口
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_0;
	
	//设置频率 多少hz
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	//把上面定义好的结构体地址带入进行初始化设置 指定到GPIOA 口
	GPIO_Init(GPIOA,&GPIO_initstruct);

    /*
	说明:
	GPIO_WriteBit(GPIOA, GPIO_Pin_0,Bit_RESET);与GPIO_WriteBit(GPIOA, GPIO_Pin_0,Bit_SET);是一一对应的
	GPIO_ResetBits(GPIOA, GPIO_Pin_0);与GPIO_SetBits(GPIOA, GPIO_Pin_0);也是一一对应的
	上面两个前者是控制输出低电平,后者是控制输出高电平,效果是一样的
	*/
	
	while(1){
		//点亮LED,低电平亮
		//GPIO_WriteBit(GPIOA, GPIO_Pin_0,Bit_RESET);
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);
		Delay_ms(100); //延时100毫秒
		
		//熄灭LED
		//GPIO_WriteBit(GPIOA, GPIO_Pin_0,Bit_SET);
		GPIO_SetBits(GPIOA, GPIO_Pin_0);
		Delay_ms(100);//延时100毫秒
	}
}


2.实现LED流水灯

 面包板上的连线图:

 这里我选择的是GPIOA 口 0~7的引脚,其对应的位置下图所示: 

 main.c代码:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{	

	//打开GPIO指定的端口,这里打开GPIOA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	
	GPIO_InitTypeDef GPIO_initstruct;  //定义结构体
	
	//配置结构体的输入输出方式 8种之一
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出模式,高低电平都可以输出来,且有效
	
	//配置选定的引脚IO口
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_All ;
	//设置频率 多少hz
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	//把上面定义好的结构体地址带入进行初始化设置 指定到GPIO A 口
	GPIO_Init(GPIOA,&GPIO_initstruct);
	
	while(1){
		//点亮LED,低电平亮
		GPIO_Write(GPIOA,~0x0001);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0002);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0004);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0008);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0010);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0020);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0040);
		Delay_ms(200);
		GPIO_Write(GPIOA,~0x0080);
		Delay_ms(200);
	}
}


3.控制蜂鸣器响应

 面包板上的连线图:

这里要用到无源蜂鸣器模块 ,相关介绍如下。

无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音

 main.c代码:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{	

	//打开GPIO指定的端口,这里打开GPIOA的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	
	GPIO_InitTypeDef GPIO_initstruct;  //先定义结构体
	
	//配置结构体的输入输出方式 8种之一
	GPIO_initstruct.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出模式,高低电平都可以输出来,且有效
	
	//配置选定的引脚IO口
	GPIO_initstruct.GPIO_Pin=GPIO_Pin_12 ;
	//设置频率 多少hz
	GPIO_initstruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	//把上面定义好的结构体地址带入进行初始化设置 指定到GPIOB 口
	GPIO_Init(GPIOB,&GPIO_initstruct);

	while(1){
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(100);
		GPIO_SetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(100);
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(100);
		GPIO_SetBits(GPIOB, GPIO_Pin_12);
		Delay_ms(700);
	}
}

以上就是本期的全部内容了,我们下次见!

每日壁纸:

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 10:24:07       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 10:24:07       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 10:24:07       57 阅读
  4. Python语言-面向对象

    2024-07-16 10:24:07       68 阅读

热门阅读

  1. 抽象工厂模式与工厂方法(简单工厂)的区别

    2024-07-16 10:24:07       25 阅读
  2. 力扣第八题——字符串转换整数

    2024-07-16 10:24:07       25 阅读
  3. OutOfMemoryError异常OOM排查

    2024-07-16 10:24:07       21 阅读
  4. leetcode热题100.最长递增子序列(动态规划大成)

    2024-07-16 10:24:07       22 阅读
  5. RK3568 安卓12 EC20模块NOCONN没有ip的问题(已解决)

    2024-07-16 10:24:07       22 阅读