国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32外設(shè)GPIO(學(xué)習(xí)筆記)

這篇具有很好參考價(jià)值的文章主要介紹了STM32外設(shè)GPIO(學(xué)習(xí)筆記)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

在編寫stm32程序時(shí),對(duì)寄存器進(jìn)行操著需要知道每個(gè)外設(shè)的基地址,標(biāo)準(zhǔn)庫(kù)的stm32f10x.h文件里也有各種外設(shè)的基地址。

比如GPIO:在定義輸出數(shù)據(jù)寄存器地址GPIOA_ODR_Addr時(shí),在GPIOA_BASE(GPIO端口A的基址地址)地址基礎(chǔ)上偏移

#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 

在stm32f10x.h文件里面有定義GPIOA_BASE,是APB2PERIPH_BASE(APB2(Advanced Peripheral Bus 2)總線的基址地址,高速總線)偏移0x0800

APB2PERIPH_BASE是在PERIPH_BASE地址基礎(chǔ)上偏移0x10000

PERIPH_BASE地址就是表示內(nèi)存地址空間的起始地址

/**********************************************************/
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)



/**********************************************************/
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)



/**********************************************************/
#define PERIPH_BASE           ((uint32_t)0x40000000)

//通用IO口地址映射表

STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記

typedef struct
{
? __IO uint32_t CRL;         // 端口配置低寄存器, 地址偏移 0X00
? __IO uint32_t CRH;         // 端口配置高寄存器, 地址偏移 0X04
? __IO uint32_t IDR;         // 端口數(shù)據(jù)輸入寄存器, 地址偏移 0X08
? __IO uint32_t ODR;         // 端口數(shù)據(jù)輸出寄存器, 地址偏移 0X0C
? __IO uint32_t BSRR;        // 端口位設(shè)置/清除寄存器,地址偏移 0X10
? __IO uint32_t BRR;         // 端口位清除寄存器, 地址偏移 0X14
? __IO uint32_t LCKR;        // 端口位鎖定寄存器, 地址偏移 0X18
} GPIO_TypeDef;

這段代碼定義了一個(gè)名為GPIO_TypeDef的結(jié)構(gòu)體類型,這是一種通用輸入輸出端口(GPIO)的類型定義。

"__IO"前綴相當(dāng)于代表了C 語言中的關(guān)鍵字“volatile”,在 C 語言中該關(guān)鍵字用于表示變量是易變的,要求編譯器不要優(yōu)化。因?yàn)镚PIO_TypeDef這個(gè)結(jié)構(gòu)體里面都對(duì)應(yīng)著寄存器,經(jīng)常由外設(shè)或者STM32芯片狀態(tài)修改,即使CPU不去改變這些寄存器內(nèi)的值,這些寄存器內(nèi)的值也會(huì)發(fā)生變化,當(dāng)使用這些變量時(shí),就要求CPU重新去訪問地址讀取數(shù)據(jù),若沒有“__IO”前綴,就會(huì)從CPU某個(gè)緩存區(qū)讀取沒及時(shí)更新的舊的數(shù)據(jù)。

下面是結(jié)構(gòu)體中每個(gè)成員的含義:

  1. CRL(Configuration Low Register)- 低字節(jié)配置寄存器,用于配置端口低8位引腳的模式、速度和上拉/下拉選擇。
  2. CRH(Configuration High Register)- 高字節(jié)配置寄存器,用于配置端口高8位引腳的模式、速度和上拉/下拉選擇。
  3. IDR(Input Data Register)- 輸入數(shù)據(jù)寄存器,用于存儲(chǔ)輸入引腳的狀態(tài)。
  4. ODR(Output Data Register)- 輸出數(shù)據(jù)寄存器,用于存儲(chǔ)輸出引腳的狀態(tài)。
  5. BSRR(Bit Set/Reset Register)- 位設(shè)置/復(fù)位寄存器,用于單獨(dú)設(shè)置或復(fù)位引腳的狀態(tài)。
  6. BRR(Bit Reset Register)- 位復(fù)位寄存器,用于復(fù)位引腳的狀態(tài)。
  7. LCKR(Lock Register)- 鎖寄存器,用于鎖定GPIO的配置寄存器,防止意外修改。

