关于固件库
STM32固件库本质上是对外设寄存器直接编程。固件库是函数的集合,其作用可理解为:向下负责与寄存器直接打交道,向上提供用户函数调用的接口(API)。对于STM32这种级别的MCU,有数百个寄存器,其地址记起来十分困难,固件库将这些寄存器底层操作都封装起来,提供一套API供开发者使用,用户只需调用相应的函数,便可实现对寄存器的编译。 |
一、创建一个keil工程,并添加stm32库函数
- 点击project > 点击New uVision project > 芯片选型stm32F103c8
- 在Target 1下新建三个 group ,分别命名为:start、library、user。项目文件夹下也是如此。
- user 用来存放main.c文件
- start 用来存放启动文件(启动文件添加这里不多叙述,主要讲述固件库的添加)
- library 用来存放库函数文件
库函数文件来自江协科技:https://pan.baidu.com/s/1lkUq8q4lrPwOKtX5m1mB7A?pwd=lhhs
提取码:lhhs
当然可以选择去keil官网下载最新的固件库。https://www.keil.arm.com/devices/?page=2
- 打开STM入门教程文件夹,点击固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\src,Ctrl+A复制全部库函数文件到刚刚创建的library文件夹下。
- 找到固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\inc,复制全部库函数头文件至library文件夹。
- 回到keil,右键library->Add Existing Fils,将library文件夹中所有.c .h 文件添加进来。
此时库函数还不能直接使用 - 打开固件库\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template
- conf.h文件用来配置库函数头文件包含关系。
- it.c和it.h用来存放中断函数
复制以上三个文件至工程的user文件夹下,并在keil中添加到user组中。
文件类型选All files。
- 设置宏定义
右键生成头文件
右键打开头文件
划到最下面
要求stm32f10x_conf.h语句有效,需先定义USE_STDPERIPH_DRIVER字符串。
复制该字符串,点击魔术棒 > c/c++ > Define 中粘贴该字符串。
- 添加头文件路径
魔术棒 -> c/c++ ,如图操作
至此,库函数添加完毕!
二、代码编写
使用GPIOA0号引脚、GPIOB0号引脚、GPIOC13号引脚实现流水灯 |
- 头文件
#include "stm32f10x.h"//固件库头文件
#include "Delay.h"//中断函数头文件
- 使能时钟寄存器
根据stm32使用手册,要用到GPIO口,我们需要先打开APB2总线上的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
- 配置寄存器
使用GPIO_InitTypeDef
函数,右键单击查看函数定义
分别是配置输出引脚、输出速率、输出模式。
按图中操作查看不同工作模式,其他配置同此。
我们这里选择GPIO_Mode_Out_PP;
推挽输出模式。
输出速率选择50MHZ。
配置寄存器代码:
GPIO_InitTypeDef GPIO_InitStructureA;
GPIO_InitStructureA.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructureA.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructureA.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructureA);
- 主函数
再次点开gpio.h文件
看到GPIO有这些输入输出函数。
选择GPIO_WriteBit
函数与延时函数实现流水灯。
delay.c文件
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; //关闭定时器
}
这是延时微秒级代码,延时毫秒或秒,在前一级基础上再套一层循环即可。
- 完整代码
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructureA;
GPIO_InitStructureA.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructureA.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructureA.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructureA);//配置GPIOA寄存器
GPIO_InitTypeDef GPIO_InitStructureB;
GPIO_InitStructureB.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructureB.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructureB.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureB);
GPIO_InitTypeDef GPIO_InitStructureC;
GPIO_InitStructureC.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructureC.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructureC.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructureC);
while (1)
{
GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);
Delay_ms(500);
GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);
Delay_ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
Delay_ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
Delay_ms(500);
GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
Delay_ms(500);
GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
Delay_ms(500);
}
}
- 硬件运行情况
三、示波器分析
可以看出三个端口信号正常,LED依次亮灭。
高电平持续时间正好0.5秒。