STM32-基于标准外设库的LED流水灯
基于标准外设库的LED流水灯
创建工程项目
一. 下载固件库
下载地址:STM32F10x系列固件库,选择版本下载。
解压文件如下:
二、新建工程
-
新建Templete文件夹,如下所示:
-
把STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport目录下的core_cm3.c和core_cm3.h两个文件复制到文件夹Templete\Libraries\CMSIS目录下。
-
STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x路径下的4个文件复制到文件夹Templete\Libraries\CMSIS目录下,对于startup文件夹,只需要startup/arm路径下的文件,把该路径下的文件移动到startup文件夹下面,其余全部删掉
此时,Templete\Libraries\CMSIS文件夹包含文件如下:
Templete\Libraries\CMSIS\startup文件夹包含文件如下:
-
把固件库STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver下的inc和src两个文件夹复制到Templete\Libraries\STM32F10x_StdPeriph_Driver
-
把固件库STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template目录下的4个文件复制到Templete\User
至此,我们需要的文件就已经添加好了。
三、Keil配置
-
打开Keil,新建工程,工程保存在Project文件夹下面
-
选择芯片,这里我们选择STM32F103C8T6
-
新建如图的4个分组,然后添加文件
startup添加文件如下,三个文件都位于Templete\Libraries\CMSIS目录下
-
Driver文件夹里面添加所有外设的源文件,文件路径Templete\Libraries\STM32F10x_StdPeriph_Driver\src,源文件里面是ST写好的各个外设的驱动
-
User文件夹里面添加文件如下:
-
点击魔术棒,包含文件头路径
包含头文件路径如图:
-
对魔术棒所做的一些更改
-
因为 3.5 版本的库函数在配置和选择外设的时候通过宏定义来选择的,所以我们需要配置一个全局的宏定义变量。定位到魔术棒 c/c++界面,然后填写“STM32F10X_HD,USE_STDPERIPH_DRIVER”到 Define 输入框里面(请注意,两个标识符中间是逗号不是句号),这里解释一下,如果你用的是中容量那么STM32F10X_HD 修改为 STM32F10X_MD,小容量修改为 STM32F10X_LD,然后点击 OK。
STM32F10X_HD 宏:为了告诉 STM32 标准库,我们使用的芯片类型是大容量的,使 STM32标准库根据我们选定的芯片型号来配置。
USE_STDPERIPH_DRIVER 宏:为了让 stm32f10x.h 包含 stm32f10x_conf.h 这个头文件。 -
修改输出文件夹路径
把输出文件夹选择为我们创建的Output文件夹,顺便创建HEX文件勾选上,这样工程就能产生HEX文件。
-
到这里,工程就新建好了。
代码实现
本实验通过标准外设库的方式,使用GPIOA端口的PA0、PA1、PA2管脚分别控制一个LED灯轮流闪烁,间隔一秒。
代码如下:
#include "stm32f10x.h" // Device header
#include "Delay.h"
void GPIOA_Init() {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 使能GPIOA外设时钟,以便使用它
GPIO_InitTypeDef GPIO_InitStructure; // 创建一个GPIO_InitTypeDef结构体变量,用于配置GPIOA引脚的初始化参数
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 配置GPIOA的工作模式为推挽输出(GPIO_Mode_Out_PP)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; // 配置GPIOA的引脚为Pin 0、 Pin 1 Pin 2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置GPIOA的输出速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); // 使用上述的GPIO_InitStructure配置GPIOA引脚
}
int main(void)
{
GPIOA_Init();
while (1)
{
GPIO_SetBits(GPIOA, GPIO_Pin_0); // 在GPIOA的引脚0上设置高电平(点亮LED等操作)
Delay_ms(1000); // 延时1秒
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 在GPIOA的引脚0上设置低电平(熄灭LED等操作)
GPIO_SetBits(GPIOA, GPIO_Pin_1); // 在GPIOA的引脚1上设置高电平(点亮LED等操作)
Delay_ms(1000); // 延时1秒
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // 在GPIOA的引脚1上设置低电平(熄灭LED等操作)
GPIO_SetBits(GPIOA, GPIO_Pin_2); // 在GPIOA的引脚2上设置高电平(点亮LED等操作)
Delay_ms(1000); // 延时1秒
GPIO_ResetBits(GPIOA, GPIO_Pin_2); // 在GPIOA的引脚2上设置低电平(熄灭LED等操作)
}
}
实际效果如下:
仿真逻辑分析仪观察时序波形
打开Keil的仿真逻辑分析仪,并运行代码,观察PA0、PA1、PA23个端口的波形变化。
通过观察,某个端口的灯点亮时,该端口处于高电平,持续1s后,转为低电平,灯随之熄灭,同时下一个端口转入高电平,如此循环往复。