在使用庫(kù)函數(shù)時(shí),里面經(jīng)常會(huì)看到下面這些:

#define I2C1                ((I2C_TypeDef *) I2C1_BASE)
#define EXTI                ((EXTI_TypeDef *) EXTI_BASE)
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define ADC1                ((ADC_TypeDef *) ADC1_BASE)
#define TIM1                ((TIM_TypeDef *) TIM1_BASE)
#define SPI1                ((SPI_TypeDef *) SPI1_BASE)
#define USART1              ((USART_TypeDef *) USART1_BASE)

比如#define GPIOA ? ? ? ? ? ? ? ((GPIO_TypeDef *) GPIOA_BASE)為例,定義GPIO_TypeDef結(jié)構(gòu)體指針,結(jié)構(gòu)體里面成員的類型和分布順序是和寄存器里面一一對(duì)應(yīng)的(結(jié)構(gòu)體里面成員是32位的(即四個(gè)字節(jié)),下表GPIO寄存器里面也是每一個(gè)偏移4個(gè)字節(jié))

STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記

然后就可以通過該結(jié)構(gòu)體指針就可以直接操作

STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記

用操作寄存器寫一個(gè)配置GPIO的示例程序:(知道就行)

#include "stm32f10x.h"

void GPIOA_PinConfig(uint32_t GPIO_Pin)
{
    // 1. 使能GPIOA的時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 2. 獲取GPIOA對(duì)應(yīng)的寄存器地址
    GPIO_TypeDef *GPIOx = GPIOA; // 指向GPIOA寄存器的指針

    // 3. 配置引腳為復(fù)用推挽模式(AF_PP)
    GPIOx->CRH &= ~(0x0F << (4 * GPIO_Pin)); // 清除模式位
    GPIOx->CRH |= (GPIO_Mode_Out_PP << (4 * GPIO_Pin)); // 設(shè)置模式位

    // 4. 配置輸出速度
    GPIOx->CRH &= ~(0x03 << (2 * GPIO_Pin)); // 清除速度位
    GPIOx->CRH |= (GPIO_Speed_50MHz << (2 * GPIO_Pin)); // 設(shè)置輸出速度
}

int main(void)
{
    // 系統(tǒng)初始化
    SystemInit();

    // 配置GPIOA的第0號(hào)引腳
    GPIOA_PinConfig(GPIO_Pin_0);

    // 主循環(huán)
    while (1)
    {

    }
}
  1. 使能GPIOA的時(shí)鐘?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);?這行代碼是用來使能STM32的時(shí)鐘控制模塊(RCC)中GPIOA端口的時(shí)鐘。在STM32中,GPIO端口是映射到APB2總線上的,所以使用RCC_APB2PeriphClockCmd函數(shù)來控制其時(shí)鐘。ENABLE是一個(gè)參數(shù),表示使能時(shí)鐘。

  2. 獲取GPIOA對(duì)應(yīng)的寄存器地址?GPIO_TypeDef *GPIOx = GPIOA; // 指向GPIOA寄存器的指針?這里定義了一個(gè)指向GPIOA端口寄存器的指針。GPIO_TypeDef是STM32的寄存器定義結(jié)構(gòu)體,用于存放端口的寄存器地址。GPIOx是一個(gè)類型為GPIO_TypeDef的指針變量,通過這個(gè)指針可以訪問到GPIOA的所有寄存器。

  3. 配置引腳為復(fù)用推挽模式(AF_PP)?GPIOx->CRH &= ~(0x0F << (4 * GPIO_Pin)); // 清除模式位?GPIOx->CRH |= (GPIO_Mode_Out_PP << (4 * GPIO_Pin)); // 設(shè)置模式位?這兩行代碼用于配置GPIOA的某一個(gè)引腳的模式。CRH是GPIOA端口的高字節(jié)寄存器,用于控制第11到第15引腳的配置。GPIO_Pin是一個(gè)宏,代表你要配置的引腳編號(hào)。0x0F是一個(gè)十六進(jìn)制數(shù),左移四位后用來清除模式位。GPIO_Mode_Out_PP是一個(gè)宏,代表復(fù)用推挽輸出模式。這兩行代碼的組合效果就是清除原來的模式位并設(shè)置新的模式位,將引腳配置為復(fù)用推挽模式。

  4. 配置輸出速度?GPIOx->CRH &= ~(0x03 << (2 * GPIO_Pin)); // 清除速度位?GPIOx->CRH |= (GPIO_Speed_50MHz << (2 * GPIO_Pin)); // 設(shè)置輸出速度?這里設(shè)置GPIOA引腳的輸出速度。CRH寄存器的高四位用于設(shè)置輸出速度。GPIO_Speed_50MHz是一個(gè)宏,表示輸出速度為50MHz。通過清除原來的速度位并設(shè)置新的速度位,將引腳的輸出速度配置為50MHz。

