国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

STM32一文通(3) GPIO

發(fā)布者:SparklingStar最新更新時(shí)間:2025-01-08 來(lái)源: jianshu關(guān)鍵字:STM32  GPIO  片上外設(shè) 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

預(yù)置知識(shí): 開時(shí)鐘

STM32 每一個(gè)片上外設(shè)資源都有自己的時(shí)鐘,這些時(shí)鐘被一個(gè)叫做RCC的外設(shè)統(tǒng)一管理,
所以,每一個(gè)片上外設(shè)想要應(yīng)用第一件事就是: 開時(shí)鐘!!!!!
根據(jù)系統(tǒng)結(jié)構(gòu)圖,GPIO都在APB2總線上


所以,我們要用void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)函數(shù)操作開啟GPIO的時(shí)鐘:


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能或者失能APB2外設(shè)時(shí)鐘


一. GPIO基礎(chǔ)知識(shí)、寄存器及庫(kù)函數(shù)

二. (重要)GPIO位帶操作

如果我們想讀取某個(gè)推挽輸出GPIO引腳現(xiàn)在的狀態(tài),怎么做呢?
我們可以讀取它的ODR寄存器狀態(tài), 比如GPIOB的0腳可以這樣讀:

GPIOB->ODR ^= GPIO_Pin_0;

由于我們不喜歡寄存器操作的方式,  現(xiàn)在我們想把它封裝起來(lái), 怎么封裝呢?

這里我們用到一個(gè)位帶別名區(qū)(可以理解為一大片寄存器), 位帶區(qū)把每個(gè)GPIO寄存器的每個(gè)位(每個(gè)引腳)的狀態(tài)映射到了自己的寄存器中. 我們根據(jù)GPIO的寄存器地址+位(引腳)偏移,可以算出去這個(gè)寄存器的哪個(gè)映射地址中可以讀到這個(gè)位(引腳)的狀態(tài), 我們稱之為地址轉(zhuǎn)換計(jì)算。計(jì)算公式推導(dǎo)過(guò)程忽略, 直接記住結(jié)果:

地址轉(zhuǎn)換計(jì)算公式

 ((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))


程序中, 我們定義這樣一個(gè)宏:

#define BITBAND(addr, bitnum) *(unsigned int*)((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))


當(dāng)我們想獲取GPIOB的ODR寄存器的某個(gè)位的狀態(tài)時(shí):

#define GPIOB_ODR_Addr      (GPIOB_BASE + 0X0C)   //找到GPIOB的基地址

#define GPIOB_ODR_bitnum    0                     //想讀GPIOB的ODR寄存器的第0位

#define BITBAND(addr, bitnum) *(unsigned int*)((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2)) //位帶操作地址轉(zhuǎn)換公式


當(dāng)函數(shù)調(diào)用時(shí):


BITBAND(GPIOB_ODR_Addr,GPIOB_ODR_bitnum)=0; //寫位


a= BITBAND(GPIOB_ODR_Addr,GPIOB_ODR_bitnum); //讀位


事實(shí)上,并非只有GPIO. 位帶區(qū)分為外設(shè)位帶區(qū)和SRAM位帶區(qū)(兩者的地址計(jì)算方法還不一樣). 它們?yōu)镾TM32提供了按位讀取的基礎(chǔ).就像51單片機(jī)里的sbit

這里舉一個(gè)位帶操作的完整例子:

main.c

#include 'stm32f10x.h'

#include 'led.h'

#include 'key.h'


#ifndef BITBAND

#define BITBAND(addr, bitnum) *(unsigned int*)((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2)) //位帶操作地址轉(zhuǎn)換公式

#endif  /*BITBAND*/


int a;

int main(void)

{

    LED_GPIO_Config();

    KEY1_GPIO_Config();

    KEY2_GPIO_Config();

    LED_G(OFF);//其實(shí)這里也可以改成LED_G_Out_Sbit=1

    LED_R(OFF);

    LED_B(OFF); 

    while(1)

    {

        if(KEY1_In_Sbit)

        {

            while(KEY1_In_Sbit);

            LED_G_Out_Sbit=!LED_G_Out_Sbit;

        }

            

        if(KEY2_In_Sbit)

        {

            while(KEY2_In_Sbit);

            LED_R_Out_Sbit=!LED_R_Out_Sbit;

        }

    }   

}


led.h

#ifndef __LED_H

#define __LED_H


#include 'stm32f10x.h'




#define LED_G_GPIO                          GPIOB

#define LED_G_Pin                           GPIO_Pin_0

#define LED_G_GPIO_ODR_Addr         (GPIOB_BASE + 0X0C)   //綠燈位帶操作:找到GPIOB的基地址

#define LED_G_ODR_bitnum                0                     //綠燈位帶操作:想讀GPIOB的ODR寄存器的第0位

