1.如何点亮一盏灯?

灯亮需要电流,电流的产生需要电势差
3.3V------- + LED - --------GND(0V)
核心板上面的LED

原理图中的LED
原理图
原理图(Schematic Diagram),也称为电路图或电气图,是一种图形表示方法,用于展示电子系统或电路的工作原理和组成部分之间的连接方式。它通常包括各种符号来代表电子元器件(如电阻器、电容器、晶体管等)以及连线来表示它们之间的电器连接。

电路分析

上拉电阻:VDD连接一个电阻连接到信号线
作用:在没有外界的电路接入或者外界电路的电平状态不确定的情况下,让电路保持在高电平状态。
下拉电阻:GND连接一个电阻连接到信号线
作用:在没有外界的电路接入或者外界电路的电平状态不确定的情况下,让电路保持在低电平的状态。
由以上分析得知:只需要给PC13引脚一个高电平,D1即可被点亮,反之,熄灭。
2.GPIO
简介
GPIO全称(General purpose input output):通用的输入输出接口
I:input 输入
O:output
GPIO是嵌入式系统,单片机开发中最常用的接口,用户可以通过编程灵活的对接口进行控制,实现对电路板上LED、数码管、按键等常用设备控制驱动,也可以作为串口的数据收发管脚,或AD的接口等复用功能使用。其作用和功能是非常重要的。
实际的应用
input 输入->采集外界的信息 各种传感器、按键。
output 输出->控制外部设备 LED 马达 风扇 蜂鸣器
功能描述
GPIO功能说明
根据数据手册中列出的每个I/O端口的特性,可通过软件将通用I/O(GPIO)端口位分别配置为多种模式:
浮空输入
上拉输入
下拉输入
模拟输入
具有上拉或者下拉功能的开漏输出
具有上拉或下拉功能的推挽输出
具有上拉或下拉功能的复用功能推挽
具有上拉或下拉功能的复用功能开漏
功能框图

VDD:元器件内部的工作电压
VCC:接入电路的电压
VSS:公共的接地端
TTL施密特触发器

去除噪声:
由于外部输入的电信号,可能会出现脉冲等噪声的影响,为了让信号更加清晰,所以就设置了TTL施密特触发器来进行整形。
滤波整形:
对于上升沿和下降沿比较缓慢的输入信号,施密特触发器可以将其转换为边缘陡峭的方波信号。这对于后续的数字电路处理非常重要,因为数字电路要求输入信号具有明确的高电平和低电平。
提高抗干扰能力:
由于施密特触发器具有滞回效应,它能够提高电路的抗干扰能力。即便输入信号存在一定程度的抖动或者噪声,施密特触发器仍能保持稳定的输出状态。
施密特触发器的工作原理:
施密特触发器的核心就在于它的滞回效应,是的施密特触发器具有两个不同的触发电平----上触发电平 VT+ 下触发电平VT-
当输入的电压从低电平开始向高电平上升时,只有超过VT+,输出才会切换到高电平。
当输入的电压从高电平开始向低电平下降时,只有超过VT-,输出才会切换到低电平。
GPIO的基本功能
浮空输入
通过配置寄存器,让电路中的上拉电阻,下拉电阻均不接入电路

IO端口->施密特触发器->输入数据寄存器/数字量输入->CPU读取
说明:浮空输入就是让引脚什么都不接,处于悬空状态
此时上拉电阻和下拉电阻的两个开关同时断开,因为没有上拉和下拉,所以当IO口没有外界电路接入的时候,此时内部电路的电平状态处于不确定的状态,这既是一个优点又是一个缺点,好处就在于完全由外界的输入来决定电平状态。
应用:一般放在用于开关或者其他元器件内部的电压读取,还有就是一些通信协议上。
上拉输入
通过寄存器的配置,让上拉电阻接入电路,在没有信号输入的情况下,IO口识别到的都是高电平。

I/O口上拉电阻->施密特触发器->输入数据寄存器->CPU读取
说明:当没有信号输入或者当外界电路的电平状态不确定的时候,上拉电阻会将信号拉高到高电平,此时IO口识别到的都是高电平,此时引脚始终读取到高电平信号。如果有外界信号输入或者电平状态稳定,以外界电路的电平状态为主。
应用:输入信号不稳定的时候
下拉输入
通过寄存器的配置,让下拉电阻接入电路,在没有信号的情况下,IO识别到的都是低电平。

