【GPIO8個函數解釋】

函數解釋

  1. void GPIO_DeInit(GPIO_TypeDef* GPIOx);
  • 作用:將指定GPIO端口的所有寄存器恢復為默認值。這會清除之前對該端口的所有配置,使其回到初始狀態。
  • 使用方法:傳入要復位的GPIO端口指針,例如GPIOAGPIOB等。
  1. void GPIO_AFIODeInit(void);
  • 作用:將復用功能I/O(AFIO)的寄存器恢復為默認值。復用功能I/O用于將一些外設功能映射到特定的GPIO引腳上,該函數可清除這些映射配置。
  • 使用方法:無需傳入參數,直接調用即可。
  1. void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
  • 作用:根據GPIO_InitStruct結構體中的參數初始化指定的GPIO端口。該結構體包含了GPIO引腳的模式、速度等配置信息。
  • 使用方法:傳入要初始化的GPIO端口指針和一個GPIO_InitTypeDef結構體指針。
  1. void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
  • 作用:將GPIO_InitTypeDef結構體的成員初始化為默認值。通常在使用GPIO_Init函數之前調用該函數,以確保結構體中的成員有合理的初始值。
  • 使用方法:傳入一個GPIO_InitTypeDef結構體指針。

示例代碼

以下是一個簡單的示例,展示了如何使用這些函數來初始化GPIO端口:

#include "stm32f10x.h"int main(void)
{GPIO_InitTypeDef GPIO_InitStructure;// 使能GPIOA時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 將GPIOA的所有寄存器恢復為默認值GPIO_DeInit(GPIOA);// 將復用功能I/O的寄存器恢復為默認值GPIO_AFIODeInit();// 將GPIO_InitStructure結構體的成員初始化為默認值GPIO_StructInit(&GPIO_InitStructure);// 配置GPIOA的引腳0為推挽輸出模式,最大速度為50MHzGPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// 根據GPIO_InitStructure結構體的參數初始化GPIOAGPIO_Init(GPIOA, &GPIO_InitStructure);while (1){// 點亮LEDGPIO_SetBits(GPIOA, GPIO_Pin_0);// 延時一段時間for (int i = 0; i < 1000000; i++);// 熄滅LEDGPIO_ResetBits(GPIOA, GPIO_Pin_0);// 延時一段時間for (int i = 0; i < 1000000; i++);}
}

代碼解釋

  1. 使能時鐘:在使用GPIO之前,需要先使能相應的時鐘。這里使用RCC_APB2PeriphClockCmd函數使能GPIOA的時鐘。
  2. 復位寄存器:調用GPIO_DeInitGPIO_AFIODeInit函數將GPIOA和復用功能I/O的寄存器恢復為默認值。
  3. 初始化結構體:調用GPIO_StructInit函數將GPIO_InitStructure結構體的成員初始化為默認值。
  4. 配置GPIO:設置GPIO_InitStructure結構體的成員,指定要配置的引腳、模式和速度。
  5. 初始化GPIO端口:調用GPIO_Init函數根據GPIO_InitStructure結構體的參數初始化GPIOA。
  6. 循環控制LED:在主循環中,使用GPIO_SetBitsGPIO_ResetBits函數點亮和熄滅連接到GPIOA引腳0的LED。

通過以上步驟,你可以使用這些函數來配置和控制STM32的GPIO端口。

函數名功能參數說明適用場景
GPIO_SetBits將指定GPIO端口的指定引腳置為高電平(邏輯1)- GPIOx:指定的GPIO端口,如GPIOAGPIOB
- GPIO_Pin:指定的引腳,如GPIO_Pin_0GPIO_Pin_1
僅需將引腳拉高的場景,操作簡單直接
GPIO_ResetBits將指定GPIO端口的指定引腳置為低電平(邏輯0)- GPIOx:指定的GPIO端口,如GPIOAGPIOB
- GPIO_Pin:指定的引腳,如GPIO_Pin_0GPIO_Pin_1
僅需將引腳拉低的場景,操作簡單直接
GPIO_WriteBit將指定GPIO端口的指定引腳設置為指定的電平值- GPIOx:指定的GPIO端口,如GPIOAGPIOB
- GPIO_Pin:指定的引腳,如GPIO_Pin_0GPIO_Pin_1
- BitVal:電平值,Bit_SET表示高電平,Bit_RESET表示低電平
需要靈活設置引腳高低電平的場景
GPIO_Write將一個16位的值寫入指定的GPIO端口,一次性設置該端口所有引腳的電平狀態- GPIOx:指定的GPIO端口,如GPIOAGPIOB
- PortVal:一個16位的值,用于設置端口所有引腳的電平
需要對一個端口的多個引腳進行批量操作的場景

