2.3 模擬輸入模式
在這里插入圖片描述
因為模擬信號經(jīng)過施密特觸發(fā)器后只有0/1兩種狀態(tài),因此信號源輸入在施密特觸發(fā)器前。類似地,當GPIO 引腳用于DAC 作為模擬電壓輸出通道時,DAC 的模擬信號輸出就不經(jīng)過雙MOS 管結構,模擬信號直接輸出到引腳。
模擬狀態(tài)與模擬外設復用引腳 區(qū)別 :
- 模擬狀態(tài):表示引腳功能選擇為模擬模式,但不作為任何片內(nèi)模擬外設(ADC)的復用引腳,只是為了減少系統(tǒng)功耗。
- 模擬外設復用引腳:表示引腳作為片內(nèi)模擬外設的復用引腳,用于完成相應功能操作,如ADC信號采集。
2.4 復用模式
在這里插入圖片描述
- 輸出可配置為推挽或者開漏模式,內(nèi)置外設的信號驅(qū)動輸出驅(qū)動器
- 施密特觸發(fā)器打開
- 弱上拉和下拉電阻被禁止
- 在每個APB2時鐘周期,出現(xiàn)在I/O腳上的數(shù)據(jù)被采樣到輸入數(shù)據(jù)寄存器
- 在開漏模式時,對輸入數(shù)據(jù)寄存器的讀訪問可得到I/O狀態(tài);在推挽式模式時,對輸出數(shù)據(jù)寄存器的讀訪問得到最后一次寫的
-
復用推挽輸出
: -
復用開漏輸出
:
- 對于復用的輸入功能,端口必須配置成輸入模式(浮空、上拉或下拉)且輸入引腳必須由外部驅(qū)動。
- 對于復用輸出功能,端口必須配置成復用功能輸出模式(推挽或開漏)。
- 對于雙向復用功能,端口位必須配置復用功能輸出模式(推挽或開漏)。
如果把端口配置成復用輸出功能,則引腳和輸出寄存器斷開,并和片上外設的輸出信號連接。
如果軟件把一個GPIO腳配置成復用輸出功能,但是外設沒有被激活,它的輸出將不確定。
注意 :
- STM32復位后,IO端口處于
浮空輸入
狀態(tài)(CNFx[1:0]=01b,MODEx[1:0]=00b
);JTAG引腳復位以后,處于上拉或者下拉狀態(tài)。 - stm32具有GPIO鎖定機制,即鎖定GPIO配置,下次復位前不能再修改端口位的配置。
- 所有IO端口都具有外部中斷能力,端口必須配置成輸入模式,才能使用外部中斷功能。
- 當LSE振蕩器關閉時,
OSC32_IN/OSC32_OUT
可以用作通用GPIOPC14/PC15
。當進入待機模式或者備份域由Vbat供電時,不能使用PC14/PC15
的GPIO口功能。 PC13/PC14/PC15
只能用于2MHz
的輸出模式(LSE關閉,PC13
關閉入侵檢測),最多只能帶30pF
的負載,而且這些I/O口絕對不能當作電流源(如驅(qū)動LED)。(參考STM32中文手冊4.1.2)- 一般上下拉電阻的阻值都在
30-50K
之間。這樣可以增強MCU的抗干擾能力。 - 芯片內(nèi)部上/下拉電阻不影響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-黃燈),系統(tǒng)時鐘啟動文件跳轉自動配置。
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文章
5301瀏覽量
119865 -
MOS
+關注
關注
31文章
1242瀏覽量
93368 -
GPIO
+關注
關注
16文章
1189瀏覽量
51850
發(fā)布評論請先 登錄
相關推薦
評論