STM32技術--GPIO配置


以下以STM32F407ZGT6為例。

一.GPIO的作用

1.當作輸入輸出口 輸出數字信號 0/1
TTL電平 0 0~1.5V 1 2.5~5V
STM32中 - 0±0.1V 1 3.3±0.3V
2.直接驅動外部電路 如LED,蜂鳴器等等
3.使用I/O口模擬通信協議 IIC
4.模擬PWM波 通過循環改變占空比來實現

二.STM32F407ZGT6芯片中GPIO口的數量及命名

1.114個I/O口,每個I/O口上有不同的通用功能,復用功能等
2.命名 Port + 端口號 + 管腳號
端口號 : A B C D E F G H 在A~G上每個端口有16個管腳(0~15),H只有2個管腳(1,2)
例 PA5 A端口的第5個管腳

三.如何操作GPIO口

通過AHB1時鍾總線與GPIO口通信 操作提供的接口----寄存器

四.STM32F407ZTG6中GPIO的寄存器

1.寄存器:一塊存儲空間(8/16/32位),具有RAM具有的特性(掉電數據丟失,讀寫速度快),每個位 都有自己獨特的作用。
2.如何操作寄存器
通過指針操作 例如我們想操作一個地址為0x4000的寄存器只需要通過*(unsigned int *)0x4000進行我們需要的操作(賦值,加減,位操作)
3.寄存器的特性
有讀/寫,只讀,只寫,讀取/清零,讀取/置位,切換,保留(reserved)等
數據(DR)寄存器:保存接受/發送的數據,一般用=接受
配置(控制CR)寄存器:配置相關的工作模式,一般用&=~進行清零或|=置一 ^= 進行反轉
狀態(SR)寄存器:外設所處的狀態,一般用 &1 操作來進行讀取
4.GPIO的工作模式
上拉:1.拉高電平2.增強電路的驅動能力
下拉:1.拉低電平2.增強電路的驅動能力
輸入:4種
浮空輸入:輸入的是數字量,不具有上下拉驅動能力的輸入 – 按鍵識別
上拉輸入:輸入的是數字量,具有上拉驅動能力的輸入
下拉輸入:輸入的是數字量,具有下拉驅動能力的輸入
模擬輸入:輸入的是模擬量 – 模數轉換 ADC
輸出:4種
通用:IO功能
復用:除了IO以外的功能,比如串口,定時器等
開漏輸出:只能輸出0(想要輸出1,需要接上拉電阻)--總線通信
推挽輸出:既能輸出0,又能輸出1.
5.通過配置步驟(以LED為例)
1.查看原理圖,找到led對應的IO口

 

以pf6為例,當向該引腳輸出0時led亮。

2.查看該IO口的通用功能是否用作作IO口

 

 

 在這里PF6的通用功能為io口的功能


3.打開該GPIO口對應的時鍾
4.配置工作模式

 

在該圖中A,B,C,D,E,F,G,H,I的時鍾總線都是AHB1,所以在我們操作該GPIO口時要將該時鍾打開,只需通過位操作將相應位置一即可,具體操作位

RCC->AHB1ENR |= (1<<0);這里左移0位即為將GPIOA置為1。

接下來配置GPIOF的工作模式,以第6位為例

因為時通用功能,所以復用暫時不看以后會提到

led的工作模式位通用推挽輸出,無上下拉,快速模式(可自己選擇)

 

若要將pf6配置為通用,要在第12,13位中寫入01操作如下:

//pf6 通用推挽輸出
GPIOF->MODER &=~ (3<<12); //清零
GPIOF->MODER |= (1<<12); //通用輸出模式
GPIOF->OTYPER &=~ (1<<6); //輸出推挽
GPIOF->OSPEEDR &=~ (3<<12); //速度清零
GPIOF->OSPEEDR |= (2<<12); //快速
GPIOF->ODR |= (1<<6); //led滅

 這里因為GPIOF->ODR的復位值為0x0000 0000,而根據 原理圖當該引腳輸出0時led亮,所以在初始化中需要將該位置1,需要讓led滅的時候把相應位置為0即可。

led是輸出的體現,那么獨立按鍵就是輸入的體現了,下面讓我們看一下怎么配置key的工作方式。

還是按上面的步驟:

1.查看原理圖,確定引腳,以及工作方式