用標(biāo)準(zhǔn)庫(kù)函數(shù)寫一個(gè)配置GPIO的示例程序:

#include "stm32f10x.h"

void GPIOA_PinConfig(void)
{
    // 1. 首先,我們需要使能GPIOA的時(shí)鐘,這樣相關(guān)的寄存器才能被訪問
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 2. 配置GPIOA的第0號(hào)引腳為復(fù)用推挽模式(AF_PP),用于輸出
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 選擇PA0
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 復(fù)用推挽模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 輸出速度為50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA的第0號(hào)引腳
}

int main(void)
{
    // 系統(tǒng)初始化
    SystemInit();

    // 配置GPIOA的第0號(hào)引腳
    GPIOA_PinConfig();

    // 主循環(huán)
    while (1)
    {
    }
}

標(biāo)準(zhǔn)庫(kù)的GPIO庫(kù)函數(shù):

void GPIO_DeInit(GPIO_TypeDef* GPIOx);
void GPIO_AFIODeInit(void);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
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_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

1.void GPIO_DeInit(GPIO_TypeDef* GPIOx);

????????將GPIOx外設(shè)寄存器初始化為其默認(rèn)重置值。

  // 假設(shè)此時(shí)你需要重置GPIOB到默認(rèn)狀態(tài)
  GPIO_DeInit(GPIOB);

2.void GPIO_AFIODeInit(void);

????????取消初始化備用函數(shù)(重新映射、事件控制和EXTI配置)注冊(cè)到它們的默認(rèn)重置值。

? ? ? ? 通俗講:將AFIO模塊的配置恢復(fù)到出廠默認(rèn)設(shè)置。包括將所有復(fù)用功能配置重置為GPIO模式,確保沒有其他外設(shè)占用這些端口。在系統(tǒng)復(fù)位或初始化時(shí)調(diào)用這個(gè)函數(shù),可以確保所有的GPIO端口都是按照預(yù)期的方式配置的。

3.void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

????????根據(jù)指定初始化GPIOx外設(shè)GPIO_InitStruct中的*參數(shù)。

????????void?表示函數(shù)沒有返回值。

????????GPIO_Init?是函數(shù)名。

????????GPIO_TypeDef* GPIOx?是函數(shù)的第一個(gè)參數(shù),它是一個(gè)指向?GPIO_TypeDef?類型的指針,這個(gè)類型定義了GPIO端口的相關(guān)結(jié)構(gòu)和特性。GPIOx?通常用來指代不同的GPIO端口,比如?GPIOA,?GPIOB,?GPIOC?等。

????????GPIO_InitTypeDef* GPIO_InitStruct?是函數(shù)的第二個(gè)參數(shù),它是一個(gè)指向?GPIO_InitTypeDef?類型的指針,這個(gè)類型定義了GPIO端口的初始化結(jié)構(gòu)體,包含了端口的各種配置選項(xiàng),如模式、速度、輸出類型、輸出速度、上下拉配置等。

????????這個(gè)函數(shù)的作用是根據(jù)?GPIO_InitStruct?結(jié)構(gòu)體中指定的參數(shù)來配置?GPIOx?端口的相關(guān)特性。例如,你可以設(shè)置端口為輸入模式,并配置內(nèi)部上下拉電阻;或者設(shè)置端口為輸出模式,并配置輸出速度和類型。

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);