這四個函數均為STM32標準庫中用于操作GPIO引腳輸出電平的函數,下面為你對比分析它們的區別,并給出使用示例。

函數區別分析

1. void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  • 功能:將指定GPIO端口的指定引腳置為高電平(邏輯1)。
  • 特點:只能用于將引腳置高,操作簡單直接,適用于只需要將引腳拉高的場景。
2. void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  • 功能:將指定GPIO端口的指定引腳置為低電平(邏輯0)。
  • 特點:只能用于將引腳置低,操作簡單直接,適用于只需要將引腳拉低的場景。
3. void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
  • 功能:將指定GPIO端口的指定引腳設置為指定的電平值,電平值可以是高電平(Bit_SET)或低電平(Bit_RESET)。
  • 特點:可以靈活設置引腳的高低電平,通過傳入不同的BitAction參數來控制。
4. void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
  • 功能:將一個16位的值寫入指定的GPIO端口,一次性設置該端口所有引腳的電平狀態。
  • 特點:可以同時控制一個端口的所有16個引腳,適用于需要對多個引腳進行批量操作的場景。

示例代碼

以下是使用這四個函數的示例代碼:

#include "stm32f10x.h"int main(void)
{GPIO_InitTypeDef GPIO_InitStructure;// 使能GPIOA時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 配置GPIOA的引腳0和引腳1為推挽輸出模式,最大速度為50MHzGPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);while (1){// 使用GPIO_SetBits將引腳0置高GPIO_SetBits(GPIOA, GPIO_Pin_0);// 延時一段時間for (int i = 0; i < 1000000; i++);// 使用GPIO_ResetBits將引腳0置低GPIO_ResetBits(GPIOA, GPIO_Pin_0);// 延時一段時間for (int i = 0; i < 1000000; i++);// 使用GPIO_WriteBit將引腳1置高GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);// 延時一段時間for (int i = 0; i < 1000000; i++);// 使用GPIO_WriteBit將引腳1置低GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);// 延時一段時間for (int i = 0; i < 1000000; i++);// 使用GPIO_Write同時設置引腳0和引腳1的電平// 0x03 表示二進制 0000 0000 0000 0011,即引腳0和引腳1都置高GPIO_Write(GPIOA, 0x03);// 延時一段時間for (int i = 0; i < 1000000; i++);// 使用GPIO_Write同時設置引腳0和引腳1的電平// 0x00 表示二進制 0000 0000 0000 0000,即引腳0和引腳1都置低GPIO_Write(GPIOA, 0x00);// 延時一段時間for (int i = 0; i < 1000000; i++);}
}

代碼解釋

  1. 使能時鐘和配置GPIO:使能GPIOA的時鐘,并將GPIOA的引腳0和引腳1配置為推挽輸出模式。
  2. 使用GPIO_SetBitsGPIO_ResetBits:分別將引腳0置高和置低,實現引腳0的電平翻轉。
  3. 使用GPIO_WriteBit:通過傳入Bit_SETBit_RESET參數,將引腳1置高和置低,實現引腳1的電平翻轉。
  4. 使用GPIO_Write:通過傳入不同的16位值,一次性設置引腳0和引腳1的電平狀態。

以下是三種GPIO控制方法的對比及效果分析:


1. 方法對比

方法1GPIO_SetBitsGPIO_ResetBits
GPIO_SetBits(GPIOA, GPIO_Pin_0);   // 置高電平
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 置低電平
  • 原理:直接操作寄存器,通過宏定義實現。
  • 特點
    • 代碼簡潔,無函數調用開銷,執行效率高。
    • 專用于單一操作(置高或置低),功能明確。
方法2GPIO_WriteBit 配合 Bit_RESETBit_SET
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); // 置低電平
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);   // 置高電平
  • 原理:通過函數調用設置電平,參數使用枚舉值(BitAction)。
  • 特點
    • 代碼直觀,參數明確(Bit_SET/Bit_RESET)。
    • 靈活性高,可動態指定電平狀態(如通過變量控制)。
方法3GPIO_WriteBit 配合強制類型轉換
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0); // 置低電平
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1); // 置高電平
  • 原理:強制將整數 01 轉換為 BitAction 類型。
  • 特點
    • 功能上等同于方法2(BitAction 內部對應 01)。
    • 缺點:代碼可讀性差,潛在兼容性風險(依賴枚舉底層實現)。

2. 效果是否相同?

  • 功能層面:三種方法最終均會修改GPIO輸出寄存器的對應位,實現引腳電平控制,效果完全相同
  • 性能層面
    • 方法1(宏操作)直接操作寄存器,無函數調用,效率最高
    • 方法2和方法3(函數調用)有輕微函數調用開銷,但實際應用中差異可忽略。

3. 代碼規范建議

  1. 推薦方法2
    使用 Bit_SETBit_RESET,兼顧可讀性、規范性和靈活性。

    GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); // 正確寫法
    
  2. 避免方法3
    強制類型轉換會降低代碼可維護性,且不符合ST庫的設計意圖。

  3. 方法1的適用場景
    若需極致性能(如高頻信號控制),可優先選擇 GPIO_SetBits/GPIO_ResetBits


4. 補充說明

  • 條件編譯 #if 0 的作用
    代碼中被 #if 0 包裹的部分會被編譯器忽略,僅用于臨時禁用代碼塊。
    若要啟用方法1或方法2,需將對應的 #if 0 改為 #if 1

總結

三種方法在功能上完全等效,但代碼風格和可維護性差異顯著。推薦優先使用方法2(Bit_SET/Bit_RESET,既能保證效率,又符合工程規范。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76530.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76530.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76530.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

將圖表和表格導出為PDF的功能

<template><div><divref"pdfContent"style"position: relative; width: 800px; margin: 0 auto"><!-- ECharts 圖表 --><div id"chart" style"width: 100%; height: 400px" /><!-- Element UI 表格 …

C++中的鏈表操作

在C中&#xff0c;鏈表是一種常見的數據結構&#xff0c;它由一系列節點組成&#xff0c;每個節點包含數據部分和指向下一個節點的指針。C標準庫&#xff08;STL&#xff09;中提供了std::list和std::forward_list兩種鏈表實現&#xff0c;分別對應雙向鏈表和單向鏈表。此外&am…

蛋白設計 ProteinMPNN

傳統方法的局限性是什么&#xff1f; 傳統蛋白質設計方法的局限性&#xff1a; 基于物理的傳統方法&#xff0c;例如羅塞塔&#xff0c;面臨計算難度&#xff0c;因為需要計算所有可能結構的能量&#xff0c;包括不需要的寡聚態和聚合態。 設計目標與顯式優化之間缺乏一致性通…

有哪些開源的視頻生成模型

1. 阿里巴巴通義萬相2.1&#xff08;WanX 2.1&#xff09; 技術架構&#xff1a;基于Diffusion Transformer&#xff08;DiT&#xff09;架構&#xff0c;結合自研的高效變分自編碼器&#xff08;VAE&#xff09;和Flow Matching訓練方案&#xff0c;支持時空上下文建模。參數…

【動態規劃】最長上升子序列模板

最長上升子序列 題目傳送門 一、題目描述 給定一個長度為 N 的數列&#xff0c;求數值嚴格單調遞增的子序列的長度最長是多少。 輸入格式 第一行包含整數 N。 第二行包含 N 個整數&#xff0c;表示完整序列。 輸出格式 輸出一個整數&#xff0c;表示最大長度。 數據范圍 …

LeetCode 891 -- 貢獻度思想

題目描述 子序列寬度之和 思路 ref 代碼 相似題 子數組范圍和 acwing

化工行業如何通過定制化工作流自動化實現25-30%成本優化?

作者&#xff1a;Mihir Jhaveri 編譯&#xff1a;李升偉 發布日期&#xff1a;2024年10月30日 在化工生產領域&#xff0c;數字化轉型正以顛覆性態勢重塑產業格局。通過集成定制化軟件、ERP系統、工業物聯網&#xff08;IIoT&#xff09;傳感網絡、機器人流程自動化&#xff0…

Compose組件轉換XML布局

文章目錄 學習JetPack Compose資源前言&#xff1a;預覽界面的實現Compose組件的布局管理一、Row和Colum組件&#xff08;LinearLayout&#xff09;LinearLayout&#xff08;垂直方向 → Column&#xff09;LinearLayout&#xff08;水平方向 → Row&#xff09; 二、相對布局 …

RAG測試數據集資源

一、通用問答基準數據集 HotpotQA 特點:包含11萬+多跳問答對最佳用途:測試復雜推理能力數據示例:{"question": "Were Scott Derrickson and Ed Wood of the same nationality?","answer": "Yes, both are American" }MS MARCO 特點…

快速掌握MCP——Spring AI MCP包教包會

最近幾個月AI的發展非常快&#xff0c;各種大模型、智能體、AI名詞和技術和框架層出不窮&#xff0c;作為一個業余小紅書博主的我最近總刷到MCP這個關鍵字&#xff0c;看著有點高級我也來學習一下。 1.SpringAI與functionCall簡單回顧 前幾個月我曾寫過兩篇關于SpringAI的基礎…

學習筆記--(6)

import numpy as np import matplotlib.pyplot as plt from scipy.special import erfc# 設置參數 rho 0.7798 z0 4.25 # 確保使用大寫 Z0&#xff0c;與定義一致def calculate_tau(z, z_prime, rho, s_values):return np.log(rho * z * z_prime * s_values / 2)# 定義 chi_…

【AI4CODE】5 Trae 錘一個基于百度Amis的Crud應用

【AI4CODE】目錄 【AI4CODE】1 Trae CN 錐安裝配置與遷移 【AI4CODE】2 Trae 錘一個 To-Do-List 【AI4CODE】3 Trae 錘一個貪吃蛇的小游戲 【AI4CODE】4 Trae 錘一個數據搬運工的小應用 1 百度 Amis 簡介 百度 Amis 是一個低代碼前端框架&#xff0c;由百度開源。它通過 J…

認識 Promise

認識 Promise 前言&#xff1a;為什么會出現 Promise&#xff1f; 最常見的一個場景就是 ajax 請求&#xff0c;通俗來說&#xff0c;由于網速的不同&#xff0c;可能你得到返回值的時間也是不同的&#xff0c;這個時候我們就需要等待&#xff0c;結果出來了之后才知道怎么樣…

純c++實現transformer 訓練+推理

項目地址 https://github.com/freelw/cpp-transformer C 實現的 Transformer 這是一個無需依賴特殊庫的 Transformer 的 C 實現&#xff0c;涵蓋了訓練與推理功能。 本項目使用C復刻了《Dive into Deep Learning》中關于 Transformer 的第 11 章11.7小節點內容。構建了一個英…

Go 語言規范學習(7)

文章目錄 Built-in functionsAppending to and copying slicesClearCloseManipulating complex numbersDeletion of map elementsLength and capacityMaking slices, maps and channelsMin and maxAllocationHandling panicsBootstrapping PackagesSource file organizationPac…

Python Cookbook-5.1 對字典排序

任務 你想對字典排序。這可能意味著需要先根據字典的鍵排序&#xff0c;然后再讓對應值也處于同樣的順序。 解決方案 最簡單的方法可以通過這樣的描述來概括:先將鍵排序&#xff0c;然后由此選出對應值: def sortedDictValues(adict):keys adict.keys()keys.sort()return …

Git Rebase 操作中丟失提交的恢復方法

背景介紹 在團隊協作中,使用 Git 進行版本控制是常見實踐。然而,有時在執行 git rebase 或者其他操作后,我們可能會發現自己的提交記錄"消失"了,這往往讓開發者感到恐慌。本文將介紹幾種在 rebase 后恢復丟失提交的方法。 問題描述 當我們執行以下操作時,可能…

C語言基礎要素(019):輸出ASCII碼表

計算機以二進制處理信息&#xff0c;但二進制對人類并不友好。比如說我們規定用二進制值 01000001 表示字母’A’&#xff0c;顯然通過鍵盤輸入或屏幕閱讀此數據而理解它為字母A&#xff0c;是比較困難的。為了有效的使用信息&#xff0c;先驅者們創建了一種稱為ASCII碼的交換代…

鴻蒙定位開發服務

引言 鴻蒙操作系統&#xff08;HarmonyOS&#xff09;作為面向萬物互聯時代的分布式操作系統&#xff0c;其定位服務&#xff08;Location Kit&#xff09;為開發者提供了多場景、高精度的位置能力支持。本文將從技術原理、開發流程到實戰案例&#xff0c;全面解析鴻蒙定位服務…

rknn_convert的使用方法

rknn_convert是RKNN-Toolkit2提供的一套常用模型轉換工具&#xff0c;通過封裝上述API接口&#xff0c;用戶只需編輯模型對應的yml配置文件&#xff0c;就可以通過指令轉換模型。以下是如何使用rknn_convert工具的示例命令以及支持的指令參數&#xff1a; python -m rknn.api.…