說心里話,STM32 GPIO的配置操作并不比51單片機復雜多少,但不同的應用場景可能會涉及到需要了解IO配置過程中更深入的細節,比方說內部施密特觸發器的通斷到底如何控制,復用信號又是如何送到IO口上的,等等。
這些操作在手冊上都說到了,但個人覺得這些知識點比較分散,不利于初學者掌握其中的細微之處,所以我想把GPIO配置的控制邏輯梳理了一下,看看寄存器哪些位的哪些配置值都干了哪些事兒,‘接通’或‘斷開’了內部的哪些硬件。
下圖是GPIO基本結構圖。
為清晰表達出內部構件被使能或禁能,我使用了‘開關’概念,當然,實際它們不會真的是一些硬件開關,而是為了表達邏輯1、0狀態。
圖7.jpg (87.8 KB, 下載次數: 43)
下載附件
2021-2-7 10:54 上傳
1、通用輸入模式配置(以PA3為例)
圖8.jpg (67.43 KB, 下載次數: 55)
下載附件
2021-2-7 10:54 上傳
將PA3配置成輸入模式的前提是GPIOA_CRL的MODE3[1:0]=00。
如果想把它配置成模擬輸入用于ADC,那就在GPIOA_CRL的CNF3[1:0]寫入00。
因為STM32F沒有復用輸入模式,所以要想把它配置成復用輸入USART2_RX,要么是讓CNF3[1:0]=01使PA3成為浮空輸入模式;要么是讓CNF3[1:0]=10配置成內部弱上拉輸入模式,但必須在此前加上一條對GPIOA_ODR的ODR3=1的操作。
這是一個很有趣也很費解的操作,既然是配置輸入,怎么又跟輸出寄存器扯上關系了呢?請看手冊上的說明:
圖9.jpg (103.63 KB, 下載次數: 40)
下載附件
2021-2-7 10:54 上傳
既然配置成輸入時輸出緩沖器已經被關閉,那么ODR3的寫1操作就一定不是指向末端的PMOS和NMOS管。肯定有一個內部邏輯,使ODR3關聯到上拉及下拉電阻開關。至于這個邏輯到底是個啥樣的硬件,官方沒說,咱們也不好意細問。知道有這么回事兒,別在配置上下拉輸入時出現錯誤就行了。
如果PA3配置成了復用輸入USART2_RX,讀GPIOA_IDR的IDR3是允許的,而且讀回來的就是PA3當前的邏輯狀態,因為APB2的時鐘會采樣PA3,除了送到USART2模塊的RX以外,還鎖存到GPIOA_IDR的IDR3上。此時要閑著沒事兒非得讀一下GPIOA_ODR的ODR3,操作上也是允許的,但似乎也沒啥實際意義,因為讀回去的位狀態是之前對ODR3的最后一次寫入值。
如果PA3配置成了模擬輸入,施密特觸發器就會被斷開,讀IDR3就不再是PA3的數據了。
2、通用輸出模式配置(以PA2為例)
圖10.jpg (79.22 KB, 下載次數: 40)
下載附件
2021-2-7 10:54 上傳
將PA2配置成輸出模式的前提是GPIOA_CRL的MODE2[1:0]=01、10或11。
由于在輸出模式下施密特觸發器一直是被打開的,每個APB2時鐘也像輸入模式一樣把PA2鎖存到GPIOA_IDR的IDR2,所以此時讀GPIOA_IDR能夠返回PA2當前的輸出邏輯狀態,但這可不是說此時PA2又可以當成輸入口使用,尤其是處于推挽輸出模式下,PA2外面的信號是進不來的。在開漏模式下,倒是可以把PA2當成輸入,這一點在下面會有描述。
還有一點值得注意,如果想把PA2配置成USART2_TX,那就必須將它配置成復用推挽或復用開漏輸出模式,千萬不能讓CNF2[1:0]=00(通用推挽)或01(通用開漏),否則USART2_TX送不到PA2上,因為這個時候‘復用/通用切換開關’是指向GPIOA_ODR的ODR2位而不是指向USART2_TX。
3、輸入輸出模式配置(以PB11為例)
有的時候需要將某個引腳當成IO口使用,比方說用PB11模擬I2C的SDA口線。
請注意,這里說的是‘模擬’SDA,而不是把PB11配置成復用的I2C2 SDA口。
咱們都知道,SDA線上必須外加上拉電阻,到底是為啥就不多說了。
作為模擬的SDA,有一繁一簡兩個方法:需要PB11送數就把它配置成通用輸出模式,回頭又需要它收數了再配置成輸入模式,在理論上這種方式是可行的,但切來切去的也真夠麻煩。
簡單的方法就是把PB11配置成通用開漏輸出模式,輸出時自不必說,當輸入時只要先在ODR11寫個1就行了。
圖11.jpg (71.49 KB, 下載次數: 50)
下載附件
2021-2-7 10:54 上傳
此時PB11是通用開漏模式,輸出端的PMOS被禁用,在ODR11上寫1并不能打開這個MOS管,而NMOS的驅動邏輯是0,所以這個MOS管也會被斷開。但由于此時施密特觸發器是接通的,所以引腳上的信號會被APB2時鐘采樣和鎖存,讀取IDR11就可以獲取PB11的輸入數據。這種在端口鎖存上寫1變輸入的方式與51單片機準輸入IO口的操作是一樣的。
上面說的是模擬I2C,如果是直接啟用復用功能那就不用這么麻煩了,人家早就把相關的邏輯操作搞得妥妥的了。按照手冊上的說明,只需將PB11配置成復用開漏就一切OK。
|