06.構建庫函數

来源:https://www.cnblogs.com/xuanchi/archive/2022/10/15/16795212.html
-Advertisement-
Play Games

GPIO 引腳號定義 #define GPIO_Pin_0 ((uint16_t)0x0001) /*!< 選擇Pin0 */ //(00000000 00000001)b #define GPIO_Pin_1 ((uint16_t)0x0002) /*!< 選擇Pin1 */ //(0000000 ...


GPIO 引腳號定義

#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	

定義 GPIO 初始化結構體

typedef struct {
  uint16_t GPIO_Pin; /*!< 選擇要配置的 GPIO 引腳 */

  uint16_t GPIO_Speed; /*!< 選擇 GPIO 引腳的速率 */

  uint16_t GPIO_Mode; /*!< 選擇 GPIO 引腳的工作模式 */
} GPIO_InitTypeDef;

GPIO 枚舉類型定義

typedef enum
{ GPIO_Mode_AIN = 0x0,           // 模擬輸入     (0000 0000)b
  GPIO_Mode_IN_FLOATING = 0x04,  // 浮空輸入     (0000 0100)b
  GPIO_Mode_IPD = 0x28,          // 下拉輸入     (0010 1000)b
  GPIO_Mode_IPU = 0x48,          // 上拉輸入     (0100 1000)b
  
  GPIO_Mode_Out_OD = 0x14,       // 開漏輸出     (0001 0100)b
  GPIO_Mode_Out_PP = 0x10,       // 推輓輸出     (0001 0000)b
  GPIO_Mode_AF_OD = 0x1C,        // 復用開漏輸出 (0001 1100)b
  GPIO_Mode_AF_PP = 0x18         // 復用推輓輸出 (0001 1000)b
}GPIOMode_TypeDef;

給 GPIO_InitTypeDef 初始化結構體賦值範例

GPIO_InitTypeDef GPIO_InitStructure;
/* GPIO 埠初始化 */
/*選擇要控制的 GPIO 引腳*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
/*設置引腳模式為輸出模式*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*設置引腳的輸出類型為推輓輸出*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO 初始化函數

GPIO_InitTypeDef GPIO_InitStructure;	
	
/* GPIO 埠初始化 */	
/*選擇要控制的 GPIO 引腳*/	
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;	
/*設置引腳模式為輸出模式*/	
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
/*設置引腳的輸出類型為推輓輸出*/	
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
  uint32_t tmpreg = 0x00, pinmask = 0x00;
  
/*---------------------- GPIO 模式配置 --------------------------*/
  // 把輸入參數GPIO_Mode的低四位暫存在currentmode
  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
  
  // bit4是1表示輸出,bit4是0則是輸入 
  // 判斷bit4是1還是0,即首選判斷是輸入還是輸出模式
  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
  { 
  // 輸出模式則要設置輸出速度
    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
  }
/*-------------GPIO CRL 寄存器配置 CRL寄存器控制著低8位IO- -------*/
  // 配置埠低8位,即Pin0~Pin7
  if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
  {
  // 先備份CRL寄存器的值
    tmpreg = GPIOx->CRL;
    
  // 迴圈,從Pin0開始配對,找出具體的Pin
    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    {
   // pos的值為1左移pinpos位
      pos = ((uint32_t)0x01) << pinpos;
      
    // 令pos與輸入參數GPIO_PIN作位與運算,為下麵的判斷作准備
      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
      
    //若currentpin=pos,則找到使用的引腳
      if (currentpin == pos)
      {
    // pinpos的值左移兩位(乘以4),因為寄存器中4個寄存器位配置一個引腳
        pos = pinpos << 2;
       //把控制這個引腳的4個寄存器位清零,其它寄存器位不變
        pinmask = ((uint32_t)0x0F) << pos;
        tmpreg &= ~pinmask;
        
        // 向寄存器寫入將要配置的引腳的模式
        tmpreg |= (currentmode << pos);  
        
    // 判斷是否為下拉輸入模式
        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
        {
      // 下拉輸入模式,引腳預設置0,對BRR寄存器寫1可對引腳置0
          GPIOx->BRR = (((uint32_t)0x01) << pinpos);
        }       
        else
        {
          // 判斷是否為上拉輸入模式
          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
          {
        // 上拉輸入模式,引腳預設值為1,對BSRR寄存器寫1可對引腳置1
            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
          }
        }
      }
    }
    // 把前面處理後的暫存值寫入到CRL寄存器之中
    GPIOx->CRL = tmpreg;
  }