IO口/下拉电阻->施密特触发器->输入数据寄存器->CPU读取
说明:当没有信号输入或者当外界的电平状态不确定的时候,下拉电阻会将信号拉低到低电平,此时引脚始终读取到低电平信号。
如果有外界信号输入或者电平状态稳定,以外界电路的电平状态为主。
模拟输入
原汁原味的信号,什么都不经过

IO口->片上外设
说明:信号进入后不经过上拉电阻或者下拉电阻,关闭施密特触发器,经由另一线路把电压信号传送到片上外设模块。所以可以理解为模拟输入的信号未经处理的信号,是原汁原味的信号。
应用:多用于ADC数据的采集
推挽输出
推挽:描述的是电流的动作

推:N-MOS管关闭,P-MOS管打开,电流从内部的VDD给外部供电,电流从内部被推出去。
挽:P-MOS关闭,N-MOS管打开,电流从外部流向内部的VSS,此时电流被挽回来。
输出数据寄存器为 0 -> 输出控制 1-> 激活N-MOS ->IO口低电平->输出低电平
输出数据寄存器为 1 -> 输出控制 0-> 激活P-MOS ->IO口高电平->输出高电平
特点:
1.具备输出高低电平的能力。
2.推挽输出就是可以需要利用两个不同的MOS管来实现输出。
推挽输出模式下(P-MOS管+N-MOS管),通过设置位设置/清除寄存器或者输出数据寄存器的值,途径P-MOS管和N-MOS管,最终输出到I/O端口 。
3.一般最常用的输出方式,既能输出高电平也能输出低电平。
开漏输出
P-MOS管不使用

在开漏模式下,输出的引脚会存在两种状态
1.低电平状态(逻辑0):当内部的晶体管(N-MOS)导通的时候,引脚的电平状态被拉低到低电平,输出低电平。
2.当晶体管(N-MOS)也关闭的时候,内部处在高阻态。没有办法输出电平,但是可以使用上拉电阻将电平状态拉高,来输出一个高电平。
虽然我们可以看到开漏输出是没办法在内部输出一个高电平,但是这一个看似是缺点。其实实际上是一种优点。当给一个低电平的时候,MOS管没有导通,此时电压不确定导致无法输出高电平,但是一旦我们在外部增加一个上拉,那么,这个上拉的电压是由我们自己确定的,这样我们就可以根据外部电路需要多少V的高电平来给这一个上拉的电压,可以更好的适应更多的情况。
推挽输出和开漏输出的区别
复用功能的推挽
复用功能的开漏
3.GPIO输出实验
GPIO相关的寄存器

寄存器的概念
为什么要学习寄存器,寄存器的作用是什么?
1.寄存器是单片机内部的存储单元
2.单片机模式的设置和寄存器直接关联的,比如输出模式,输出的高低电平,上拉电阻和下拉电阻是否打开,所以想要对单片机进行设置就是对寄存器改写的过程。
下面我们以PC13引脚为例,进行寄存器的使用
时钟使能寄存器
我们在找GPIOC端口之前需要先配置GPIO的C端口的时钟使能,C端口才能进行工作。
1.确定C端口连接的总线

2.找到总线相关的时钟寄存器


如果我们想要使用GPIOC端口的话,就必须开启RCC_AHB2ENR的位2 置位1
端口模式寄存器


注意:此寄存器两位控制一个引脚
PC13配置为通用的输出模式:位27,26分别置为0,1
端口输出类型寄存器

PC13配置为推挽输出:位13置位0
端口输出速度寄存器

PC13配置为低速输出:位27,26置位0,0
端口上下拉寄存器

PC13引脚输出高电平:位13置位1
总结
- 打开时钟是能寄存器 RCC_AHB2ENR 位2写1
- 配置端口模式寄存器 GPIO_MODER 位27 26写为 0,1
- 端口输出类型寄存器 GPIOC_OTYPER 位 13置位 0
- 端口输出速度寄存器 GPIOC_OSPEEDR 位 27,26置位 0,0
- 端口上下拉寄存器 GPIOC_PUPDR 位 27 26 置位 0,0
- 配置输出数据寄存器 GPIOC_ODR 位13置位1
置0公式: 寄存器地址 &= ~(1 << n)
置1公式: 寄存器地址 |= (1 << n)
寄存器💡
1.创建一个文件

2.选择一个空的或者新建一个文件夹

3.芯片选型


