STM32深入学习3:GPIO模块控制LED(寄存器版)

发布时间 2023-09-03 19:51:39作者: zxkic

GPIO模块数据手册详解:

GPIO:通用输入/输出

AFIO:备用输入/输出

GPIOx_CRL和GPIOx_CRH:配置寄存器

GPIOx_IDR和GPIOx_ODR:数据寄存器

GPIOx_BSRR:置位/复位寄存器

GPIOx_BRR:复位寄存器

GPIOx_LCKR:锁定寄存器,锁定GPIO的数值

GPIO模式:

1.输入浮动:完全由外部决定

2.输入上拉和输入下拉:存在上拉和下拉电阻

3.模拟输入:不经过任何电路,直接到AD输入

4.输出开漏:开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动。

5.输出推挽模式:想输出高电平,就输出高电平,想输出低电平就输出低电平。有较强的驱动力,但是如果两个输出接在一起会引起短路。

6.备用功能推挽

7.备用功能开漏

为了使用外部中断,需要将端口配置为输入模式,进行映射。

PZ-6806L原理图上,LED接到了PC0-PC7上,同时LED的另一边接的是3.3V,因此,管脚置0为亮,置1为灭。

mian函数之前,还有起始代码:从复位开始执行第一条指令,到main函数之前所做的事情就是起始代码。构建运行环境。

起始代码:不同的CPU起始代码一般不同。startup file for device,根据cpu的汇编环境编写。

寄存器信息:

STM32f103zet6 的portB的起始地址

GPIOC_CRL和GPIOC_CRH

偏移量 GPIOC_CRL 0x00, 寄存器地址为0x4001 1000

    GPIOC_ODR 0X0C  寄存器地址为0x4001 100C

ARM是内存与IO统一编址的,所以ARM中的所有外设都是通过寄存器来操作的

每个寄存器都有地址,C语言通过位操作和指针来进行操作。

常见面试题:用c语言向内存地址0xXXXXX写入16

*(unsigned int*) 0xXXXXX = 16;

或者unsigned int *p = (unsigned int *) 地址, *p = 16;

 

除了GPIOC_CRL和GPIOC_ODR需要设定外,RCC_APB2_ENR也需要进行设定。

RCC_APB2_ENR 寄存器地址为:0x40021000,偏移量为0x18

优先选择bsrr,因为bsrr是原子操作,不会被中断操作打断。

#define RCC_APB2_ENR 0x40021018
#define GPIOC_CRL 0x40011000
#define GPIOC_ODR 0x4001100C
    *((unsigned int *)RCC_APB2_ENR) = 0x00000010;
    //推挽输出模式,速率为50MHZ
    (*((unsigned int *)GPIOC_CRL)) = 0x33333333;
    //输出0点亮LED
    (*((unsigned int *)GPIOC_ODR)) = 0X00000000;

 

 

STM32时钟设置函数移植与讲解

上电之后系统自动会设置一个时钟,默认使用8M。如果需要72M,那么需要人为的切换时钟源

HSE的设定,PLL的设定,SYSCLK的设定

SysClock_Init()函数进行时钟初始化。

RCC_CR寄存器:偏移量为0x00

RCC基地址:0X40021000

do while()循环,判断外部时钟开启是否成功

RCC_CFGR配置系统时钟源

打开PLL使能,设定PLL的频率

设置 FLASH 时延 保证能正确读取内存中的内容