MCU和GPIO (1)
1.单片机MCU
好久没有更新了,最近学了一下hi3861芯片,算是学STM32的预习。有机会再更新hi3861吧
1.1单片机和嵌入式系统
嵌入式系统
- 硬件 + 软件的嵌入式系统。嵌入到特定设备中,从而控制设备的执行。
- 硬件:处理单元,内存 + 硬盘
- 软件:裸机程序 或者 实时操作系统。
生活中实现的常见场景
- 智能家居,智能穿戴设备,无人设备,智能驾驶,军事
- 汽车主机厂,军工单位,智能化工厂
1.2MCU
微控制单元(Microcontroller Unit;MCU) ,又称单片微型计算机(Single Chip Microcomputer )或者单片机,是把中央处理器(Central Process Unit;CPU)的频率与规格做适当缩减,并将内存(memory)、计数器(Timer)、USB、A/D转换、UART、PLC、DMA等周边接口,甚至LCD驱动电路都整合在单一芯片上,形成芯片级的计算机,为不同的应用场合做不同组合控制。
1.3STM32开发板概述
主包学习使用的开发板是STM32F103ZET6,图中这个
目前使用的开发版是基于 STM32F103ZET6 型号。
ST 意法半导体公司产品
M 使用 Cortex-M 内核
32 当前 MCU 为 32 位芯片
F103
F1 ==> Cortex-M3 内核
03 ==> F1 系列的型号,03 是增强型。
ZET6
Z ==> 引脚数目 144 引脚
E ==> 闪存存储器大小(Flash) 512 KB
T ==> 封装标准 LQFP 封装
6 ==> 工作温度范围 -40 ~ 85 ℃
2.GPIO
2.1GPIO概述
GPIO,全称为 通用输入输出,是一种存在于集成电路(如微控制器、单板计算机等)上的数字信 号引脚。它的核心特征是 “通用”,意味着这些引脚没有预先设定的单一功能(比如专门用于UART 通信或I2C通信),其具体行为(作为输入还是输出)可以通过软件进行动态配置。 对于 GPIO 而言
- GPIO 方式 输入 or 输出
- GPIO 电压情况,高电平 or 低电平
2.2STM32F103ZET6 GPIO 相关内容
不同的 MCU 信号中,对应的 GPIO 数量不同,主要因素是对应 STM32 引脚数量
- GD32F103C8T6 对应 GPIO 有两组分别是 GPIOA 和 GPIOB,每一组 16 个通用GPIO,可编 程 GPIO 有 32 个
- STM32F103ZET6 对应 GPIO 有七组 GPIOA ~ GPIOG,每一组 16 个通用GPIO,可编程 GPIO 有 16 * 7 = 112 个
硬件设计中的很多理念都遵循 2 进制思想,另外在硬件开发中,操作使用的二进制情况很多,需要重点掌握【位操作】相关内容
2.3GPIO开发流程
原理图分析
- 根据原理图,分析当前编程需要控制的引脚是哪一个,同时期望的现象需要当前 IO 对 应工作状态。
寄存器控制开发
- 时钟使能,MCU 中所有的外部设备处于休眠状态。需要告知 MCU 当前外部设备需要工 作,加入到 MCU 的执行周期中。
- 根据原理图分析的 GPIO 工作模式,对应 GPIO 进行配置。
- 明确 GPIO 分组
- 明确 GPIO 引脚编号
- 明确 GPIO 工作模式和高低电平状态。
- 根据以上信息进行配置。
根据业务所需,进行相关代码实现。
2.4GPIO控制LED灯
这里用最简单的控制LED灯来学习GPIO的使用
LED原理图分析
- 对应引脚是LED0和LED1
- 当前LED对应IO引脚
- IO提供高电平,LED灭
- IO提供低电平,LED亮
- 分析
- GPIO要求可以提供高低电平切换。
- GPIO对应输出模式
- LED0 ==> PB5
- GPIO 分组 B 组中编号为 5 的引脚
- LED1 ==> PE5
- GPIO 分组 E 组中编号为 5 的引脚
2.5GPIO端口内部基本电路情况
STM32中GPIO有八中工作模式
2.5.1. 浮空输入模式(Floating Input)
- 原理:在这种模式下,GPIO 引脚没有接上拉电阻或下拉电阻,其电平状态完全取决于外部电路。引脚处于高阻抗状态,输入电流几乎为零。根据当前 IO 口分压来判断高低电平数据。
- 应用场景:适用于外部信号已经有明确的驱动能力和电平状态的情况,比如连接按键,按键按下时直接将引脚接地,松开时引脚浮空,通过读取引脚电平判断按键状态。
2.5.2. 上拉输入模式(Pull - up Input)
- 原理:GPIO 引脚内部连接了上拉电阻,当外部电路没有对引脚进行驱动时,引脚电平被上拉到高电平。如果外部电路将引脚拉低,那么引脚电平就为低电平。
- 应用场景:常用于按键输入,当按键未按下时,引脚通过上拉电阻保持高电平;按键按下时,引脚接地变为低电平,避免了引脚浮空可能带来的电平不稳定问题。
2.5.3. 下拉输入模式(Pull - down Input)
- 原理:与上拉输入模式相反,GPIO 引脚内部连接了下拉电阻,当外部电路没有对引脚进行驱动时,引脚电平被下拉到低电平。如果外部电路将引脚拉高,那么引脚电平就为高电平。
- 应用场景:同样适用于按键输入等场景,当按键未按下时,引脚通过下拉电阻保持低电平;按键按下时,引脚接高电平。
2.5.4. 模拟输入模式(Analog Input)
- 原理:该模式下,GPIO 引脚用于模拟信号的输入,内部的数字逻辑电路被断开,引脚直接连接到模拟信号处理模块,如 ADC(模拟 - 数字转换器)。
- 应用场景:用于采集模拟信号,如温度传感器、压力传感器等输出的模拟电压信号,通过ADC 将模拟信号转换为数字信号进行处理。
2.5.5. 开漏输出模式(Open - Drain Output)
- 原理:在开漏输出模式下,GPIO 引脚内部的输出级只有 N 沟道 MOS 管,当输出为低电平MOS 管导通,引脚接地;当输出为高电平时,MOS 管截止,引脚处于高阻态,需要外部接上拉阻才能输出高电平。
- 应用场景:常用于实现线与功能、I2C 总线等通信协议,多个开漏输出引脚可以连接在一起,只要有一个引脚输出低电平,总线就为低电平。
2.5.6. 推挽输出模式(Push - Pull Output)
- 原理:推挽输出模式下,GPIO 引脚内部的输出级由 P 沟道 MOS 管和 N 沟道 MOS 管组成。当输出为高电平时,P 沟道 MOS 管导通,引脚输出高电平;当输出为低电平时,N 沟道MOS 管导通,引脚输出低电平。
- 应用场景:适用于直接驱动一些负载,如 LED 灯,能够提供的驱动能力。
2.5.7. 复用开漏输出模式(Alternate Function Open - Drain Output)
- 原理:该模式下,GPIO 引脚的功能由片上外设控制,输出级采用开漏输出结构。与普通开漏输出模式类似,需要外部接上拉电阻才能输出高电平。
- 应用场景:常用于一些通信协议和外设接口,如 SPI 总线的某些引脚、I2C 总线等,将 GPIO引脚复用为外设的特定功能。
2.5.8. 复用推挽输出模式(Alternate Function Push - Pull Output)
- 原理:此模式下,GPIO 引脚的功能由片上外设控制,输出级采用推挽输出结构,能够直接输出高电平和低电平。
- 应用场景:常用于一些需要较强驱动能力的外设接口,如 UART 通信的发送引脚、PWM 信号输出等。
2.6时钟使能
时钟是当前 MCU 的执行能力,主要的核心参数/内容
- 时钟频率:一般都是 MCU 和外部晶振提供,作为 MCU 处理任务的核心时钟参数,当前STM32F103ZET6 芯片时钟是 72 MHz。芯片的运算速度可以认为是 13.88ns 时间周期执行一次计算。
- 时钟树:当前 MCU 内部的电路设计,将 MCU 的计算器能力提供多个时钟提供端口,将MCU 执行能力提供给不同的功能模块,每一个模块都有固定的内部时钟管道。
- 类似于水厂/热力公司,根据不同的区域管道,提供自来水/热力。
2.7寄存器开发模式
2.7.1时钟使能,对应寄存器RCC
RCC ==> Reset & Clock Control
根据原理分析引脚关系和时钟树分析对应时钟分配情况,当前需要通过 RCC 控制 APB2 使能 (Enable) GPIOB 和 GPIOE 两个 GPIO 组时钟,从而满足执行操作。
根据文档:
我们要让IOPE和IOPB使能
有两种方式
方式1:直接赋值给寄存器数据0x0000 0048
方式2:
RCC->APB2ENR |= (0x01 << 6); // 使能 GPIOE
RCC->APB2ENR |= (0x01 << 3); // 使能 GPIOB
2.7.2GPIO对应引脚配置
根据原理图分析,对应引脚是 PB5 和 PE5,对应工作模式为 GPIO 推挽输出模式。利用 GPIO 寄 存器对当前的 IO 引脚进行控制。
在 STM32 中的一组 GPIO 有 16 个 IO 口。内核将 16 个 IO 分为高低两组
高位寄存器 8 ~ 15
低位寄存器 0 ~ 7
因为多组 GPIO,在底层寄存器中,利用 GPIOx 提供不同的分组 GPIO 控制。例如 GPIOA,
GPIOB...
当前 GPIOB ==> PB5 和 GPIOE ==> PE5 所需的工作模式为
通用推挽输出模式
需要对当前寄存器中的 CNF5 和 MODE5 进行组合配置,可以提供数据为
0001 ==> 推挽输出模式,速度 10 MHz
0011 ==> 推挽输出模式,速度 50 MHz
0010 ==> 推挽输出模式,速度 2 MHz
GPIOB->CRL |= (0x03 << 20); // GPIOB 组中 PB5 引脚配置为通用推挽输出模式,速度 50MHz
GPIOE->CRL |= (0x03 << 20); // GPIOE 组中 PE5 引脚配置为通用推挽输出模式,速度 50MHz
2.7.3 GPIO 引脚输出高低电平配置
通过ODR配置输出电平
GPIOB->ODR &= ~(0x01 << 5);
GPIOE->ODR &= ~(0x01 << 5);
LED 灭,GPIO对应就为高电平
GPIOB->ODR |= (0x01 << 5);
GPIOE->ODR |= (0x01 << 5);
2.8代码实现
#include "stm32f10x.h"
/*
STM32 核心头文件,没有当前头文件无法完成项目开发!!!
stm32f10x.h 对应芯片系列为
F10x ==> F101 F102 F103 F105 F107....
*/
int main(void)
{
/*
1. 时钟使能
需要将 MCU 时钟提供给 GPIOB 和 GPIOE
对应寄存器是 RCC->APB2ENR
*/
RCC->APB2ENR |= (0x01 << 3); // 使能 GPIOB IO组
RCC->APB2ENR |= (0x01 << 6); // 使能 GPIOE IO组
/*
2. 对应 GPIO 引脚功能配置,需要对 PB5 和 PE5 引脚统一配置为
【通用推挽输出模式】
对应寄存器是 GPIOx->CRL
GPIOB->CRL &= ~(0x0F << 20);
GPIOB->CRL 32位寄存器 0100 0100 【????】 0100 0100 0100 0100 0100
0x0F ==> 0000 1111 执行左移 20 位
0000 1111 0000 0000 0000 0000 0000
~(0x0F << 20)
1111 0000 1111 1111 1111 1111 1111
GPIOB->CRL &= ~(0x0F << 20);
0100 0100 ???? 0100 0100 0100 0100 0100
& 1111 0000 1111 1111 1111 1111 1111
0100 0100 0000 0100 0100 0100 0100 0100
*/
// PB5 配置
GPIOB->CRL &= ~(0x0F << 20);
GPIOB->CRL |= (0x03 << 20); // 0011 ==> 通用推挽输出模式,速度 50 MHz
// PE5 配置
GPIOE->CRL &= ~(0x0F << 20);
GPIOE->CRL |= (0x03 << 20); // 0011 ==> 通用推挽输出模式,速度 50 MHz
/*
3. 控制 GPIOx_ODR 寄存器,配置高低电平
高电平 ==> LED 灭
低电平 ==> LED 亮
*/
while (1)
{
// LED0 亮 LED1 灭
GPIOB->ODR &= ~(0x01 << 5);
GPIOE->ODR |= (0x01 << 5);
for (u32 i = 0; i < 10000000; i++) {}
GPIOB->ODR |= (0x01 << 5);
GPIOE->ODR &= ~(0x01 << 5);
for (u32 i = 0; i < 10000000; i++) {}
}
}