4.void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)

????????用默認(rèn)值填充每個(gè)GPIO_InitStruct成員。

? ? ? ? 將配置好的GPIO_InitStructure結(jié)構(gòu)體成員恢復(fù)默認(rèn)。

5.uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

????????讀取指定的輸入端口引腳。

// 讀取GPIOx的Pin0的狀態(tài)
uint8_t pin_state = GPIO_ReadInputDataBit(GPIOx, GPIO_Pin_0);

/*返回(uint8_t)Bit_SET或者(uint8_t)Bit_RESET;*/

6.uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

????????讀取指定的GPIO輸入數(shù)據(jù)端口。

    while (1)
    {
        // 讀取GPIOx的所有引腳的狀態(tài)
        uint16_t input_data = GPIO_ReadInputData(GPIOx);

        // 檢查每個(gè)引腳的狀態(tài)
        for (int i = 0; i < 16; i++) { // 假設(shè)GPIOA有16個(gè)引腳
            if ((input_data & (1 << i)) != 0) {
                // 如果第i個(gè)引腳是高電平
                printf("Pin %d is HIGH\n", i);
            } else {
                // 如果第i個(gè)引腳是低電平
                printf("Pin %d is LOW\n", i);
            }
        }
    }

先定義了要使用的 GPIO 端口。然后在主循環(huán)中,使用?GPIO_ReadInputData?函數(shù)來讀取 GPIOA 端口的所有引腳的狀態(tài)。我們將讀取的數(shù)據(jù)循環(huán)檢查每個(gè)引腳的狀態(tài),并通過printf函數(shù)輸出是高電平還是低電平。

7.uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

????????讀取指定的輸出數(shù)據(jù)端口位。

8.uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

????????讀取指定的GPIO輸出數(shù)據(jù)端口。

9.void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);將GPIOx的GPIO_Pin_x腳置高電平。
? ?void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);將GPIOx的GPIO_Pin_x腳置低電平。

10.void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);設(shè)置或清除所選數(shù)據(jù)端口位。
? ? ?void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);將數(shù)據(jù)寫入指定的GPIO數(shù)據(jù)端口。

        // 切換GPIOA的Pin0和Pin1的狀態(tài)
        GPIO_WriteBit(GPIOA, GPIO_PIN0, Bit_RESET);
        GPIO_WriteBit(GPIOA, GPIO_PIN1, Bit_SET);

    // 設(shè)置GPIOA的所有引腳為高電平
    uint16_t all_pins = 0xFFFF; // 16位全為1,表示所有引腳
    GPIO_Write(GPIOA, all_pins);

11.void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

????????鎖定GPIO引腳配置寄存器。
12.void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

????????選擇用作事件輸出的GPIO引腳。

? ? ?void GPIO_EventOutputCmd(FunctionalState NewState);

????????啟用或禁用事件輸出。

#include "stm32f10x.h"

// 假設(shè)我們使用GPIOA的Pin0作為事件輸出源
#define GPIO_PortSource GPIOA
#define GPIO_PinSource GPIO_Pin_0

void EXTI0_IRQHandler(void) // EXTI0中斷處理函數(shù)
{
    // 檢查是否是GPIOA的Pin0產(chǎn)生的中斷
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 清除中斷標(biāo)志
        EXTI_ClearITPendingBit(EXTI_Line0);

        // 這里添加中斷處理代碼
        printf("GPIOA Pin0 interrupt occurred!\n");
    }
}

