当前位置:   article > 正文

STM32-GPIO(江协科技学习笔记)_stm32 gpio

stm32 gpio

目录

1、工程结构

2、系统结构

3、GPIO位结构

4、GPIO模式

5、ELD和蜂鸣器

6、标准库中常见的GPIO函数及其用法


1、工程结构

2、系统结构

在STM32中,所有的GPIO都是挂载在APB2外设总线上的。

APB1(Advanced Peripheral Bus 1)和APB2,它们是AHB(Advanced High-performance Bus)的从属总线。两个AHB/APB桥在AHB2APB总线间提供同步连接。APB1操作速度限于36MHzAPB2操作于全速(最高72MHz)
注意: 当对 APB 寄存器进行 8 位或者 16 位访问时,该访问会被自动转换成 32 位的访问:桥会自动将 8 或者 32 位的数据扩展以配合 32 位的向量

3、GPIO位结构

(1)施密特触发器:对输入电压进行整形。其执行逻辑为:如果输入电压大于某一阈值,输出就会瞬间升为高电平

(2)模拟输入:这个是连接到ADC(片上外设)上的,因为ADC需要接收模拟量,所以接到施密特触发器前面。

(3)复用功能输入:这个是连接到其他需要读取端口的外设上的,比如串口的输入引脚等,这根线接收的是数字量,所以接到施密特触发器后面。

(4)输出数据寄存器(ODR):写其的某一位就可以操作对应的某个端口。

(5)位设置/清除寄存器:可用来单独操作输出数据寄存器的某一位,而不是影响其他位。因为输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以想单独控制其中某一个端口而不影响其他端口的话,就需要一些特殊的方式:

  • 先读出这个寄存器,然后用按位与和按位或的方式更改某一位(&=  |=),最后再将更改后的数据写回去。但这种方法效率不高且麻烦,对IO口的操作而言不太合适

  • 通过设置这个位设置/清除寄存器,如果我们要对某一位置1,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样它内部就会有电路自动将位设置寄存器中对应位置1,而剩下写0的位保持不变。保证了只操作其中某一位而不影响其它位,并且这是一步到位的操作。如果想对某一位进行清0的操作,就在位清除寄存器的对应位写1即可,内部电路会把这一位清0.

  • 读写STM32中的“位带”区域,这个位带的作用跟51单片机的位寻址作用差不多。在STM32中,专门分配有一段地址区域,这段地址映射了RAM和外设寄存器所有的位,读取这段地址中的数据,就相当于读写所映射位置的某一位,这就是位带的操作方式。

输出模式

控制开关

工作方式

特点

推挽输出

P-MOS、N-MOS均有效

数据寄存器为1时,上管导通,下管断开,输出直接接到VDD,即高电平;反之则是低电平

这种模式下,高低电平均有较强的驱动能力,所以推挽输出模式也可以叫强推输出模式(STM32对IO口具有绝对的控制权,高低电平都由STM32说了算)

开漏输出

P-MOS无效、N-MOS均有效

数据寄存器为1时,下管断开,下管断开,输出相当于断开,即高阻模式。数据寄存器为0时,下管导通,输出直接接到VSS,即输出低电平。这种模式下,只有低电平有驱动能力,高电平没有驱动能力。

这个开漏模式可以作为通信协议的驱动方式,比如I2C通信的引脚,就是使用的开漏模式。在多机通信的情况下,这个模式可以避免各个设备的相互干扰。另外开漏模式还可以用于输出5V的电平信号。

关闭

P-MOS、N-MOS均有效

当引脚配置为输入模式的时候,输出关闭,端口的电平由外部信号来控制

4、GPIO模式

(1)1、2、3模式的电路结构基本一样,区别就是上拉电阻和下拉电阻的连接。

(浮空输入下,端口一定要接上一个连续的驱动源,不能出现悬空的状态)

(2)

(3)

(4)

GPIO_Mode_AIN

Analog In--模拟输入

GPIO_Mode_IN_FLOATING

Floating--浮空输入

GPIO_Mode_IPD

In Pull Down--下拉输入

GPIO_Mode_IPU

In Pull Up--上拉输入

GPIO_Mode_OUT_OD

Out Open Drain--开漏输出

GPIO_Mode_OUT_PP

Out Push Pull--推挽输出(点灯 )

GPIO_Mode_AF_OD

Atl Open Drain--复用开漏

GPIO_Mode_AF_PP

Atl Push Pull--复用推挽

5、ELD和蜂鸣器

LED:长正短负,小正大负。

以上图为例,将P1^2引脚接低电平,蜂鸣器响,接高电平,蜂鸣器关闭(低电平触发)。

(1)低电平驱动LED:当PA0输出低电平时,LED两端就会产生电压差,从而形成正向导通的电流,LED点亮。 

该GPIO在推挽输出模式下,高低电平均有比较强的驱动能力,故两种接法均可。但在单片机的电路里,一般使用低电平驱动,因为很多单片机或者芯片都使用了“高电平弱驱动,低电平强驱动”的规则。

(2)蜂鸣器电路使用了三极管开关的驱动方案(最简单的驱动电路)(对于功率稍微大一点的电路,直接用IO口驱动会导致STM32负担过重)。三极管左边的是基极,带箭头的是发射极,剩下的是集电极。

PNP三极管:基极给低电平三极管导通, 蜂鸣器有电流,反之没有。

NPN三极管:相反。

(PNP的三极管接在蜂鸣器上面,而NPN的三极管接在蜂鸣器下面,因为三极管的通断需要在发射极和基极直接产生一定的开启电压,若反过来可能导致三极管不能开启)

(3)在PA0口输出高低电平,驱动LED闪烁

(注意因为配置的是GPIO,所以要使用APB2外设总线)

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. int main(void)
  4. {
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // RCC的APB2外设时钟控制函数(PA0-GPIOA,使能)
  6. GPIO_InitTypeDef GPIO_InitStructure;
  7. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  8. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //选择0号端口
  9. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  10. GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIO初始化(GPOIX, )第二个参数是一个结构体,需要先把结构体类型复制下来,再在前面定义
  11. // GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 设置指定端口为低电平
  12. // GPIO_SetBits(GPIOA, GPIO_Pin_0); // 设置指定端口为高电平
  13. // GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); // 设置指定端口为高电平
  14. // GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); // 设置指定端口为低电平
  15. // GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0); // 将0强制转换为BitAction的枚举类型,低电平
  16. // GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1); // 将1强制转换为BitAction的枚举类型,高电平
  17. while(1)
  18. {
  19. GPIO_ResetBits(GPIOA, GPIO_Pin_0);
  20. Delay_ms(500);
  21. GPIO_SetBits(GPIOA, GPIO_Pin_0);
  22. Delay_ms(500);
  23. //直接法
  24. GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
  25. Delay_ms(500);
  26. GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
  27. Delay_ms(500);
  28. //枚举法
  29. GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);
  30. Delay_ms(500);
  31. GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
  32. Delay_ms(500);
  33. }
  34. }

6、标准库中常见的GPIO函数及其用法

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

读取输入数据寄存器某引脚的输入值

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

读取输入数据寄存器全部的输入值

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

读取输出数据寄存器某引脚的输入值

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

读取输入数据寄存器全部的输入值

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

设置指定端口为低电平

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

设置指定端口为高电平

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

一般可以实现批量或者同时控制多个 GPIO 引脚的输出状态

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

用来单独设置某一个特定的 GPIO 引脚的输出状态

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号