单片机相关知识
单片机-MCU,串口通讯-线GPIO全称拿到一块新芯片,我怎么知道哪些是 GPIO?PP代表。后面的字母代表“哪一组”:A组就是PA,B组就是PB,C组就是PC。PA0到PA15PB0到PB15。只要名字叫P加字母加数字的,,全都可以拿来控制继电器或者读按钮!单片机芯片上那些最基础、最普通的引脚,用它来控制继电器,继电器这个东西,本质上就是一个。给它通电(3.3V),它内部的磁铁就吸合,开关闭合。
单片机-MCU,串口通讯-线
GPIO全称General-Purpose Input/Output(通用输入/输出)
拿到一块新芯片,我怎么知道哪些是 GPIO?
在 STM32 乃至全世界 90% 的 ARM 架构单片机中,GPIO 引脚的命名都有极度统一的规律:它们一定是以字母 P 开头的。
-
P代表 Port(端口)。 -
后面的字母代表“哪一组”:A组就是
PA,B组就是PB,C组就是PC。 -
最后的数字代表“第几个”:
PA0到PA15,PB0到PB15。 只要名字叫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 这个函数就像是给快递员派单,它强制要求你必须填入三个参数(缺一不可):
-
去哪栋楼(Port)?
RELAY_PWR_GPIO_Port(还记得你在 CubeMX 里给 PA5 起的别名吗?这个词在底层其实就是代表GPIOA,也就是 A 栋楼)。 -
去哪个房间(Pin)?
RELAY_PWR_Pin(底层代表GPIO_PIN_5,也就是 5 号房间)。 -
干什么事(State)?
GPIO_PIN_SET(把灯打开,输出 3.3V)。
所以,并不是 GPIO_PIN_SET 这个词本身对应 PA5,而是你传给函数的前两个参数,极其精准地把炮口对准了 PA5!如果你想控制 PA4(方向继电器),前两个参数就换成了 RELAY_DIR_GPIO_Port 和 RELAY_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 多行,里面到处都是控制 GPIOA 和 GPIO_PIN_5 开关继电器的代码。 突然,你发现 PA5 这个引脚在物理画板子的时候被别的线挡住了,你不得不把动力继电器改接到 PB12 上。
-
如果你之前是手写
GPIOA和GPIO_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 这种能传递复杂数据的通讯方式。
更多推荐



所有评论(0)