4.新建一个C类型的文件


5.添加启动文件



6.添加以下系统初始化的函数
cpp
void SystemInit(void)
{
*(unsigned int*) 0xE000ED88|=((3UL << 20U)|(3UL << 22U));
}
int main(void)
{
}
寻找寄存器地址
RCC

GPIOC端口

打开时钟是能寄存器 RCC_AHB2ENR1 位2写1
0x56020c00+0x08c |=(1<<2);
0x56020c8c |=(1<<2);
配置端口模式寄存器 GPIOC_MODER 位27 26写为 0,1
0x52020800 &= ~(1<<27);
0x52020800 |= (1<<26);
端口输出类型寄存器 GPIOC_OTYPER 位 13置位 0
0x52020804 &= ~(1<<13);
端口输出速度寄存器 GPIOC_OSPEEDR 位 27,26置位 0,0
0x52020808 &= ~(1<<27);
0x52020808 &= ~(1<<26);
或者
0x52020808 &= ~(3<<26);
端口上下拉寄存器 GPIOC_PUPDR 位 27 26 置位 0,0
0x5202080c &= ~(3<<26);
配置输出数据寄存器 GPIOC_ODR 位13置位1
0x52020814 |= (1<<13);
代码实现
cpp
void SystemInit(void)
{
*(unsigned int*) 0xE000ED88|=((3UL << 20U)|(3UL << 22U));
}
int main(void)
{
//打开时钟是能寄存器 RCC_AHB2ENR1 位2写1
*(unsigned int*)0x56020c8c |=(1<<2);
//配置端口模式寄存器 GPIOC_MODER 位27 26写为 0,1
*(unsigned int*)0x52020800 &= ~(1<<27);
*(unsigned int*)0x52020800 |= (1<<26);
//端口输出类型寄存器 GPIOC_OTYPER 位 13置位 0
*(unsigned int*)0x52020804 &= ~(1<<13);
//端口输出速度寄存器 GPIOC_OSPEEDR 位 27,26置位 0,0
*(unsigned int*)0x52020808 &= ~(3<<26);
//端口上下拉寄存器 GPIOC_PUPDR 位 27 26 置位 0,0
*(unsigned int*)0x5202080c &= ~(3<<26);
//配置输出数据寄存器 GPIOC_ODR 位13置位1
*(unsigned int*)0x52020814 |= (1<<13);
}

风扇:PC6 马达PC7 蜂鸣器:PA15
HAL库💡
MX+KEIL5实现(主流,巨简单)
MX配置


配置完生成代码编译下载即可。
代码分析
原理图查询
下面我们以LD1为例进行原理图的查找
1.首先我们找到要控制的元器件,查看丝印为LD1,在拓展板上

2.我们打开拓展板的原理图找到了LD1所在的位置

由原理图分析可知,LED1连接的引脚输出高电平,LD1亮
2.LED1想要找到连接的芯片引脚就需要往核心板上靠近,拓展板必须通过排线连接到底板

3.找到J1上LED1连接的引脚

3.拓展板上的J1连接的是底板上的J6

4.打开底板的原理图找到J6的4号脚

5.底板通过底板上的排针槽J1和J2连接的核心板,所以,我们LED1想要链接到芯片上就必须经过这两个槽,所以去J1和J2上找LED1


6.底板上的J1的槽到核心板上是J2,底板的J2连的是核心板的J3


GPIO 相关 的 函数 接口
cpp
void HAL_GPIO_WritePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
功能:给指定引脚写入电平状态
参数:端口号
引脚号
GPIO_PIN_SET:高电平
GPIO_PIN_RESET:低电平
返回值:无
GPIO_PinState HAL_GPIO_ReadPin (const GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
功能:读取指定引脚的电平状态
参数:端口号
引脚号
返回值:电平状态
void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
功能:翻转指定引脚的电平状态
参数:端口号
引脚号
返回值:无
HAL_Delay(ms)
功能:延时函数
参数:毫秒级时间
灯光闪示例


- G P I O 输入 实验 (按键控制执行器)
实验要求
使用Key1来控制LED1灯
原理图分析


由原理图可知,当按键没有被按下的时候,KEY1连接的引脚检测到的是高电平。
当按键被按下的时候,key1连接的引脚读取到的是低电平。
我们要想检测按键是否被按下买只需要读取引脚读到低电平就可以了
KEY1:PC9
MX配置

延时 消抖

抬手检测

