2.3 模拟输入模式
在这里插入图片描述
因为模拟信号经过施密特触发器后只有0/1两种状态,因此信号源输入在施密特触发器前。类似地,当GPIO 引脚用于DAC 作为模拟电压输出通道时,DAC 的模拟信号输出就不经过双MOS 管结构,模拟信号直接输出到引脚。
模拟状态与模拟外设复用引脚 区别 :
- 模拟状态:表示引脚功能选择为模拟模式,但不作为任何片内模拟外设(ADC)的复用引脚,只是为了减少系统功耗。
- 模拟外设复用引脚:表示引脚作为片内模拟外设的复用引脚,用于完成相应功能操作,如ADC信号采集。
2.4 复用模式
在这里插入图片描述
- 输出可配置为推挽或者开漏模式,内置外设的信号驱动输出驱动器
- 施密特触发器打开
- 弱上拉和下拉电阻被禁止
- 在每个APB2时钟周期,出现在I/O脚上的数据被采样到输入数据寄存器
- 在开漏模式时,对输入数据寄存器的读访问可得到I/O状态;在推挽式模式时,对输出数据寄存器的读访问得到最后一次写的
-
复用推挽输出
: -
复用开漏输出
:
- 对于复用的输入功能,端口必须配置成输入模式(浮空、上拉或下拉)且输入引脚必须由外部驱动。
- 对于复用输出功能,端口必须配置成复用功能输出模式(推挽或开漏)。
- 对于双向复用功能,端口位必须配置复用功能输出模式(推挽或开漏)。
如果把端口配置成复用输出功能,则引脚和输出寄存器断开,并和片上外设的输出信号连接。
如果软件把一个GPIO脚配置成复用输出功能,但是外设没有被激活,它的输出将不确定。
注意 :
- STM32复位后,IO端口处于
浮空输入
状态(CNFx[1:0]=01b,MODEx[1:0]=00b
);JTAG引脚复位以后,处于上拉或者下拉状态。 - stm32具有GPIO锁定机制,即锁定GPIO配置,下次复位前不能再修改端口位的配置。
- 所有IO端口都具有外部中断能力,端口必须配置成输入模式,才能使用外部中断功能。
- 当LSE振荡器关闭时,
OSC32_IN/OSC32_OUT
可以用作通用GPIOPC14/PC15
。当进入待机模式或者备份域由Vbat供电时,不能使用PC14/PC15
的GPIO口功能。 PC13/PC14/PC15
只能用于2MHz
的输出模式(LSE关闭,PC13
关闭入侵检测),最多只能带30pF
的负载,而且这些I/O口绝对不能当作电流源(如驱动LED)。(参考STM32中文手册4.1.2)- 一般上下拉电阻的阻值都在
30-50K
之间。这样可以增强MCU的抗干扰能力。 - 芯片内部上/下拉电阻不影响GPIO输出模式。
3 GPIO模块寄存器
注意 :必须以字(32位)的方式操作GPIO外设寄存器!
端口模式与输出速度配置:
(//file.elecfans.com/web2/M00/8C/10/pYYBAGPXZCGACOv3AALmvH1WBmE220.jpg)
GPIO寄存器地址映像和复位值:
GPIO外设基地址与相对于APB2总线(0x4001 0000
)的偏移地址:
GPIO外设 | 基地址 | 相对APB2总线偏移地址 |
---|---|---|
GPIOA | 0x4001 0800 | 0x0000 0800 |
GPIOB | 0x4001 0C00 | 0x0000 0C00 |
GPIOC | 0x4001 1000 | 0x0000 1000 |
GPIOD | 0x4001 1400 | 0x0000 1400 |
GPIOE | 0x4001 1800 | 0x0000 1800 |
GPIOF | 0x4001 1C00 | 0x0000 1C00 |
GPIOG | 0x4001 2000 | 0x0000 2000 |
4 应用示例
直接使用寄存器点灯(PA8-红灯 PD2-黄灯),系统时钟启动文件跳转自动配置。
led.h
:
#ifndef __LED_H
#define __LED_H
#include
typedef unsigned int uint32_t;
#define _IO volatile
#define _I volatile const
#define _O volatile
#define PERIPH_BASE 0x40000000UL
#define APB1_BASE PERIPH_BASE
#define APB2_BASE (PERIPH_BASE + 0x10000)
#define AHB_BASE (PERIPH_BASE + 0x20000)
#define GPIOA_BASE (APB2_BASE + 0x0800)
#define GPIOD_BASE (APB2_BASE + 0x1400)
#define RCC_BASE (AHB_BASE + 0x1000)
typedef struct
{
_IO uint32_t CRL;
_IO uint32_t CRH;
_I uint32_t IDR;
_IO uint32_t ODR;
_IO uint32_t BSRR;
_IO uint32_t BRR;
_IO uint32_t LCKR;
} GPIO_Init_t;
typedef struct
{
_IO uint32_t CR;
_IO uint32_t CFGR;
_IO uint32_t CIR;
_IO uint32_t APB2RSTR;
_IO uint32_t APB1RSTR;
_IO uint32_t AHBENR;
_IO uint32_t APB2ENR;
_IO uint32_t APB1ENR;
_IO uint32_t BDCR;
_IO uint32_t CSR;
} RCC_t;
#define GPIOA ((GPIO_Init_t*)GPIOA_BASE)
#define GPIOD ((GPIO_Init_t*)GPIOD_BASE)
#define RCC ((RCC_t *) RCC_BASE)
#define RED_LED_GPIO_PORT GPIOA
#define RED_LED_GPIO_PIN (0x0100) // PIN8
#define YELLOW_LED_GPIO_PORT GPIOD
#define YELLOW_LED_GPIO_PIN (0x0004) // PIN2
#define RED_LED_ON (RED_LED_GPIO_PORT->BRR |= RED_LED_GPIO_PIN)
#define RED_LED_OFF (RED_LED_GPIO_PORT->BSRR |= RED_LED_GPIO_PIN)
#define RED_LED_TOGGLE (RED_LED_GPIO_PORT->ODR ^= RED_LED_GPIO_PIN)
#define YELLOW_LED_ON (YELLOW_LED_GPIO_PORT->BRR |= YELLOW_LED_GPIO_PIN)
#define YELLOW_LED_OFF (YELLOW_LED_GPIO_PORT->BSRR |= YELLOW_LED_GPIO_PIN)
#define YELLOW_LED_TOGGLE (YELLOW_LED_GPIO_PORT->ODR ^= YELLOW_LED_GPIO_PIN)
void LED_Init(void);
#endif /* __LED_H */
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
led.c & main.c
:
void LED_Init(void)
{
RCC->APB2ENR |= 1 << 2; // PortA
RCC->APB2ENR |= 1 << 5; // PortD
RED_LED_GPIO_PORT->CRH &= ~(0x0f << (0 * 4));
RED_LED_GPIO_PORT->CRH |= 0x03 << (0 * 4);
RED_LED_GPIO_PORT->BSRR |= 0x01 << 8;
YELLOW_LED_GPIO_PORT->CRL &= ~(0x0f << (2 * 4));
YELLOW_LED_GPIO_PORT->CRL |= 0x03 << (2 * 4);
YELLOW_LED_GPIO_PORT->BSRR |= 0x01 << 2;
}
int main()
{
LED_Init();
while(1)
{
YELLOW_LED_TOGGLE;
HAL_Delay(500);
}
}
1234567891011121314151617181920212223
END
-
寄存器
+关注
关注
31文章
5305浏览量
119914 -
MOS
+关注
关注
32文章
1244浏览量
93405 -
GPIO
+关注
关注
16文章
1191浏览量
51870
发布评论请先 登录
相关推荐
评论