目录
GPIO的工作模式介绍
1.输入模式(模拟、上拉、下拉、浮空)
2.输出模式(推挽/开漏)
3.复用功能(推挽/开漏)
4.模拟输入输出(上下拉无影响)
如何使用寄存器点亮第一个LED灯
GPIO的工作模式介绍
1.输入模式(模拟、上拉、下拉、浮空)
在输入模式时,施密特触发器打开,输出被禁止。可通过输入数据寄存器 GPIOx_IDR 读取 I/O 状态。输入模式可以配置为模拟、上拉、下拉以及浮空模 式。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候可以使用这个模式。 模拟输入则用于 ADC 采集。
2.输出模式(推挽/开漏)
在输出模式中,推挽模式时双 MOS 管以推挽方式工作,输出数据寄存器 GPIOx_ODR 可控制 I/O 输出高低电平。开漏模式时,只有 N-MOS 管工作,输出 数 据 寄 存 器 可 控 制 I/O 输 出 高 阻 态 或 低 电 平 。 输 出 速 度 可 配 置 , 有 2MHz\25MHz\50MHz 的选项。此处的输出速度即 I/O 支持的高低电平状态最高切 换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大 即可。在输出模式时,施密特触发器是打开的,即输入可用,通过输入数据寄存 器 GPIOx_IDR 可读取 I/O 的实际状态。
3.复用功能(推挽/开漏)
由于 STM32 的 GPIO 引脚具有第二功能,因此当使用复用功能的时候,也就 是通过其他外设复用功能输出信号与 GPIO 数据寄存器一起连接到双 MOS 管电路 的输入,其中梯形结构是用来选择使用复用功能还是普通 IO 口功能。例如我们 使用 USART 串口通讯时,需要用到某个 GPIO 引脚作为通讯发送引脚,这个时 候就可以把该 GPIO 引脚配置成 USART 串口复用功能,由串口外设控制该引脚, 发送数据。
复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式, 但是输出信号源于其它外设,输出数据寄存器 GPIOx_ODR 无效;输入可用,通 过输入数据寄存器可获取 I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。
4.模拟输入输出(上下拉无影响)
模拟输入输出模式中,双 MOS 管结构被关闭,施密特触发器停用,上/下拉 也被禁止。其它外设通过模拟通道进行输入输出。通过对 GPIO 寄存器写入不同 的参数,就可以改变 GPIO 的应用模式,再强调一下,要了解具体寄存器时一定 要查阅《STM32F1xx 参考手册》中对应外设的寄存器说明。在 GPIO 外设中,通 过设置“端口配置寄存器 GPIOx_CRL 和 GPIOx_CRH”可配置 GPIO 的工作模式和输出速度。CRH 控制端口的高八位,CRL控制端口的低八位。
以上内容均可结合官方普中科技视频讲解教程,链接如下。7.1-使用寄存器点亮第一个LED--GPIO概念及分类_哔哩哔哩_bilibili
如何使用寄存器点亮第一个LED灯
开发板上LED电路图如上,D1-D8 发光二极管阴极是连接 在 STM32 的 PC0-PC7 管脚上。如果要使 D1 指示灯亮,只需要控制 PC0 管脚输出 低电平,如果要使 D1 指示灯灭,只需控制 PC0 输出高电平。对于其他的 LED 控 制方法一样。如果你们使用的是其他板子,连接 LED 的管脚和极性不一样,查看数据手册,在程序中修改对应的 GPIO 管脚和输出电平状态即可,原理是一样的。
我们需要在外部定义一个 SystemInit 函数设置 STM32 的时钟; STM32 上电后,会执行 SystemInit 函数,最后执行我们C语言中的 main 函数。
那什么是时钟呢?
时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样, 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。
为什么 STM32 要有多个时钟源呢?
STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费。并且同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题。所以便有了STM32的时钟系统和时钟树。
具体内容可参考另一个大佬讲解,非常详细。【STM32】系统时钟RCC详解(超详细,超全面)_rcc时钟_Z小旋的博客-CSDN博客
接下来我们用1个小实验帮助我们理解寄存器点亮发光二极管的工作原理。
点亮 D1 发光二极管,让 STM32 的 PC0 管脚输出一个低电平
在stm32f10x.h中封装寄存器,代码如下
/*片上外设基地址*/
#define PERIPH_BASE ((unsigned int)0x40000000)
/*总线基地址*/
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
/*GPIO外设基地址*/
#define GPIOC_BASE (AHB2PERIPH_BASE + 0x1000)
/* GPIOB寄存器地址,强制转换成指针 */
#define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18)
/*RCC外设基地址*/
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB2时钟使能寄存器地址,强制转换成指针*/
#define RCC_AHB2ENR *(unsigned int*)(RCC_BASE+0x18)
封装好寄存器后,选择通用推挽输出模式,PC0引脚输出低电平
main函数代码如下
#include "stm32f10x.h"//使用寄存器时需要把头文件保存起来,否则编译报错。
/**
* 主函数
*/
//延时函数
void delay(unsigned int i)
{
while(i--);
}
int main(void)
{
/*开启 GPIOC 时钟,使用外设时都要先开启它的时钟*/
RCC_AHB2ENR|= (1<<4); //该寄存器第四位控制时钟使能端,为时钟开启。
//参考stm32F1XXx中文参考手册6.3.7
//设置为通用推挽输出模式,以下两条指令可以设置0,1,2,3管脚为1,1,0,0
//0,1负责输出模式最大速度50MHZ,2,3负责输出方式为通用推挽输出方式
GPIOC_CRL&= ~0x0F; //把低四位置0,端口清空
GPIOC_CRL|= 3; //0,1置1,设置为通用推挽输出方式
while(1)
{
// //PC0引脚输出低电平
// GPIOC_BSRR = (1<<(16+0));
// //LED闪烁
// delay(0xFFFFF);
// //PC0引脚输出高电平
// GPIOC_BSRR = (1<<(0+0));
// //LED闪烁
// delay(0xFFFFF);
//PC1引脚输出低电平
GPIOC_BSRR = (1<<(16+1));
delay(0xFFFFF);
//PC1引脚输出高电平
GPIOC_BSRR = (1<<(0+1));
//LED闪烁
delay(0xFFFFF);
}
}
// 函数为空,目的是为了骗过编译器不报错
void SystemInit(void)
{
}
将PC0管脚与LED1连接起来,将程序烧录,即可观察到实验现象。
文章来源:https://www.toymoban.com/news/detail-738620.html
既然已经掌握了如何点亮一个发光二极管,那么试试怎么同时点亮2个发光二极管?文章来源地址https://www.toymoban.com/news/detail-738620.html
到了这里,关于STM32F103ZET6 GPIO工作模式介绍+使用寄存器点亮第一个LED灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!