一些前备知识

两种MOS管

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

GPIO

由于本人没学过模电数电,故不了解mos管,查阅后,了解后大致如下 :

1.分为p mos和n mos,两种区别仅为底下的半导体不同,P型的是以p型为衬底,N型同理。n型半导体是硅掺5价磷,p掺3价硼。故前者带电子,后者有空穴。

2.n mos管实际上是由两个半导体组成,再加上一个栅格来控制导通(如果没有栅格,则无论正反向均导通不了),栅格通电,吸引电子,挤掉空穴,形成n沟道,导通。p型反之。箭头代表电子移动方向。如图所示:

两种MOS管

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中文参考手册