1)读库函数的一些宏定义和结构体
#define __IO voiatile
typedef unsigned int uint32_t;
typedef unsigned shrot uint16_t;
- 以结构体的形式定义好了外设寄存器后,使用结构体前还需要给结构体的首地址赋值,才能访问到需要的寄存器;
eg:GPIOx_TypeDef GPIOA
结构体的首地址赋了GPIOA地址的值;
IO端口认识
每个通用 I/O 端口包括 4 个 32 位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR 和 GPIOx_PUPDR)、
2 个 32 位数据寄存器(GPIOx_IDR 和GPIOx_ODR)、
1 个 32 位置位/复位寄存器 (GPIOx_BSRR)、
1 个 32 位锁定寄存器(GPIOx_LCKR)、
2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)。
GPIOx_MODER 寄存器用于选择 I/O 方向(输入、输出、AF、模拟)。
GPIOx_OTYPER 和 GPIOx_OSPEEDR 寄存器分别用于选择输出类型(推挽或开漏)和速度 (无论采用哪种 I/O 方向,都会直接将 I/O 速度引脚连接到相应的 GPIOx_OSPEEDR 寄存器位)。
无论采用哪种 I/O 方向,GPIOx_PUPDR 寄存器都用于选择上拉/下拉。
GPIOx_ODR 用于存储待输出数据,可对其进行读/写访问。通过 I/O 输入的数据存储到输入数据寄存器
GPIOx_IDR 它是一个只读寄存器。(每两个AHB时钟读取一次IO的状态)
I/O口的数据数据寄存器和位操作
ODR和IDR为GPIO的输出和输入寄存器,16位BSRR分为两个BSR和BRR置位和复位不能单独操作,都是写1有效。
一、推挽输出和开漏输出设置,控制寄存器: GPIOx_OTYPER
推挽输出与开漏输出的应用场合:
1、推挽输出:一般应用在输出电平为0~3.3V而且需要高速切换开关状态的的场合
2、开漏输出:一般应用在I2C、SMBUS通讯等需要“线与”功能的总线电路中
二、输出数据寄存器:ODR
输出模式引脚电平受输出寄存器ODR的影响,而ODR寄存器对应引脚位为0,引脚初始化为低电平,上拉只是小幅度的提高输出电流的能力;
三、启动文件的作用:
初始化堆栈指针 SP;
初始化程序计数器指针 PC;
设置堆、栈的大小;
设置中断向量表的入口地址;
配置外部 SRAM 作为数据存储器(这个由用户配置,一般的开发板可没有外部SRAM);
调用 SystemIni() 函数配置 STM32 的系统时钟。
设置 C 库的分支入口“__main”(最终用来调用 main 函数);
四、用寄存器点亮LED
1、IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
从启动文件可以看出我们需要写SystemInit()和main()两个函数
SystemInit()函数是配置系统的,为了简单我们使用默认状态,即在主函数中写入SystemInit()函数但并不做任何动作,目的就是骗过编译器;
2、在配置寄存器是要定义他们的地址,所以接下来就是定义地址
3、配置相关寄存器
五、编程实现:
1、时钟配置RCC
1)GPIOx挂载在AHB1总线上,所以要使能RCC_AHB1ENR总线时钟;
2)RCC_AHB1ENR |= (1<<7);
2、模式选择:
1)GPIOH_MODER &= ~( 0x03<< (210));先将20 21引脚清零,然后写入01 GPIOH_MODER |= (1<<210);
2)模式选择、速度配置、上拉下拉同上;
3)然后利用复位置位寄存器GPIOH_BSRR或输入输出GPIOH_ODR配置;