以key1為例,可以看出當按鍵沒用按下的時候,該IO口檢測到的(就是向IO口輸入的)為低電平,按鍵按下時,就會檢測到高電平。我們可以搜索他的標號(KEY1)來確定他的端口號,所以我么只要配置PA0,為輸入模式就可以使用KEY1這個獨立按鍵了

 

2.看該IO口是否有IO口的功能

通用功能是IO口的功能 

3.打開對應的時鍾

4.配置相應的工作模式

RCC->AHB1ENR &=~ (1<<0);
RCC->AHB1ENR |= (1<<0);
//pa0 浮空輸入
GPIOA->MODER &=~ 3;
GPIOA->PUPDR &=~ 3;

這樣就配置完成了,我們只要檢測GPIOA->IDR這個輸入數據寄存器就可以確定按鍵是否按下了。

完整代碼如下:

復制代碼
 1 #include "led.h"
 2 #include "delay.h"
 3 
 4 
 5 
 6 /*
 7 函數名稱:led_config()
 8 函數功能:初始化led
 9 函數參數:無
10 
11 */
12 void led_config()
13 {
14     //pf6
15     //開時鍾
16     RCC->AHB1ENR |= ((1<<5)|(1<<2));
17     //pf6 通用推挽輸出
18     GPIOF->MODER &=~ ((3<<12)|(3<<18)|(3<<20));        //清零
19     GPIOF->MODER |= ((1<<12)|(1<<18)|(1<<20));        //通用輸出模式
20     GPIOF->OTYPER &=~ ((1<<6)|(1<<9)|(1<<10));        //輸出推挽
21     GPIOF->OSPEEDR &=~ ((3<<12)|(3<<18)|(3<<20));    //速度清零
22     GPIOF->OSPEEDR |= ((2<<12)|(2<<18)|(2<<20));    //快速
23     GPIOF->ODR |= ((1<<6)|(1<<9)|(1<<10));                //led滅
24     
25     GPIOC->MODER &=~ (3<<0);
26     GPIOC->MODER |= (1<<0);
27     GPIOC->OTYPER &=~ (1<<0);
28     GPIOC->OSPEEDR &=~ (3<<0);
29     GPIOC->OSPEEDR |= (2<<0);
30     GPIOC->ODR |= (1<<0);
31     
32 }
33 
34 
35 void led1_Flash()
36 {
37     
38     LED1(1);
39     delay_nms(500);
40     LED1(0);
41     delay_nms(500);
42 }
43 
44 //流水燈
45 void led_pipeline()
46 {
47     LED1(1);
48     delay_nms(500);
49     LED1(0);
50     LED2(1);
51     delay_nms(500);
52     LED2(0);
53     LED3(1);
54     delay_nms(500);
55     LED3(0);
56     LED4(1);
57     delay_nms(500);
58     LED4(0);
59 }
60 
61 //呼吸燈
62 void breath_led()
63 {
64     uint32_t i;
65     for(i=0;i<1000;i++)
66     {
67         LED2(1);
68         delay_nus(i);
69         LED2(0);
70         delay_nus(1000-i);
71     }
72     for(i=0;i<1000;i++)
73     {
74         LED2(0);
75         delay_nus(1000-i);
76         LED2(1);
77         delay_nus(i);
78     }
79 
80 }
復制代碼
復制代碼
#include "key.h"
#include "delay.h"

/*

函數功能:初始化key
函數名稱:key_config()
函數參數:無
*/
void key_config()
{
    //開時鍾
    RCC->AHB1ENR &=~ (1|(1<<4));
    RCC->AHB1ENR |= (1|(1<<4));
    //pa0 浮空輸入
    GPIOA->MODER &=~ 3;
    GPIOA->PUPDR &=~ 3;
    
    GPIOE->MODER &=~ ((3<<4)|(3<<6)|(3<<8));
    GPIOE->PUPDR &=~ ((3<<4)|(3<<6)|(3<<8));
}


/*

函數功能:獲取按鍵的值
函數名稱:getKeyValue()
函數參數:無
*/
uint8_t getKeyValue()
{
    uint8_t value;
    if(key1)
    {
        delay_nms(10);
        if(key1)
        {
            value = 1;
        }
    }
    else if(!key2)
    {
        delay_nms(10);
        if(!key2)
        {
            value = 2;
        }
    }
    else if(!key3)
    {
        delay_nms(10);
        if(!key3)
        {
            value = 3;
        }
    }
    else if(!key4)
    {
        delay_nms(10);
        if(!key4)
        {
            value = 4;
        }
    }
    
    return value;
}
復制代碼

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM