单片机-MCU,串口通讯-线

GPIO全称General-Purpose Input/Output(通用输入/输出)

拿到一块新芯片,我怎么知道哪些是 GPIO?

在 STM32 乃至全世界 90% 的 ARM 架构单片机中,GPIO 引脚的命名都有极度统一的规律:它们一定是以字母 P 开头的。

  • P 代表 Port(端口)

  • 后面的字母代表“哪一组”:A组就是 PA,B组就是 PB,C组就是 PC

  • 最后的数字代表“第几个”:PA0PA15PB0PB15。 只要名字叫 P 加字母加数字的,全都是 GPIO,全都可以拿来控制继电器或者读按钮!

单片机芯片上那些最基础、最普通的引脚,用它来控制继电器,继电器这个东西,本质上就是一个极其头脑简单的物理电磁开关。给它通电(3.3V),它内部的磁铁就吸合,开关闭合。给它断电(0V),磁铁松开,开关就断开。所以,继电器的需求就是简单的有电和没电,用 GPIO 配置为 Output(输出模式)Output(输出) = 单片机的嘴巴。单片机主动往外吐电压(3.3V 或 0V),去命令继电器干活。继电器是个执行机构,它需要外部给它电压才能吸合。

HAL_GPIO_WritePin(RELAY_PWR_GPIO_Port, RELAY_PWR_Pin, GPIO_PIN_SET);

在 C 语言的 HAL 库里,HAL_GPIO_WritePin 这个函数就像是给快递员派单,它强制要求你必须填入三个参数(缺一不可):

  1. 去哪栋楼(Port)? RELAY_PWR_GPIO_Port (还记得你在 CubeMX 里给 PA5 起的别名吗?这个词在底层其实就是代表 GPIOA,也就是 A 栋楼)。

  2. 去哪个房间(Pin)? RELAY_PWR_Pin(底层代表 GPIO_PIN_5,也就是 5 号房间)。

  3. 干什么事(State)? GPIO_PIN_SET(把灯打开,输出 3.3V)。

所以,并不是 GPIO_PIN_SET 这个词本身对应 PA5,而是你传给函数的前两个参数,极其精准地把炮口对准了 PA5!如果你想控制 PA4(方向继电器),前两个参数就换成了 RELAY_DIR_GPIO_PortRELAY_DIR_Pin

#define RELAY_DIR_Pin GPIO_PIN_4
#define RELAY_DIR_GPIO_Port GPIOA

为什么RELAY_PWR_GPIO_Port代表着去A栋楼

当你刚才在 CubeMX 的图形界面里,给 PA5 引脚起了一个霸气的名字叫 RELAY_PWR,然后点击生成代码时,CubeMX 偷偷在你工程目录下的一个叫 main.h 的头文件里,写下了这样两行代码:

#define RELAY_PWR_Pin GPIO_PIN_5
#define RELAY_PWR_GPIO_Port GPIOA

#define 的意思就是“等价替换”。 它相当于给 Keil 的编译器下了一道死命令:“以后在代码里,只要看到 RELAY_PWR_GPIO_Port 这一长串字母,你就直接把它当成 GPIOA ;只要看到 RELAY_PWR_Pin,你就直接当成 GPIO_PIN_5!”

所以,当你写下这行代码: HAL_GPIO_WritePin(RELAY_PWR_GPIO_Port, RELAY_PWR_Pin, GPIO_PIN_SET);

在按下 F7 编译的那一瞬间,编译器会自动把它“翻译”成单片机能看懂的真面目: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

好处:

假设一种灾难情况: 你的板子画好了,代码也写了 500 多行,里面到处都是控制 GPIOAGPIO_PIN_5 开关继电器的代码。 突然,你发现 PA5 这个引脚在物理画板子的时候被别的线挡住了,你不得不把动力继电器改接到 PB12 上。

  • 如果你之前是手写 GPIOAGPIO_PIN_5 你现在得在几百行代码里,一行一行地去搜索,把所有的 GPIOA 改成 GPIOB,把所有的 PIN_5 改成 PIN_12。万一漏改了一个,机器就直接失控报错。

  • 但有了 CubeMX 的别名魔法(User Label): 你只需要在 CubeMX 的图形界面里,把 PA5 恢复默认,然后去点击 PB12,给 PB12 重新起名叫 RELAY_PWR。 再次点击生成代码,CubeMX 就会把 main.h 里的魔法词典悄悄改成

    #define RELAY_PWR_Pin GPIO_PIN_12
    #define RELAY_PWR_GPIO_Port GPIOB
    

    而你之前在 main.c 里写的那 500 行业务代码,一行都不需要改! 因为 RELAY_PWR_GPIO_Port 这个词没变,只是它底层指代的楼层和房间自动变了。

二、 I2C:精密传达数据的“快递专线”(控制 DAC)

1. I2C 是什么? I2C(读作 I-squared-C)是一种非常经典的芯片间通讯协议(通讯语言)。 它只需要两根线:一根叫 SCL(时钟线,负责喊节拍),一根叫 SDA(数据线,负责传信息)I2C1 只是说明咱们用的是 STM32 芯片内部集成的第 1 号 I2C 硬件模块(引脚是 PB6 和 PB7)。

2. 为什么用它控制 DAC 模块?

你买的那个 MCP4725 DAC 模块,是一个“高智商”芯片。它的任务是输出 0V 到 3.3V 之间任意的精细电压(比如 1.65V、2.1V)。

这时候,你用刚才的 GPIO 就不行了!GPIO 只能给 0V 或者 3.3V,它没法给出一个“1.65V”的半拉子电压。

所以,单片机必须跟 DAC 模块**“进行数字交流”**:

  • DAC 模块在 I2C 总线上有一个自己的专属门牌号(比如地址 0xC0)。

  • 当你想让扳手半速运转时,单片机就会通过 I2C 的这两根线,打包发送一封“快递信件”给这个门牌号,信封里装着数字 2048

  • DAC 模块收到这封信,拆开一看:“哦,老大让我输出 2048 对应的电压”,然后它芯片内部的电路就会精准地在 OUT 引脚上制造出 1.65V 的模拟电压,从而让扳手半速转动。

总结:I2C 就像是快递员,负责在两颗芯片之间精准地传递一串长长的“数据包”。因为 DAC 需要知道具体的调速数值(0~4095),而不是简单的开关,所以必须用 I2C 这种能传递复杂数据的通讯方式。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