/*-------------GPIO CRH 寄存器配置 CRH寄存器控制著高8位IO- -----------*/
  // 配置埠高8位,即Pin8~Pin15
  if (GPIO_InitStruct->GPIO_Pin 0x00FF)
  {
    // // 先備份CRH寄存器的值
    tmpreg = GPIOx->CRH;
    
  // 迴圈,從Pin8開始配對,找出具體的Pin
    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    {
      pos = (((uint32_t)0x01) << (pinpos + 0x08));
      
      // pos與輸入參數GPIO_PIN作位與運算
      currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
      
   //若currentpin=pos,則找到使用的引腳
      if (currentpin == pos)
      {
    //pinpos的值左移兩位(乘以4),因為寄存器中4個寄存器位配置一個引腳
        pos = pinpos << 2;
        
      //把控制這個引腳的4個寄存器位清零,其它寄存器位不變
        pinmask = ((uint32_t)0x0F) << pos;
        tmpreg &= ~pinmask;
        
        // 向寄存器寫入將要配置的引腳的模式
        tmpreg |= (currentmode << pos);
        
    // 判斷是否為下拉輸入模式
        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
        {
      // 下拉輸入模式,引腳預設置0,對BRR寄存器寫1可對引腳置0
          GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
        }
         // 判斷是否為上拉輸入模式
        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
        {
      // 上拉輸入模式,引腳預設值為1,對BSRR寄存器寫1可對引腳置1
          GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
        }
      }
    }
  // 把前面處理後的暫存值寫入到CRH寄存器之中
    GPIOx->CRH = tmpreg;
  }
}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 某寶秒殺,用毫秒級的精準度來搶購! 還記得前段時間情人節,各種產品活動秒殺。結果自然少不了被對象一番折磨 (註意:不是new出來的哈,也不是橡膠的,實實在在的女朋友) 於是乎徹底激發了我的求生欲,在這種關頭我是必鬚髮揮出自己的才能了,這才有了這篇毫秒級秒殺的精品出來,話不多說直接進入主題 項目環境​ ...
  • 2022-10-11 10:58:41 😀 前言 本文開始流程式控制制方面的學習,主要包括用戶交互和流程式控制制語句,適合新手學習。 1 用戶交互Scanner 1.1 Scanner對象 Java提供了一個可以獲取用戶輸入的Scanner工具類 基本語法: Scanner s = new Scanner ...
  • 各種語言用到的編輯器 python開發:pycharm(收費),vscode(免費),sublintext, go開發:goland(收費),vscode,國產的 java:idea(收費),eclipse(免費),MyEclipse(收費) android:androidstudio(免費),ec ...
  • 大家好,我是三友~~ 最近突然心血來潮(就是閑的)就想著擼一個簡單的配置中心,順便也照葫蘆畫瓢給整合到SpringCloud。 本文大綱 配置中心的概述 隨著歷史的車輪不斷的前進,技術不斷的進步,單體架構的系統都逐漸轉向微服務架構。雖然微服務架構有諸多優點,但是隨著越來越多的服務實例的數量,配置的不 ...
  • 在一個項目中,客戶要求對報表中的簽名進行仿手寫的簽名處理,因此我們原先只是顯示相關人員的姓名的地方,需要採用手寫方式簽名,我們的報表是利用FastReport處理的,在利用楷體處理的時候,開發展示倒是正常效果,不過實際上在伺服器運行的時候,出來的確實正規的宋體格式,相應的字體都已經安裝,不過還是沒有... ...
  • 1.進程 進程的概念從字義上理解相對還是比較抽象的,但進程實際上對我們並不陌生,可以說它無時不刻的伴隨著我們的生活。當你每天上班打開電腦,運行微信與好友通訊、運行瀏覽器閱讀網頁新聞等,這一些將程式運行起來的操作,都屬於創建了一個進程。並且我們可以對同一種程式重覆運行多次,這意味著一個程式可以創建多個 ...
  • 一:背景 1.講故事 前段時間有位朋友微信找到我,說他生產機器上的 Console 服務看起來像是卡死了,也不生成日誌,對方也收不到我的httpclient請求,不知道程式出現什麼情況了,特來尋求幫助。 哈哈,一般來說卡死的情況在窗體程式(WinForm,WPF) 上特別多,在 Console,We ...
  • 導圖 1.inode表結構 每個文件的屬性信息,比如:文件的大小,時間,類型,許可權等,稱為文件的元數據(meta data) 元數據是存放在inode(index node)表中。inode 表中有很多條記錄組成,第一條記錄對應的存放了一個 文件的元數據信息。 1.1硬鏈接和軟連接 硬連接 同一個文 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...