#define LED_G_Out_Sbit                          BITBAND(LED_G_GPIO_ODR_Addr,LED_G_ODR_bitnum)   //將綠燈的位定義出來(lái)了


#define LED_R_GPIO                          GPIOB

#define LED_R_Pin                           GPIO_Pin_5

#define LED_R_GPIO_ODR_Addr         (GPIOB_BASE + 0X0C)   //紅燈位帶操作:找到GPIOB的基地址

#define LED_R_ODR_bitnum                5                     //紅燈位帶操作:想讀GPIOB的ODR寄存器的第5位

#define LED_R_Out_Sbit                          BITBAND(LED_R_GPIO_ODR_Addr,LED_R_ODR_bitnum)    //將宏燈的位定義出來(lái)了


#define LED_B_GPIO                          GPIOB

#define LED_B_Pin                           GPIO_Pin_1

#define LED_B_GPIO_ODR_Addr         (GPIOB_BASE + 0X0C)   //藍(lán)燈位帶操作:找到GPIOB的基地址

#define LED_B_ODR_bitnum                1                     //藍(lán)燈位帶操作:想讀GPIOB的ODR寄存器的第1位

#define LED_B_Out_Sbit                          BITBAND(LED_B_GPIO_ODR_Addr,LED_B_ODR_bitnum)  //將藍(lán)燈的位定義出來(lái)了


#define ON   1

#define OFF  0


#define LED_G(a) if(a) GPIO_ResetBits(LED_G_GPIO,LED_G_Pin); else GPIO_SetBits(LED_G_GPIO,LED_G_Pin);// 這里用了一個(gè)條件定義

#define LED_R(a) if(a) GPIO_ResetBits(LED_R_GPIO,LED_R_Pin); else GPIO_SetBits(LED_R_GPIO,LED_R_Pin);// 這里用了一個(gè)條件定義

#define LED_B(a) if(a) GPIO_ResetBits(LED_B_GPIO,LED_B_Pin); else GPIO_SetBits(LED_B_GPIO,LED_B_Pin);// 這里用了一個(gè)條件定義


void LED_GPIO_Config(void);


#endif /*__LED_H*/


key.h

#ifndef __KEY_H

#define __KEY_H


#include 'stm32f10x.h'


#define KEY1_GPIO                           GPIOA

#define KEY1_GPIO_Pin                       GPIO_Pin_0

#define KEY1_GPIO_IDR_Addr          (GPIOA_BASE + 0X08)   //key1位帶操作:找到GPIOA的IDR基地址

#define KEY1_ODR_bitnum                 0                     //key1位帶操作:想讀GPIOA的IDR寄存器的第0位

#define KEY1_In_Sbit                                BITBAND(KEY1_GPIO_IDR_Addr,KEY1_ODR_bitnum)   //將藍(lán)燈的位定義出來(lái)了


#define KEY2_GPIO                           GPIOC

#define KEY2_GPIO_Pin                       GPIO_Pin_13

#define KEY2_GPIO_IDR_Addr          (GPIOC_BASE + 0X08)   //key2位帶操作:找到GPIOC的IDR基地址

#define KEY2_ODR_bitnum                 13                    //key2位帶操作:想讀GPIOC的IDR寄存器的第13位

#define KEY2_In_Sbit                                BITBAND(KEY2_GPIO_IDR_Addr,KEY2_ODR_bitnum)  //按位操作KEY2


#define KEY_ON                  1

#define KEY_OFF                 0


void KEY1_GPIO_Config(void);

void KEY2_GPIO_Config(void);


#endif


led.c和 key.c 都只有GPIO初始化函數(shù), 這里省略了


三.  GPIO庫(kù)函數(shù)

1. GPIO初始化函數(shù):GPIO_Init

GPIO初始化用以下函數(shù)

參數(shù)1:可以看到,初始化時(shí),需要一個(gè)GPIO_TypeDef類型的指針GPIOx
參數(shù)2:需要一個(gè)GPIO_InitTypeDef類型的指針GPIO_InitStruct
這個(gè)GPIO_InitTypeDef如何定義呢?

定義這個(gè)結(jié)構(gòu)體,需要對(duì)以下參數(shù)進(jìn)行初始化

  • 參數(shù)2的參數(shù)1: GPIO_Pin: 可選值

  • 參數(shù)2的參數(shù)2: GPIO_Speed

  • 參數(shù)2的參數(shù)3:

例子:

GPIO_InitTypeDef GPIO_InitStructure;  //創(chuàng)建GPIO_InitTypeDef類型的結(jié)構(gòu)體GPIO_InitStructure

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高輸出速率50MHz

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出

GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化外設(shè)GPIOx寄存器


2. GPIO位輸出1函數(shù):GPIO_SetBits

