打印
[STM32F4]

从51到ARM裸机开发实验(004)STM32F401VE GPIO实验

[复制链接]
963|45
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
仿照“从51到ARM裸机开发实验(003) AT89C51 GPIO实验”,同样实现这样一种场景:四个按键作为开关、四个LED作为响应,每个开关控制一盏灯,按一次开灯,再按一次关灯。再接入一个蜂鸣和另外两个按键作为音量加和音量减,音量加每按一次蜂鸣器音量增加5%,音量减每按一次音量减少5%。这次将MCU替换成STM32F401VE芯片,属于ARM-Cortex 系列,为Cortex-M4内核。虽然实现相同的场景,但是开发配置和编码方式却大不一样。从电路图可以看出STM32F401VE有五组IO口,分别为PA~PE。每组有16个引脚,Px0~Px15,但Protues仿真图中没有PB11引脚, STM32F401VE的PB11引脚不能当GPIO使用, 同时必须外接2.2uF电容,在仿真图中略去了。每个GPIO模块内,主要包含了寄存器和驱动器,寄存器是一段特殊的存储器,内核可以通过APB总线对寄存器进行读写;驱动器是用来增强信号的驱动能力。STM32为32位单片机,但每组IO端口却只有16个引脚,是因为只用低16位的端口,高16位没有用到。注意:STM32F401VE必须加载.elf、.hex等可执行文件后才能运行仿真,未加载可执行文件时直接运行仿真会报错。

一、仿真电路图设计



Each general-purpose I/O port has four 32-bit configuration registers (GPIOx_MODER,GPIOx_OTYPER, GPIOx_OSPEEDR and GPIOx_PUPDR), two 32-bit data registers(GPIOx_IDR and GPIOx_ODR), a 32-bit set/reset register (GPIOx_BSRR), a 32-bit lockingregister (GPIOx_LCKR) and two 32-bit alternate function selection register (GPIOx_AFRHand GPIOx_AFRL).


使用特权

评论回复
沙发
wangtaohui|  楼主 | 2023-11-23 23:21 | 只看该作者
   相对于51单片机来说,STM32的功能显然要强大的多,其配置过程也复杂的多,上面是STM32F401xD/E官方文档中关于GPIO配置的介绍。每个通用 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)。下面列出即将要用到的端口配置,当然这还只是STM32的冰山一角,更多功能请参考官方的芯片手册。\

使用特权

评论回复
板凳
wangtaohui|  楼主 | 2023-11-23 23:21 | 只看该作者
端口模式
        根据数据手册中列出的每个 I/O 端口的特性,可通过软件将通用 I/O (GPIO) 端口的各个端口位分别配置为多种模式:
● 输入浮空
● 输入上拉
● 输入下拉
● 模拟功能
● 具有上拉或下拉功能的开漏输出
● 具有上拉或下拉功能的推挽输出
● 具有上拉或下拉功能的复用功能推挽
● 具有上拉或下拉功能的复用功能开漏
每个 I/O 端口位均可自由编程,但 I/O 端口寄存器必须按 32 位字、半字或字节进行访问。
GPIOx_BSRR 寄存器旨在实现对 GPIO ODR 寄存器进行原子读取/修改访问。这样便可确保
在读取和修改访问之间发生中断请求也不会有问题。

使用特权

评论回复
地板
wangtaohui|  楼主 | 2023-11-23 23:21 | 只看该作者
端口配置
2.1、I/O 端口控制寄存器

        每个 GPIO 有 4 个 32 位存储器映射的控制寄存器(GPIOx_MODER、GPIOx_OTYPER、
GPIOx_OSPEEDR、GPIOx_PUPDR),可配置多达 16 个 I/O。GPIOx_MODER 寄存器用于
选择 I/O 方向(输入、输出、AF、模拟)。GPIOx_OTYPER 和 GPIOx_OSPEEDR 寄存器分
别用于选择输出类型(推挽或开漏)和速度 (无论采用哪种 I/O 方向,都会直接将 I/O 速度引
脚连接到相应的 GPIOx_OSPEEDR 寄存器位)。无论采用哪种 I/O 方向,GPIOx_PUPDR 寄
存器都用于选择上拉/下拉。

使用特权

评论回复
5
wangtaohui|  楼主 | 2023-11-23 23:22 | 只看该作者
I/O 端口数据寄存器

每个 GPIO 都具有 2 个 16 位数据寄存器:输入和输出数据寄存器(GPIOx_IDR 和GPIOx_ODR)。GPIOx_ODR 用于存储待输出数据,可对其进行读/写访问。通过 I/O 输入的数据存储到输入数据寄存器 (GPIOx_IDR) 中,它是一个只读寄存器。

使用特权

评论回复
6
wangtaohui|  楼主 | 2023-11-23 23:23 | 只看该作者
使用Keil5开发STM32
1、地址映射
        STM32为32位单片机,其可访问4G的内存地址,范围为0~(2^32-1),用16进制表示为0x00000000~0xFFFFFFFF。在这4G的内存地址上,有些地址是和各种寄存器对应起来的。比如GPIO控制相关的寄存器就和如下的内存地址相对应。如GPIOA相关的配置寄存器、数据寄存器、速度寄存器等都映射在0x40020000~0x400203FF这段地址空间内,根据芯片手册,对某个地址空间写入数据,就是把数据写入到寄存器中去了。如果写入到配置寄存器,则该端口(引脚)状态按照配置情况生效。如果数据写入到数据寄存器,则根据配置,引脚可输出高低电平或从引脚上读取到0或1。

使用特权

评论回复
7
wangtaohui|  楼主 | 2023-11-23 23:23 | 只看该作者

根据电路图,用到的端口位PA、PB、PD,即GPIOA、GPIOB、GPIOD,其对应相关配置寄存器如下:

1.1、GPIO 端口模式寄存器 (GPIOx_MODER) (x = A..E and H)

复位值(复位的时候此寄存器中的默认值):
● 0xA800 0000(端口 A)
● 0x0000 0280(端口 B)
● 0x0000 0000(其它端口)

使用特权

评论回复
8
wangtaohui|  楼主 | 2023-11-23 23:23 | 只看该作者

偏移地址:0x00 即
寄存器GPIOA_MODER的地址 = 0x40020000 + 0x00
寄存器GPIOB_MODER的地址 = 0x40020400 + 0x00
寄存器GPIOD_MODER的地址 = 0x40020C00 + 0x00

使用特权

评论回复
9
wangtaohui|  楼主 | 2023-11-23 23:23 | 只看该作者
每个寄存器有32位,每2位控制一个引脚,32位控制16个引脚。2位数据就会有四种状态(模式):

00:输入模式(复位状态)
01:通用输出模式
10:复用功能模式
11:模拟模式

本场景中连接按键的引脚配置为输入模式、其他引脚配置为输出模式。

使用特权

评论回复
10
wangtaohui|  楼主 | 2023-11-23 23:24 | 只看该作者
GPIO 端口输出类型寄存器 (GPIOx_OTYPER)(x = A..E and H)

复位值(复位的时候此寄存器中的默认值):● 0x0000 0000

偏移地址:0x04 即
寄存器GPIOA_OTYPER的地址 = 0x40020000 + 0x04
寄存器GPIOB_OTYPER的地址 = 0x40020400 + 0x04
寄存器GPIOD_OTYPER的地址 = 0x40020C00 + 0x04


使用特权

评论回复
11
wangtaohui|  楼主 | 2023-11-23 23:24 | 只看该作者
此寄存器的高16位为保留,低16位每位控制一个引脚。每位有0和1两种状态:

0:输出推挽(复位状态)(可以输出高、低电平,连接数字器件)
1:输出开漏 (输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。
适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内))

本场景中采用输出推挽即可。


使用特权

评论回复
12
wangtaohui|  楼主 | 2023-11-23 23:24 | 只看该作者
GPIO 端口输出速度寄存器  (GPIOx_OSPEEDR)(x = A..E and H)

复位值(复位的时候此寄存器中的默认值):

• 0x0C00 0000 for port A
• 0x0000 00C0 for port B
• 0x0000 0000 for other ports


使用特权

评论回复
13
wangtaohui|  楼主 | 2023-11-23 23:24 | 只看该作者
偏移地址:0x08 即
寄存器GPIOA_OSPEEDR的地址 = 0x40020000 + 0x08
寄存器GPIOB_OSPEEDR的地址 = 0x40020400 + 0x08
寄存器GPIOD_OSPEEDR的地址 = 0x40020C00 + 0x08

使用特权

评论回复
14
wangtaohui|  楼主 | 2023-11-23 23:24 | 只看该作者
速度寄存器的配置方式也是每2位控制一个引脚,32位控制16个引脚,2位组合的四种状态如下:

00:2 MHz(低速)
01:25 MHz(中速)
10:50 MHz(快速)
11:30 pF 时为 100 MHz(高速)(15 pF 时为 80 MHz 输出(最大速度))

使用特权

评论回复
15
wangtaohui|  楼主 | 2023-11-23 23:25 | 只看该作者
GPIO 端口上拉/ 下拉寄存器 (GPIOx_PUPDR)(x = A..E and H)

复位值(复位的时候此寄存器中的默认值):

• 0x6400 0000 for port A
• 0x0000 0100 for port B
• 0x0000 0000 for other ports

偏移地址:0x0c 即
寄存器GPIOA_PUPDR的地址 = 0x40020000 + 0x0c
寄存器GPIOB_PUPDR的地址 = 0x40020400 + 0x0c
寄存器GPIOD_PUPDR的地址 = 0x40020C00 + 0x0c


使用特权

评论回复
16
wangtaohui|  楼主 | 2023-11-23 23:25 | 只看该作者
同样每2位控制一个引脚,32位控制16个引脚,2位组合的四种状态如下:

00:无上拉或下拉
01:上拉(上拉后引脚为高电平)
10:下拉(下拉后引脚为低电平)
11:保留

使用特权

评论回复
17
wangtaohui|  楼主 | 2023-11-23 23:26 | 只看该作者
GPIO 端口输入数据寄存器(GPIOx_IDR) (x = A..E and H)

复位值:0x0000 XXXX(其中 X 表示未定义)

偏移地址:0x10 即

寄存器GPIOA_IDR的地址 = 0x40020000 + 0x10
寄存器GPIOB_IDR的地址 = 0x40020400 + 0x10
寄存器GPIOD_IDR的地址 = 0x40020C00 + 0x10

高16位保留,未使用。低16位分别对应16个引脚, 这些位为只读形式,只能在字模式下访问。它们包含相应 I/O 端口的输入值。

使用特权

评论回复
18
wangtaohui|  楼主 | 2023-11-23 23:26 | 只看该作者
GPIO 端口输出数据寄存器 (GPIOx_ODR) (x = A..E and H)

复位值:0x0000 0000

偏移地址:0x14

寄存器GPIOA_ODR的地址 = 0x40020000 + 0x14
寄存器GPIOB_ODR的地址 = 0x40020400 + 0x14
寄存器GPIOD_ODR的地址 = 0x40020C00 + 0x14



高16位保留,低16位对应16个引脚,每位写入1/0即可从引脚输出高低电平。

使用特权

评论回复
19
wangtaohui|  楼主 | 2023-11-23 23:26 | 只看该作者
RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)

偏移地址:0x30
复位值:0x0010 0000
访问:无等待周期,按字、半字和字节访问。



本场景中使用到了第0、1、3位

使用特权

评论回复
20
wangtaohui|  楼主 | 2023-11-23 23:26 | 只看该作者
位3 GPIODEN :IO 端口 D 时钟使能 (IO port D clock enable)
由软件置 1 和清零。
0:禁止 IO 端口 D 时钟
1:使能 IO 端口 D 时钟
位 2 GPIOCEN :IO 端口 C 时钟使能 (IO port C clock enable)
由软件置 1 和清零。
0:禁止 IO 端口 C 时钟
1:使能 IO 端口 C 时钟
位 1 GPIOBEN :IO 端口 B 时钟使能 (IO port B clock enable)
由软件置 1 和清零。
0:禁止 IO 端口 B 时钟
1:使能 IO 端口 B 时钟
位 0 GPIOAEN :IO 端口 A 时钟使能 (IO port A clock enable)
由软件置 1 和清零。
0:禁止 IO 端口 A 时钟
1:使能 IO 端口 A 时钟

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

482

帖子

0

粉丝