int main(void)
{
    // 系統(tǒng)初始化代碼(略)

    // 配置GPIOA的Pin0作為事件輸出源!!!!!!!!!!!
    GPIO_EventOutputConfig(GPIO_PortSource, GPIO_PinSource);
    // 啟用GPIOA的Pin0的事件輸出功能
    GPIO_EventOutputCmd(GPIO_PortSource, GPIO_PinSource, ENABLE);

    // 配置GPIOA的Pin0為上拉輸入,并配置為中斷模式
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_PinSource;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 輸入模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 上拉
    GPIO_Init(GPIO_PortSource, &GPIO_InitStructure);

    // 配置EXTI線為中斷模式
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中斷模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿觸發(fā)
    EXTI_Init(&EXTI_InitStructure);

    // 使能中斷!!!!!!!!!!!
    NVIC_EnableIRQ(EXTI0_IRQn);

    // 主循環(huán)
    while (1)
    {
        // 可以在這里添加其他代碼
    }
}


13.void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

????????更改指定引腳的映射。

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);


重映射后記得打開復(fù)用時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* 打開GPIO時(shí)鐘 */


14.void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

????????選擇用作EXTI線的GPIO引腳。

#include "stm32f10x.h" // STM32F10x 系列的標(biāo)準(zhǔn)庫(kù)頭文件

// 假設(shè)我們使用GPIOB的Pin0作為外部中斷源
#define GPIO_PortSource GPIOB
#define GPIO_PinSource GPIO_Pin_0

void EXTI0_IRQHandler(void) // EXTI0中斷處理函數(shù)
{
    // 檢查是否是GPIOB的Pin0產(chǎn)生的中斷
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 清除中斷標(biāo)志
        EXTI_ClearITPendingBit(EXTI_Line0);

        // 這里添加中斷處理代碼
        printf("GPIOB Pin0 interrupt occurred!\n");
    }
}

int main(void)
{
    // 系統(tǒng)初始化代碼(略)

    // 配置GPIOB的Pin0為外部中斷源
    GPIO_EXTILineConfig(GPIO_PortSource, GPIO_PinSource);

    // 配置EXTI線為中斷模式
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中斷模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿觸發(fā)
    EXTI_Init(&EXTI_InitStructure);

    // 使能中斷
    NVIC_EnableIRQ(EXTI0_IRQn);

    // 主循環(huán)
    while (1)
    {
        // 可以在這里添加其他代碼
    }
}


15.void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

????????選擇以太網(wǎng)媒體接口。文章來源地址http://www.zghlxwxcb.cn/news/detail-848645.html

