(一)建立基于固件库的STM32工程
1.新建STM32文件夹
(1)首先,建立一个STM32工程文件夹
(2)在工程文件夹中新建立以下3个文件
(3)去STM32官网下载STM32标准外设软件库——官方下载地址:https://www.st.com/zh/embedded-software/stm32-standard-peripheral-libraries.html进去之后,我的单片机版本是STM32F103C8T6,所以我选择并且点击图中的F1
然后选择版本、下载、解压
可以得到包含许多文件的一个文件夹
(4)打开刚才下载的标准库文件,将startup 中的启动文件、内核寄存器描述、外设寄存器文件复制到工程Start文件夹中
(5)将外设库的inc、src文件夹里面的文件复制到Library文件夹下
(6)将存放中断函数的文件复制到工程文件的User下面
2.新建STM32工程
(1)打开keil5,点击Project,点击新建Keil工程
(2)工程目录选择我们新建的Project文件夹,取一个工程名字
(3)在弹出固件选择框,选择我们用的那一款芯片型号,点OK
(4)弹出如下框(提示用不用软件自带的库),不用理会,直接关掉
(5)点击Target1,选择Manage Project items……
(6)点击第一步进行添加文件;点击第二步进行取文件名字;最后点击OK
(7)双击刚刚建立的文件,分别按照如下图所示进行添加.c文件
(8)点击魔法棒,接着点击C/C++,在Define中添加宏定义USE_STDPERIPH_DRIVER或者STM32F10X_MD,USE_STDPERIPH_DRIVER
再次点击进行添加头文件.h路径
(9)为了及时清除编译时产生的不需要信息,还可以直接添加keilkill.bat文件
至此,基于固件库的STM32工程文件夹正式创建完毕!!!
(二)编写基于固件库LED流水灯工程代码
1. GPIO初始化
(1)GPIO固件库工作模式,本次实验选择的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;
输入模式:上拉和下拉输入的电平由上拉或者下拉,浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于 ADC 采集。
输出模式:推挽模式时双 MOS 管以轮流方式工作,输出数据寄存器 GPIOx_ODR可控制 I/O 输出高低电平。开漏模式时,只有 N-MOS 管工作,输出数据寄存器可控制 I/O输出高阻态或低电平。
(2)本次选用GPIOA——>PA0,PA1,PA2,对这三个GPIO口进行固件库方式初始化与配置
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
2.编写程序文件
(1)编写main.c文件
双击打开左边之前创建并导入的main.c文件
在main.c里面编写如下代码:
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
while (1)
{
GPIO_Write(GPIOA, ~0x0001); //0000 0000 0000 0001
Delay_ms(1000);
GPIO_Write(GPIOA, ~0x0002); //0000 0000 0000 0010
Delay_ms(1000);
GPIO_Write(GPIOA, ~0x0004); //0000 0000 0000 0100
Delay_ms(1000);
}
}
(2)编写延时函数
点击新建空文档来进行编写Delay.h与Delay.c,并且保存在之前所创建的用于储存项目的文件里的User里面,去文件名字的时候,一定不要遗漏.c与.h后缀,负责就不是C文件与头文件h了
Delay.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);
}
}
Delay.h
#ifndef __DELAY_H
#define __DELAY_H
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);
#endif
(3)将刚刚编写的两个.c和.h文件包含在本工程中
(三)STM32固件库流水灯程序的实验与仿真
1.烧录实验
(1)电路连接
PA0——黄灯、PA1——红灯、PA2—— 绿灯
链接实物图
(2)ST-link配置
(3)编译烧录
(4)结果展示
VID_20231015_225718
2.仿真实验
(1)进入keil仿真
第一步
配置仿真实验条件:首先应该选择Use Simulator,其次是Run to main()选项打钩,然后分别修改上图中的 3 、4、5 、6,
注意,3和5在STM32的单片机中应该都是固定的,但是4和6是跟你所采用的具体某一款单片机是对应
的。4和6应该是图1中STMicroelectronics 保持一致
第二步
第三步
第四步
第五步
添加引脚:添加引脚信息时候,PA脚输入:PORTA,PB脚输入PORTB,PC脚输入PORTC;接着输入".",接着在.后面输入对应引脚号,最后回车即可;例如:我这里要输入PA0,PA1,PA2这三个引脚的信息:依次分别添加三个引脚,分别添加三个引脚信息:PORTA.0;PORTA.1;PORTA.2,最后回车完成添加
第六步
点击图示开始进行仿真
(2)仿真实验结果
分析:由视频可以看出黄色为PA0、绿色为PA1、红色为PA2,时序状态正确,高低电平转换周期(LED闪烁周期)实际为3秒,且为低电平点亮。