文章目录
前言
第一次编写程序就是输出hello world,第一次编程单片机就是点灯。
点灯中需要使用到GPIO,可以说GPIO是在玩单片机中第一个接触的输入输出接口。
1.stm32f103zet6 的GPIO简介
stm32f103zet6 一共有7组IO口, 每组IO口有16个IO,一共16X7=112个IO
其基本功能如下
- 输入、输出功能
- 所有IO口都有 外部中断能力 端口必须配置成输入模式,才能使用外部中断功能.
- IO端口复用功能(最大化利用stm32的资源)
- IO端口重映射功能(方便布线)
2.stm32中GPIO工作方式(共8种)
stm32中 gpio的工作方式有输入和输出两种,在输入,输出模式中又细分出好几种的细分模式。
输入四种方式
- 浮空输入
浮空输入(input floating), 不接上拉电阻和下拉电阻,即输入引脚即不接高电平,也不接低电平。
IO引脚状态完全由外部输入所决定,这是CPU能够通过读数据寄存器的操作知道IO口的状态。
- 上拉输入
带上拉的输入(input pull-up),接一个上拉电阻。
当引脚被设置为上拉输入,无输入信号时,CPU读取到的状态是状态为高电平;
当被外部输入信号为低电平时,CPU读取到的状态为低电平。
- 下拉输入
带下拉的输入(input pull-down), 接一个下拉电阻。
引脚被设置为下拉输入时, 引脚悬空的状态下,CPU读到的状态是低电平;
当被外部输入信号为高电平时,CPU读取的电平为高电平。
- 模拟输入(input analog)
引脚设置为模拟输入进,能够获取的模拟信号,可以通过ADC转换为数字量,如变化的电压值。
原理:TTL施密特触发器关闭,CPU不能直接读取IO口的电平状态,io口电平状态直接输入到片上外设模块中。
输出的四种方式
-
推挽输出(Push-Pull):
推挽输出, 可以输出高、低电平。
推挽电路是由两个三极管或MOSFET,以推挽方式存在于电路中,电路工作时,两只对称的开关管每次只有一个导通,所以导通损耗小、效率高、既提高电路的负载能力,又提高开关速度。
推挽输出电路如下:
- 内部输出1时
上边的MOS管导通同时下边的MOS管截至,IO口输出高电平。 - 内部输出0时
上边的MOS管截至同时下边的MOS管导通,IO口输出低电平。
- 内部输出1时
-
开漏输出(Open-Drain):
只可以输出低电平,不能输出高电平。想输出高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强
开漏输出电路如下
- 内部输出1
此时MOS管截止,输出与地断开,IO口输出显示高阻态。(高阻态可以理解成断路,电阻非常高)
这时候IO口其实是没有驱动能力的,需要外部连接上拉电阻才能输出高电平,才能驱动数字器件。 - 内部输出0
此时MOS管导通,IO口输出低电平。
- 内部输出1
-
复用推挽输出、复用开漏输出
这两种模式,可以理解为把GPIO配置为第二功能使用的时候的配置,并非作为通用IO口使用。
比如使用外设I2C时,需要把GPIO配置为复用开漏输出,用于数据通信功能。
再比如串口通信的TX,以及SPI外设的GPIO使用就要把引脚设置为复用推挽输出。
注意:GPIO没有模拟输出
GPIO引脚本身只能输出高电平(如3.3V或5V,取决于控制器)或低电平(如0V或接地)
我们可以通过几种技术来模拟更平滑或变化的电压输出,以实现类似模拟输出的效果。以下是一些常见的方法:
- PWM(脉冲宽度调制)
PWM是最常用的模拟输出方法之一。通过快速切换GPIO引脚的高电平和低电平,并且调整高电平所占的时间比例(即占空比),可以在连接到该引脚的元件(如LED、电机驱动器或DAC输入)上产生平均电压的效果。 - DAC(数模转换器)
DAC芯片可以直接将数字信号转换为模拟信号。如果你的项目需要高精度或连续的模拟电压输出,DAC是更好的选择。然而,大多数微控制器本身不包含DAC,需要外部DAC芯片或使用内置的模拟比较器(如果有的话)来实现类似功能。 - 软件模拟(针对简单的需求)
对于非常简单的模拟输出需求(如调整LED亮度),并且不需要非常精确的电压控制,你可以通过软件延迟来控制GPIO引脚的高低电平持续时间,以此模拟PWM。虽然这种方法效率较低且精度有限,但它不需要额外的硬件或PWM支持。
3.GPIO3种最大翻转速度
输出信号电平的反转是有时间的,stm32通过控制输出引脚的反转频率,来控制输出电平的翻转最大速度。
频率越高,反转越快,波形越陡峭。
- 2Mhz
2Mhz的翻转速度比较慢。 - 10Mhz
相对于2Mhz,10Mhz的翻转速度块很多,波形更陡峭。 - 50Mhz
4.每组GPIO端口的寄存器
配置每组GPIO的寄存器数目有 7个。
操作寄存器的要求:IO端寄存器必须按32位字被访问,不允许 半字-16位 或 字节-8位 访问
每组GPIO的配置寄存器具体有
GPIO配置寄存器(2个)
配置一个GPIO口的输入输出模式及其频率需要4个位,如下图所示。
因为一组GPIO有16个GPIO口,416=64=232,所有一组GPIO需要2个配置寄存器用来配置GPIO的模式,这两寄存器分别是CRL和CRH。
数据寄存器(两个)
数据寄存器一个是输入寄存器,另一个是输出寄存器。
端口输入寄存器(Input-Data-Register),只用16位,用来表示一组GPIO口的输入高低电平,0表示低电平,1表示高电平。
输出寄存器同输入寄存器,只用16个位,用来表示一组GPIO口的输出电平。
32位置位/复位寄存器(1个)
GPIOx_BSRR:端口位设置/清除寄存器
16位复位寄存器(1个)
GPIOx_BRR :端口位清除寄存器
32位锁定寄存器(1个)
用来锁定CRL、CRH的配置状态(存疑)
5.stm32配置GPIO口
思路
1、配置GPIO的引脚的模式
2、在对应的引脚输出一个电平
代码
配置GPIOA_0,GPIOA_1位输出模式,50MHz,CNF[1:0]和MODE0[1:0]应该为0011。
GPIOA->CRL = 0x33;//0x00000033前面的零是可以省略的
GPIOA->ORD = 0x00;
GPIOA->ODR = 0x3;
软件仿真验证
1、初始复位状态
2、执行GPIOA->CRL = 0x33;
3、执行GPIOA->ODR = 0x00;
4、执行GPIOA->ODR = 0x3;
5种配置GPIO的方式
1)作为普通 GPIO 输入:根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时不要使能该引脚对应的所有复用功能模块。
2)作为普通 GPIO 输出:根据需要配置该引脚为推挽输出或开漏输出,同时不要使能该引脚对应的所有复用功能模块。
3)作为普通模拟输入:配置该引脚为模拟输入模式,同时不要使能该引脚对应的所有复用功能模块。
4)作为内置外设的输入:根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时使能该引脚对应的某个复用功能模块。
5)作为内置外设的输出:根据需要配置该引脚为复用推挽输出或复用开漏输出,同时使能该引脚对应的所有复用功能模块。