3. GPIO位輸出0函數(shù):GPIO_ResetBits

4. GPIO讀取位輸入  GPIO_ReadInputDataBit

5. GPIO讀取位輸出  GPIO_ReadOutputDataBit

6. GPIO整體寫端口:

7. GPIO整體讀端口:


關(guān)鍵字:STM32  GPIO  片上外設(shè) 引用地址:STM32一文通(3) GPIO

上一篇:Arduino IDE下用STM32點(diǎn)亮OLED屏幕
下一篇:基于STM32的(GSM+DHT11)果園環(huán)境監(jiān)測(cè)系統(tǒng)

推薦閱讀最新更新時(shí)間:2025-07-02 13:44

什么是GPIO? STM32中關(guān)于GPIO口的介紹
一、什么是GPIO? GPIO的英文全稱是General-Purpose IO ports,也就是通用輸入輸出口。 在嵌入式系統(tǒng)中,經(jīng)常需要控制許多結(jié)構(gòu)簡(jiǎn)單的外部設(shè)備或者電路,這些設(shè)備有的需要通過(guò)CPU控制,有的需要CPU提供輸入信號(hào)。并且,許多設(shè)備或電路只要求有開/關(guān)兩種狀體就夠了,比如LED的亮與滅。對(duì)這些設(shè)備的控制,使用傳統(tǒng)的串口或者并口就顯得比較復(fù)雜,所以,在嵌入式微處理器上通常提供了一種“通用可編程I/O端口”,也就是GPIO。 一個(gè)GPIO端口至少需要兩個(gè)寄存器,一個(gè)做控制用的“通用IO端口控制寄存器”,還有一個(gè)是存放數(shù)據(jù)的“通用I/O端口數(shù)據(jù)寄存器”。數(shù)據(jù)寄存器的每一位是和GPIO的硬件引腳對(duì)應(yīng)的,而數(shù)據(jù)的傳遞方向是
[單片機(jī)]
什么是<font color='red'>GPIO</font>? <font color='red'>STM32</font>中關(guān)于<font color='red'>GPIO</font>口的介紹
【跟著江科大學(xué)Stm32GPIO_按鍵控制LED_光敏傳感器控制蜂鳴器
一、按鍵控制LED 用兩個(gè)按鍵來(lái)分別控制兩個(gè)LED的狀態(tài),初始狀態(tài)兩燈均熄滅,按下1次點(diǎn)亮,再按下熄滅 因?yàn)榻拼蟮奶撞蛽尣坏?我就自己看著圖和利用現(xiàn)有的東西配了一套,結(jié)果是一樣的,會(huì)比較亂 LED.H #ifndef __LED_H #define __LED_H void LED_Init(void); void LED1_ON(void); void LED1_OFF(void); void LED2_ON(void); void LED2_OFF(void); #endif LED.c #include stm32f10x.h // Device header void LED_
[單片機(jī)]
【跟著江科大學(xué)<font color='red'>Stm32</font>】<font color='red'>GPIO</font>_按鍵控制LED_光敏傳感器控制蜂鳴器
STM32上電以后GPIO默認(rèn)是Floating input
真實(shí)案例1: 用開發(fā)板STM32的PD13來(lái)測(cè)試,直接裸露的管腳。 硬件連接我手上發(fā)光二極管的比較長(zhǎng)的一端也就是 + 極,開發(fā)板找GND連接二極管較短的一端也就是 - 極。 #define TSBUZGPIO GPIOD #define TSBUZGPIOPIN GPIO_Pin_13 #define TS_BUZ_H() GPIO_SetBits(TSBUZGPIO ,TSBUZGPIOPIN) #define TS_BUZ_L() GPIO_ResetBits(TSBUZGPIO ,TSBUZGPIOPIN) void TS_Buz_Init(void) { GPIO
[單片機(jī)]
<font color='red'>STM32</font>上電以后<font color='red'>GPIO</font>默認(rèn)是Floating input
STM32GPIO工作原理(八種工作方式超詳細(xì)分析)
STM32F1xx官方資料: 《STM32中文參考手冊(cè)V10》-第8章通用和復(fù)用功能IO(GPIO和AFIO ) 芯片數(shù)據(jù)手冊(cè)(datasheet) STM32的GPIO介紹 STM32引腳說(shuō)明 GPIO是通用輸入/輸出端口的簡(jiǎn)稱,是STM32可控制的引腳。GPIO的引腳與外部硬件設(shè)備連接,可實(shí)現(xiàn)與外部通訊、控制外部硬件或者采集外部硬件數(shù)據(jù)的功能。 STM32F103ZET6芯片為144腳芯片,包括7個(gè)通用目的的輸入/輸出口(GPIO)組,分別為GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,同時(shí)每組GPIO口組有16個(gè)GPIO口。通常簡(jiǎn)略稱為PAx、PBx、PCx、PDx、PEx、
[單片機(jī)]
【<font color='red'>STM32</font>】<font color='red'>GPIO</font>工作原理(八種工作方式超詳細(xì)分析)
STM32小問(wèn)題-復(fù)用調(diào)試接口JTAG/SWD為普通GPIO
這幾天做畢業(yè)設(shè)計(jì),按鍵模塊用到了PA14和PA15這兩個(gè)IO口(由于IO是引出到拓展板上,所以剛開始并不知道PA14和PA15是被調(diào)試接口占用了)。設(shè)置好相應(yīng)的寄存器后發(fā)現(xiàn)只有PA15正常按下能被拉低,而PA14用萬(wàn)用表檢測(cè)始終處于低電平狀態(tài)。剛開始我以為這個(gè)管腳壞了,就想著設(shè)置成輸出高電平試試,結(jié)果可想而知,查看手冊(cè)后發(fā)現(xiàn)在在復(fù)位后JTAG接口的PA14被設(shè)置為下拉了,所以按鍵讀回來(lái)的永遠(yuǎn)是低電平。 后來(lái)發(fā)現(xiàn)核心板上PA15引腳連接到了JTAG接口就想能不能通過(guò)復(fù)用把這幾個(gè)口解放出來(lái),畢竟在正常應(yīng)用中調(diào)試接口是不工作的,還不如利用起來(lái)(其實(shí)是我懶得再改板子PCB了),后來(lái)查看手冊(cè)發(fā)現(xiàn)真的可以復(fù)用起來(lái)。 手冊(cè)描述如下 手冊(cè)
[單片機(jī)]
STM32使用BSRR和BRR寄存器快速操作GPIO端口
STM32的每個(gè)GPIO端口都有兩個(gè)特別的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通過(guò)這兩個(gè)寄存器可以直接對(duì)對(duì)應(yīng)的GPIOx端口置'1'或置'0'。 GPIOx_BSRR的高16位中每一位對(duì)應(yīng)端口x的每個(gè)位,對(duì)高16位中的某位置'1'則端口x的對(duì)應(yīng)位被清'0';寄存器中的位置'0',則對(duì)它對(duì)應(yīng)的位不起作用。 GPIOx_BSRR的低16位中每一位也對(duì)應(yīng)端口x的每個(gè)位,對(duì)低16位中的某位置'1'則它對(duì)應(yīng)的端口位被置'1';寄存器中的位置'0',則對(duì)它對(duì)應(yīng)的端口不起作用。
[單片機(jī)]
STC15W408AS單片機(jī)GPIO口介紹及其工作模式
一、GPIO口介紹 STC15W408AS單片機(jī)有14個(gè)I/O口。其所有I/O口均可由軟件配置成4種類型。4種類型分別為:準(zhǔn)雙向口/弱上拉(標(biāo)準(zhǔn)8051輸出模式)、推挽輸出/強(qiáng)上拉、高阻輸入(電流既不能流入也不能流出)或開漏輸出功能。每個(gè)口由2個(gè)控制寄存器中的相應(yīng)位控制每個(gè)引腳工作類型。STC15系列單片機(jī)的I/O口上電復(fù)位后為準(zhǔn)雙向口/弱上拉(傳統(tǒng)8051的I/O口)模式。每個(gè)I/O口驅(qū)動(dòng)能力均可達(dá)到20mA,但40-pin及40-pin以上單片機(jī)的整個(gè)芯片最大不要超過(guò)120mA,20-pin以上及32-pin以下(包括32-pin)單片機(jī)的整個(gè)芯片最大不要超過(guò)90mA。 P3口類似。 注意: 雖然每個(gè)I/O口在弱上拉(準(zhǔn)雙
[單片機(jī)]
STC15W408AS單片機(jī)<font color='red'>GPIO</font>口介紹及其工作模式
stm32f103 GPIO—— 一燈大師之庫(kù)函數(shù)版
在使用庫(kù)函數(shù)之前,我們先來(lái)看GPIO寄存器的結(jié)構(gòu)體 該結(jié)構(gòu)體中的成員,包含了引腳,輸出速度,輸出模式。我們可以使用這個(gè)結(jié)構(gòu)體來(lái)對(duì)I/O口進(jìn)行配置。 GPIO_InitTypeDef GPIO_InitStruct; //定義一個(gè)結(jié)構(gòu)體,用來(lái)需要配置的寄存器信息 void LED_Config(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; //配置的引腳為Pin6引腳 GPIO_InitStruct.GPIO_Speed =
[單片機(jī)]
stm32f103 <font color='red'>GPIO</font>—— 一燈大師之庫(kù)函數(shù)版
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved