目录
首言
对于stm32的操作,通常有寄存器、标准库、HAL库三种编译方式,在本文主要就是借用点灯这一实例,展示标准库是如何让GPIO工作起来的。
一、装配标准库
下载标准库
下载地址:
链接: STM32 Standard Peripheral Libraries - STMicroelectronics
STM32F103标准库模板:
STM32工程文件夹主要包含以下几个文件夹:
- Library: 放置库文件,包含驱动程序和算法等。提供运行需要的驱动程序支持。
- Listings: 放置汇编列表文件(.lst)。这些文件记录了编译过程中产生的汇编代码。
- Objects: 放置目标文件(.o文件),这些文件是编译源代码(.c文件)后的结果,包含机器码等。
- Start: 放置启动文件startup_stm32f10x_xx.s,包含系统时钟配置、堆栈设置、中断向量表等初始化代码。
- User: 用户代码文件夹,放置用户自己编写的源代码(.c文件)。
- 其中:
- Listings和Objects是编译过程中的中间文件。
- Startup文件负责系统初始化。
- User文件夹放用户应用程序源代码。
接下来就是将这些文件配置进入工程
首先将工程文件夹里面的文件全部导入工程,全部的.c和.h文件
接着点击魔术棒,导入文件夹路径
二、操作stm32的GPIO口的步骤
1.使用RCC开启GPIO时钟
2.使用GPIO_Init函数初始化GPIO口
3.使用输入输出的函数控制GPIO口
给指定端口给定想要的高低电平,本文采用高电平熄灭、低电平点亮的模式。
三、相关库函数说明
1.gcc相关函数
因为本文需要点亮LED灯,因此我们只需要借助GPIOx端口进行输出高低电平,因此需要开启APB2 时钟,语法如下:
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
第一个参数是选择输出端口,通常为GPIOA、GPIOB等,第二个参数是选择状态,使能(ENABLE)和失能(DISABLE)二选一
2.GPIO_Init函数
GPIO_Init的语法为:
GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
在使用时需要端口和初始化结构体,因此在使用该函数之前,需要先定义一个结构体。
3.GPIO输出函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//把指定端口的引脚设置为高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//把指定端口的引脚设置为低电平
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//对指定端口的引脚进行写入操作
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//对指定端口的16个引脚同时进行写入操作
四、编写代码,点亮led
1.开启RCC时钟
本文需要使用的引脚为PA0-15,因此需要开启APB2的外设使能时钟,如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2.初始化GPIO口
(1)定义结构体
结构体的类型为:GPIO_InitTypeDef
该结构体的成员有三个,分别为:GPIO_Pin、GPIO_Speed、GPIO_Mode。
GPIO_Mode为GPIO工作的模式,共八种,如下所示:
typedef enum
{ 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//复用推挽输出
}GPIOMode_TypeDef;
GPIO_Pin为我们选择的引脚,按照格式选择相应引脚即可,如下:
GPIO_Speed为输出速率,具体如下:
本文具体创建的结构体代码如下:
GPIO_InitTypeDef GPIOA_Initleds;
GPIOA_Initleds.GPIO_Mode =GPIO_Mode_Out_PP;//推挽输出模式
GPIOA_Initleds.GPIO_Pin =GPIO_Pin_All;//输出引脚为PA0-15全部作为输出端口
GPIOA_Initleds.GPIO_Speed =GPIO_Speed_50MHz;//输出速率为50MHz
(2) 使用GPIO_Init函数
GPIO_Init (GPIOA,&GPIOA_Initleds);//&是取地址的意思
3.点亮LED灯
因为本文是直接对PA0的8个端口进行灯的亮灭操作,因此本文选用的是GPIO_Write函数
(1)延时函数
本文因为延时函数比较常用,将延时函数做成了Delay.h的头文件,其中.C文件代码内容具体如下:
#include "stm32f10x.h"
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
本文的题目要求是需要亮灭间隔1秒,因此直接调用Delay_s即可
具体代码如下:
Delay_s(1);
(3)设定灯的亮灭
本文因为要使8个引脚的灯按规律亮灭,如果使用GPIO_Bits和GPIO_Rebits需要重复写八次,代码内容繁多,因此本文直接使用GPIO_Write函数对十六个端口进行写入操作,同时借用循环移位操作,每次向左移位一次,实现灯的亮灭转换,具体的代码如下:
for (i=0;i<=7;i++)
{
GPIO_Write(GPIOA,~(0X0001<<i));//0000 0000 0000 0001取反
Delay_s(1);
if (i==8)i=0;
}
4.完整代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//初始化GPIO口
GPIO_InitTypeDef GPIOA_Initleds;
GPIOA_Initleds.GPIO_Mode =GPIO_Mode_Out_PP;//推挽输出模式
GPIOA_Initleds.GPIO_Pin =GPIO_Pin_All;//输出引脚为PA0-15全部作为输出端口
GPIOA_Initleds.GPIO_Speed =GPIO_Speed_50MHz;//输出速率为50MHz
GPIO_Init (GPIOA,&GPIOA_Initleds);//&是取地址的意思
while (1)
{
int i;
for (i=0;i<=7;i++)
{
GPIO_Write(GPIOA,~(0X0001<<i));//0000 0000 0000 0001取反
Delay_s(1);
if (i==8)i=0;
}
}
}
五、检验效果
1.时序波形
首先设置debug
接下来再点击debug,进行引脚设置
最后点击 全速运行程序,即可输出波形
由波形可以看出,PA0-7的引脚能够依次实现亮灭
2.烧录结果
由于本文将拍摄的视频转为gif格式,看出来的有延时,间隔比1s大了,但是实际是烧录情况是非常完美的
六、总结
- 配置GPIO引脚:首先,需要配置微控制器的GPIO引脚,以便将LED连接到适当的引脚上。这可以通过在STM32CubeMX中配置引脚映射来实现。在配置过程中,需要为LED选择一个适当的GPIO引脚,并确保将正确的端口和引脚号映射到该引脚。
- 初始化GPIO库:在Keil中,需要编写初始化代码来启用GPIO库,并设置GPIO引脚的模式为输出模式。这可以通过调用HAL库函数来完成。例如,使用STM32CubeMX生成的初始化代码中通常会包括以下内容:
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
其中,GPIOA
是端口名称,GPIO_InitStruct
是一个结构体,包含了引脚配置信息。
- 点亮LED:一旦GPIO库初始化完成,可以使用标准库函数来控制LED的亮度。在大多数情况下,这意味着将GPIO引脚的值设置为高电平(HIGH)以点亮LED。例如,使用STM32CubeMX生成的代码中通常会包括以下内容:
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
其中,GPIOA
是端口名称,GPIO_PIN_1
是LED连接到的引脚号,GPIO_PIN_SET
表示将引脚设置为高电平状态。
- 编译和调试:最后,使用Keil编译器将源代码编译成可执行文件,并使用调试器进行调试。可以在Keil的仿真器中模拟LED的行为,以确保代码正常工作。
七、参考
https://www.bilibili.com/video/BV1th411z7sn?p=6&vd_source=282ea78ce81b7a1817b467d1df493b2a