久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: GPIO_Init()函數詳解 [打印本頁]

作者: jiajialin    時間: 2015-5-20 02:28
標題: GPIO_Init()函數詳解
函數目的:對GPIO進行初始化。
如果對寄存器操作GPIO有一定了解的話,對下面理解起來就比較簡單。
如果將GPIO口設置為輸出模式,要設置兩個寄存器,CRL與ODR。
CRL:規定了低8位GPIO的輸出輸入狀態模式。
ODR:只用[15:0]確定GPIO端口的輸出值。
如下重點要理解CRL的工作方式。

CRL設置原理如上:
例如設置端口PD7,那么就需要設置[31:28]四位,首先確定輸入低二位輸入輸出狀態及輸出模式下的速度,高二位設置GPIO端口的工作方式。如果不理解,多看看兩幅原理圖。
編寫GPIO_Init()的原理(以CRL為例):
1.首先對GPIO_Mode,GPIO_Pin,GPIO_Speed進行宏定義。與CRL中使用略有差異,對GPIO_Mode中的定義,可以看到輸出模式下的定義的高四位均為0x1.而輸入模式下設置為0/2/4,此舉的目的是為了便于計算機進行識別處理。進行完第一步后,能夠的得到4位的GPIO的狀態的數據。
2.管腳及管腳的輸出值如何確定。這是GPIO_Init()的第二個難點。
首先確定GPIO_Pin是哪個管腳,然后確定后,將CRL寄存器的4*Pin的位置上的數據值為零,然后將第一步的取得值賦予CRL。
3.CRH和CRL的原理相同,通過 if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)來判斷是設置GPIO的低8位和高8位。

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
//GPIO_Init()函數定義
{
  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
  uint32_t tmpreg = 0x00, pinmask = 0x00;
//定義變量用作GPIO中CRL、CRH、ODR的判定

  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
  assert_param(IS_GPIO_PIN
(GPIO_InitStruct->GPIO_Pin));  
  //檢查實參是否符合要求

  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
//將GPIO_Mode的值與0x0f相與,只取Mode的低四位將值賦予currentmode。
  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
//說明是輸出。需要對速度進行配置。
// GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
由此可以看出當上式判斷為真時,即GPIO設定為輸出模式。則進行下步判斷。
  {

assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
//判斷GPIO_Speed的速度值是否符合要求

currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
//若為輸出,將速度配置到最后兩位。
//注意:因為GPIO_Mode設置的值得低二位均為零,所以將GPIO_Speed賦予currentmode。
  }


  if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
//判斷是否是設置CRL。
  {
tmpreg = GPIOx->CRL;
//首先將GPIOx_CRL的值賦予tmpreg。
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
//通過循環比較,確定管腳
    {
      pos = ((uint32_t)0x01) << pinpos;
//位移操作,簡單好用

      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
//   將定義的GPIO_Pin與pos相與,如同下句,對管腳定位
      if (currentpin == pos)
//如果管腳確定為第pos個管腳。
      {
        pos = pinpos << 2;
//那么就將pinpos的向左位移兩位。即理解為位置乘以4.這需要看下CRL寄存器原理

        pinmask = ((uint32_t)0x0F) << pos;
//將0x0f(1111)向左位移pos位(剛剛經過pinpos向左位移過兩位)。即將CRL要處理的位置進行處理。
        tmpreg &= ~pinmask;
//將tmpreg的相應位置置零!

        tmpreg |= (currentmode << pos);
//將剛剛設置好的currentmode放置到指定的位置(原理參照CRL)。

        if (GPIO_InitStruct->GPIO  _Mode == GPIO_Mode_IPD)
        {
          GPIOx->BRR = (((uint32_t)0x01) << pinpos);
        }
        else
        {

          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
          {
            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
          }
//若為上下拉輸入。如上設置,較為簡單。
        }
      }
    }
    GPIOx->CRL = tmpreg;
  }


  if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
  {
    tmpreg = GPIOx->CRH;
    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    {
      pos = (((uint32_t)0x01) << (pinpos + 0x08));

      currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
      if (currentpin == pos)
      {
        pos = pinpos << 2;

        pinmask = ((uint32_t)0x0F) << pos;
        tmpreg &= ~pinmask;

        tmpreg |= (currentmode << pos);

        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
        {
          GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
        }

        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
        {
          GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
        }
      }
    }
    GPIOx->CRH = tmpreg;
  }
}


作者: katv0718    時間: 2022-9-6 21:48
好,分析得很詳細,謝謝!
作者: 我,菜雞    時間: 2022-12-17 11:49
樓主辛苦了,剛好想做一個基于寄存器的IO口初始化函數,便于不同IO口的快速操作。,
作者: lml_user    時間: 2023-10-11 11:54
很詳細




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 日韩中文字幕在线视频 | 免费三片在线观看网站v888 | 免费日韩av | 欧美三级韩国三级日本三斤在线观看 | 艳妇乳肉豪妇荡乳 | 亚洲爱爱网 | 久操精品 | 香蕉视频网站 | 国产一区二区精品丝袜 | 亚欧在线观看 | 伊人精品视频 | 久久精品一区二区国产 | 成人羞羞国产免费 | 欧美精品一区在线 | 国产高清一区二区三区 | 不卡视频一区二区 | 国产日韩一区 | 欧美在线视频免费 | 国产三级在线播放 | 成年网站在线观看 | 一级黄毛片 | 欧美日韩一区二区三区四区 | 国产成人精品一区二区三区福利 | 亚洲一级大片 | 国产精品久久久久久久久 | 国产永久视频 | 国产日韩精品一区二区 | 国产精品一区二区免费 | 在线黄色av | 欧美黄色一区 | 青青久操 | 国产欧美精品一区二区三区 | 一级理论片| 国产精品久久网 | 亚洲欧美精品 | 亚洲乱码一区二区 | 激情综合久久 | 91亚洲精选| av激情影院 | 激情丁香婷婷 | 天堂中文在线视频 |