GPIO功能框圖講解:
網(wǎng)下圖2,3,4部分是GPIO輸入部分;5,6,7部分是輸出部分;
STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記
TTL肖特基觸發(fā)器(也叫施密特觸發(fā)器)如果輸入電壓大于某一閾值,輸出就會(huì)瞬間升為高電平,如果輸入電壓小于某─閾值。輸出就會(huì)瞬間降為低電平。大于2V為高電平,低于1.2V為低電平。
STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記
推挽輸出
????????OUT處相當(dāng)于肉眼可見的芯片引腳,引腳的兩個(gè)保護(hù)二級(jí)管可以防止引腳外部過高或過低的電壓輸入,當(dāng)引腳電壓高于 VDD 時(shí),上方的二極管導(dǎo)通,當(dāng)引腳電壓低于 VSS 時(shí),下方的二極管導(dǎo)通,防止不正常電壓引入芯片導(dǎo)致芯片燒毀。(不能直接接大功率驅(qū)動(dòng)芯片)
????????INT(相當(dāng)于芯片內(nèi)部GPIO的ODR數(shù)據(jù)輸出寄存器輸出的值),當(dāng)INT為1時(shí),經(jīng)過反向放大器,2處為0,PMOS管導(dǎo)通,NMOS管關(guān)閉,對(duì)外輸出高電平;
????????當(dāng)INT為0時(shí),經(jīng)過反向放大器,2處為1,PMOS管關(guān)閉,NMOS管導(dǎo)通,對(duì)外輸出低電平;
PMOS管負(fù)責(zé)灌電流,NMOS管負(fù)責(zé)拉電流。
????????推挽結(jié)構(gòu)指兩個(gè)三極管受兩路互補(bǔ)的信號(hào)控制,總是在一個(gè)導(dǎo)通的時(shí)候 另外一個(gè)截止,優(yōu)點(diǎn)開關(guān)效率效率高,電流大,驅(qū)動(dòng)能力強(qiáng)。
????????輸出高電平時(shí),電流輸出到負(fù)載,叫灌電流,可以理解成推,輸出低電 平時(shí),負(fù)載電流流向芯片,叫拉電流,即挽。
STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記開漏輸出
1、只能輸出低電平,不能輸出高電平。
2、如果要輸出高電平,則需要外接上拉。
3、開漏輸出具有“線與”功能,一個(gè)為低,全部為低,多用于I2C和
SMBUS總線。
????????開漏輸出一般應(yīng)用在 I2C、 SMBUS 通訊等需要“線與”功能的總線電路中。除此之外,還用在電平不匹配的場(chǎng)合,如需要輸出 5 伏的高電平,就可以在外部接一個(gè)上拉電阻,上拉電源為 5 伏,并且把 GPIO 設(shè)置為開漏模式,當(dāng)輸出高阻態(tài)時(shí),由上拉電阻和電源向外輸出 5 伏的電平。
???????? STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記
自建固件庫(kù):
以端口位設(shè)置/清除寄存器(GPIOx_BSRR) (x=A..E)為例,設(shè)置GPIO口為高電平只需讓該寄存器低16為置一即可。
#define GPIO_Pin_12 ? ((uint16_t)0x1000) ?/*!< 選擇Pin12 */ ? //(00010000 00000000)b
STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記
只對(duì)低16位操作,又是整型,所以是uint16_t,0x1000是16進(jìn)制,一個(gè)16進(jìn)制位對(duì)應(yīng)4個(gè)二進(jìn)制位,所以是0x1000
STM32外設(shè)GPIO(學(xué)習(xí)筆記),stm32,學(xué)習(xí),筆記
#define GPIO_Pin_0    ((uint16_t)0x0001)  /*!< 選擇Pin0 */    //(00000000 00000001)b
#define GPIO_Pin_1    ((uint16_t)0x0002)  /*!< 選擇Pin1 */    //(00000000 00000010)b
#define GPIO_Pin_2    ((uint16_t)0x0004)  /*!< 選擇Pin2 */    //(00000000 00000100)b
#define GPIO_Pin_3    ((uint16_t)0x0008)  /*!< 選擇Pin3 */    //(00000000 00001000)b
#define GPIO_Pin_4    ((uint16_t)0x0010)  /*!< 選擇Pin4 */    //(00000000 00010000)b
#define GPIO_Pin_5    ((uint16_t)0x0020)  /*!< 選擇Pin5 */    //(00000000 00100000)b
#define GPIO_Pin_6    ((uint16_t)0x0040)  /*!< 選擇Pin6 */    //(00000000 01000000)b
#define GPIO_Pin_7    ((uint16_t)0x0080)  /*!< 選擇Pin7 */    //(00000000 10000000)b

#define GPIO_Pin_8    ((uint16_t)0x0100)  /*!< 選擇Pin8 */    //(00000001 00000000)b
#define GPIO_Pin_9    ((uint16_t)0x0200)  /*!< 選擇Pin9 */    //(00000010 00000000)b
#define GPIO_Pin_10   ((uint16_t)0x0400)  /*!< 選擇Pin10 */   //(00000100 00000000)b
#define GPIO_Pin_11   ((uint16_t)0x0800)  /*!< 選擇Pin11 */   //(00001000 00000000)b
#define GPIO_Pin_12   ((uint16_t)0x1000)  /*!< 選擇Pin12 */   //(00010000 00000000)b
#define GPIO_Pin_13   ((uint16_t)0x2000)  /*!< 選擇Pin13 */   //(00100000 00000000)b
#define GPIO_Pin_14   ((uint16_t)0x4000)  /*!< 選擇Pin14 */   //(01000000 00000000)b
#define GPIO_Pin_15   ((uint16_t)0x8000)  /*!< 選擇Pin15 */   //(10000000 00000000)b
#define GPIO_Pin_All  ((uint16_t)0xFFFF)  /*!< 選擇全部引腳*/ //(11111111 11111111)b

到了這里,關(guān)于STM32外設(shè)GPIO(學(xué)習(xí)筆記)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包