一些前备知识
两种MOS管
首先,在翻阅一些B站上的视频后,我发现大部分GPIO都讲到了其内部结构,如下图所示:

由于本人没学过模电数电,故不了解mos管,查阅后,了解后大致如下 :
1.分为p mos和n mos,两种区别仅为底下的半导体不同,P型的是以p型为衬底,N型同理。n型半导体是硅掺5价磷,p掺3价硼。故前者带电子,后者有空穴。
2.n mos管实际上是由两个半导体组成,再加上一个栅格来控制导通(如果没有栅格,则无论正反向均导通不了),栅格通电,吸引电子,挤掉空穴,形成n沟道,导通。p型反之。箭头代表电子移动方向。如图所示:

3.n mos需要达到一定电压才可导通,p则需要小于一定电压。
上拉电阻和下拉电阻
1.设置上拉电阻,控制默认为高电压,当外部电路为低电压,产生数字信号,读取数据。
2.设置下拉电阻,控制默认为低电压,当外部电路为高电压,产生数字信号,读取数据。
TTL肖特基触发器(施密特触发器)
设置阈值电压,消除电压的波动影响,将图形变化变为数字变化(01变化)。
GPIO的八种模式
(1)模拟输入:直接读取具体电压值,上拉下拉断开
(2)上拉输入:上拉电阻闭合
(3)下拉输入:下拉电阻闭合
(4)复用功能输入:一些外部模块的输出,如串口模块
(5)推挽输出:芯片自身提供电源

(6)开漏输出:外接提供电源
(7)复用推挽输出:外设模块,串口、iiic等
(8)复用开漏输出:同上
GPIO相应的HAL库函数
GPIO_Mode_AIN 模拟输入
GPIO_Mode_IN_FLOATING 浮空输入
GPIO_Mode_IPD 下拉输入
GPIO_Mode_IPU 上拉输入
GPIO_Mode_Out_OD 开漏输出
GPIO_Mode_Out_PP 推挽输出
GPIO_Mode_AF_OD 复用开漏输出
GPIO_Mode_AF_PP 复用推挽输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); #初始IO口状态
HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); #重置IO口状态
HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); #读取IO口状态
HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState); #设置IO口状态
*PinState:GPIO 端口输出的状态,可以是 GPIO_PIN_RESET 或 GPIO_PIN_SET
HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); #转换IO口状态
HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); #锁定IO口状态
HAL_Delay() #()填毫秒数
|
实践led点亮/有源蜂鸣器的发音
Cubemx对应引脚设置GPIO_Output,生成代码:
1 2 3 4 5 6 7 8 9 10 11 12
| while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState); #填入你的IO口及对应状态 HAL_Delay(500); HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState); #填入你的IO口及对应相反状态 HAL_Delay(500); }
|
或者,你可以:
1 2 3 4 5 6 7 8 9 10
| while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); #填入你的IO口及对应状态 HAL_Delay(500); }
|
则可以实现led的闪烁和蜂鸣器的发音。
摁键的控制/光敏传感器的传感
Cubemx对应引脚设置GPIO_INput,生成代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); #填入你的IO口 if(HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)==GPIO_PIN_RESET) { HAL_Delay(10); #延时消抖 if(HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)==GPIO_PIN_RESET) #简单的摁键消抖 { #摁键/光敏传感器所控制的模块 } } }
|
注:
1 2 3 4 5 6
| 光敏模块引脚说明
VCC:电源引脚,接单片机+5V或者3.3V。 GND:地线,接单片机GND。 DO:开关量输出(0或1),模块在无光条件下或光强达不到设定阈值时,DO口输出高电平;当外界环境光强超过设定阈值时,DO输出低电平。 AO:模拟量输出(电压),与单片机AD模块相连,通过AD转换,获得准确数值。(后续中使用PA1引脚作为ADC转换,因此此处接单片机的PA1引脚)
|
故只能实现光信号简单的控制。
主要参考资源
1.B站江科大stm32 P5-8
2.B站keysking
3.B站爱上半导体
4.维库电子市场网
5.CSDN xiang–ying
6.CSDN 编号09527
7.stm32官方固件参考手册 、stm32中文参考手册