Notes06: 自写库_编写端口复位置位函数
野火霸道开发板学习笔记
信息说明
- 开发板: 野火霸道V2
- 芯片型号: STM32F103ZET6
- 下载器型号: 野火fireDAP下载器(高速版)
- 软件环境: Keil5(MDK-ARM V5.15)
- 芯片包型号: Keil.STM32F1xx_DFP.1.1.0 注: 亲测版本2.4.0不可用
- 操作系统 : Win11
编写端口复位置位函数
添加RCC寄存器结构体定义
RCC寄存器名称图
stm32f10x.h的改动
typedef struct
{
uint32_t CR;
uint32_t CFGR;
uint32_t CIR;
uint32_t APB2RSTR;
uint32_t APB1RSTR;
uint32_t AHBENR;
uint32_t APB2ENR;
uint32_t APB1ENR;
uint32_t BDCR;
uint32_t CSR;
}RCC_TypeDef;
#define RCC ((RCC_TypeDef*) RCC_BASE)
main.c的改动
RCC->APB2ENR |= (1 << 3);
GPIOB->CRL &= ~((0x0F) << (4*0));
GPIOB->CRL |= ((1) << (4*0));
GPIOB->ODR &= ~(1 << 0);
端口置位函数
端口置位函数使用的是GPIOx_BSRR寄存器,如下图所示
在stm32f10x_gpio.c中的函数实现
// 置位函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/*
* Note:
* 使用GPIOx_BSRR寄存器
* Bit31:16 : 写1清0, 写0不变
* Bit15:0 : 写1置1, 写0不变
*/
GPIOx->BSRR |= GPIO_Pin;
return;
}
在stm32f10x_gpio.h中的函数声明
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
端口复位函数
端口复位函数使用的是GPIOx_BRR寄存器, 如下图
在stmf10x_gpio.c中的函数实现
// 复位函数
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/*
* Note:
* 使用GPIOx_BRR寄存器
* Bit31:16 : 保留
* Bit15:0 : 写1清除, 写0不变
*/
GPIOx->BRR |= GPIO_Pin;
return;
}
在stmf10x_gpio.h中的函数声明
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
C语法补充
为了避免在stm32f10x.h中存在重复定义, 加入如下的语句
#ifndef __STM32F10X_H
#define __STM32F10X_H
#endif // !__STM32F10X_H
在stm32f10x_gpio.h中也应该加入类似语句
宏定义说明
在使用GPIOx_BSRR 和 GPIOx_BRR 寄存器置1过程中, 避免对其他位进行误操作, 需要进行 |= 操作,对 |= 的对象进行宏定义, 代码如下
// GPIO_Pin configuration
#define GPIO_Pin_0 ((uint16_t)0x0001) // (00000000 00000001)b
#define GPIO_Pin_1 ((uint16_t)0x0002) // (00000000 00000010)b
#define GPIO_Pin_2 ((uint16_t)0x0004) // (00000000 00000100)b
#define GPIO_Pin_3 ((uint16_t)0x0008) // (00000000 00001000)b
#define GPIO_Pin_4 ((uint16_t)0x0010) // (00000000 00010000)b
#define GPIO_Pin_5 ((uint16_t)0x0020) // (00000000 00100000)b
#define GPIO_Pin_6 ((uint16_t)0x0040) // (00000000 01000000)b
#define GPIO_Pin_7 ((uint16_t)0x0080) // (00000000 10000000)b
#define GPIO_Pin_8 ((uint16_t)0x0100) // (00000001 00000000)b
#define GPIO_Pin_9 ((uint16_t)0x0200) // (00000010 00000000)b
#define GPIO_Pin_10 ((uint16_t)0x0400) // (00000100 00000000)b
#define GPIO_Pin_11 ((uint16_t)0x0800) // (00001000 00000000)b
#define GPIO_Pin_12 ((uint16_t)0x1000) // (00010000 00000000)b
#define GPIO_Pin_13 ((uint16_t)0x2000) // (00100000 00000000)b
#define GPIO_Pin_14 ((uint16_t)0x4000) // (01000000 00000000)b
#define GPIO_Pin_15 ((uint16_t)0x8000) // (10000000 00000000)b
#define GPIO_Pin_ALL ((uint16_t)0xFFFF) // (11111111 11111111)b
main.c文件
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
int main(void)
{
# if 0 // 直接操作寄存器
*(unsigned int *)0x40021018 |= (1 << 3); // 打开时钟, 控制RCC_APB2ENR寄存器, 实现IO端口B时钟开启
/*
* RCC_APB2ENR寄存器(Address : 0x40021000(RCC) + 0x18)
* Bit3 : IOPBN : IO端口B时钟使能(I/O port B clock enable)
* 由软件置1或请0
* 0 : IO端口B时钟关闭
* 1 : IO端口B时钟开启
*/
*(unsigned int *)0x40010C00 |= ((1) << (4*