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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4034|回復: 1
收起左側

STM8固件庫GPIO學習筆記(轉帖)

[復制鏈接]
ID:75926 發表于 2015-4-3 00:12 | 顯示全部樓層 |閱讀模式
1、STM8的寄存器映射
STM8 core采用了哈佛結構,有兩條總線分別用于訪問Flash和RAM,但Flash,RAM,GPIO and peripheral registers都被映射到了線性的16Mbyte(24位地址)的存儲器空間中;stm8s208rb的GPIO and peripheral registers被映射到了0x00 5000 ~ 0x00 57FF地址空間。所以要在C語言中訪問外圍設備寄存器我們只需要指向這些地址空間的指針即可了。

2、STM8的寄存器的地址
在STM8中,與某個外圍設備有關的寄存器在地址上都是順序排列的;比如與GPIO有關的寄存器有ODR、IDR、DDR、CR1、CR2,與PA口有關的這五個寄存器就被安排在了0x00 5000~0x00 5004這5個地址空間中,它們有一個0x005000的基地址,分別偏移0,1,2,3,4。

3、”stm8s.h"中與GPIO有關的定義,以及固件庫中訪問外圍設備寄存器的方法
typedef struct GPIO_struct
{
  vu8 ODR; /*!< Output Data Register */
  vu8 IDR; /*!< Input Data Register */
  vu8 DDR; /*!< Data Direction Register */
  vu8 CR1; /*!< Configuration Register 1 */
  vu8 CR2; /*!< Configuration Register 2 */
}
GPIO_TypeDef;

#define GPIOA_BaseAddress       0x5000
#define GPIOB_BaseAddress       0x5005
#define GPIOC_BaseAddress       0x500A
#define GPIOD_BaseAddress       0x500F
#define GPIOE_BaseAddress       0x5014
#define GPIOF_BaseAddress       0x5019

#define GPIOA ((GPIO_TypeDef *) GPIOA_BaseAddress)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BaseAddress)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BaseAddress)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BaseAddress)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BaseAddress)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BaseAddress)

在結構體GPIO_TypeDef中,ODR,IDR,DDR,CR1,CR2的偏移分別是0,1,2,3,4正好與STM8S208RB對這幾個安排一致,當我們將0x5000這個地址轉換為指向GPIO_TypeDef的指針后,
我們就可以用類似GPIOA->ODR的方法訪問寄存器了。非常巧妙,STM32中也是這種方法。

4、GPIO特性簡述
STM8的每一個GPIO引腳都可以獨立的作為輸入/輸出IO引腳使用,作為輸入IO引腳使用時,每一個IO引腳都可以作為外部中斷的觸發輸入端使用,輸入有上拉和懸浮,輸出有模擬開漏和推挽模式。
DDR用于設置方向,ODR用于輸出,IDR用于輸入,CR1、CR2用于控制,具體可參考數據手冊,使用固件庫時我們可以不關心具體值。

5、GPIO的初始化
固件庫為我們提供了GPIO_Init這個函數,用于GPIO工作模式的初始化設置,它的原型為
void GPIO_Init(GPIO_TypeDef* GPIOx,  GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode);
第一個參數是上面提到的GPIOA這樣的指針,第二、三個參數都是枚舉型變量(本質就是一些常數),用來制定要初始化的引腳和工作模式。枚舉變量定義如下:
typedef enum
{
  GPIO_MODE_IN_FL_NO_IT      = (u8)0b00000000,  /*!< Input floating, no external interrupt */
  GPIO_MODE_IN_PU_NO_IT      = (u8)0b01000000,  /*!< Input pull-up, no external interrupt */
  GPIO_MODE_IN_FL_IT         = (u8)0b00100000,  /*!< Input floating, external interrupt */
  GPIO_MODE_IN_PU_IT         = (u8)0b01100000,  /*!< Input pull-up, external interrupt */
  GPIO_MODE_OUT_OD_LOW_FAST  = (u8)0b10000000,  /*!< Output open-drain, low level, no slope control */
  GPIO_MODE_OUT_PP_LOW_FAST  = (u8)0b11000000,  /*!< Output push-pull, low level, no slope control */
  GPIO_MODE_OUT_OD_LOW_SLOW  = (u8)0b10100000,  /*!< Output open-drain, low level, slow slope */
  GPIO_MODE_OUT_PP_LOW_SLOW  = (u8)0b11100000,  /*!< Output push-pull, low level, slow slope */
  GPIO_MODE_OUT_OD_HIZ_FAST  = (u8)0b10010000,  /*!< Output open-drain, high-impedance level, no slope control */
  GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0b11010000,  /*!< Output push-pull, high level, no slope control */
  GPIO_MODE_OUT_OD_HIZ_SLOW  = (u8)0b10110000,  /*!< Output open-drain, high-impedance level, slow slope */
  GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0b11110000   /*!< Output push-pull, high level, slow slope */
}GPIO_Mode_TypeDef;

typedef enum
{
  GPIO_PIN_0    = ((u8)0x01),  /*!< Pin 0 selected */
  GPIO_PIN_1    = ((u8)0x02),  /*!< Pin 1 selected */
  GPIO_PIN_2    = ((u8)0x04),  /*!< Pin 2 selected */
  GPIO_PIN_3    = ((u8)0x08),   /*!< Pin 3 selected */
  GPIO_PIN_4    = ((u8)0x10),  /*!< Pin 4 selected */
  GPIO_PIN_5    = ((u8)0x20),  /*!< Pin 5 selected */
  GPIO_PIN_6    = ((u8)0x40),  /*!< Pin 6 selected */
  GPIO_PIN_7    = ((u8)0x80),  /*!< Pin 7 selected */
  GPIO_PIN_LNIB = ((u8)0x0F),  /*!< Low nibble pins selected */
  GPIO_PIN_HNIB = ((u8)0xF0),  /*!< High nibble pins selected */
  GPIO_PIN_ALL  = ((u8)0xFF)   /*!< All pins selected */
}GPIO_Pin_TypeDef;

我們可以如此使用這個函數:

#define LEDS_PORT (GPIOH)
#define LED1_PIN  (GPIO_PIN_3)
#define LED2_PIN  (GPIO_PIN_2)
#define LED3_PIN  (GPIO_PIN_1)
#define LED4_PIN  (GPIO_PIN_0)

#define BUTTON_PORT (GPIOC)
#define BUTTON_PIN  (GPIO_PIN_0)

/* Initialize I/Os in Output Mode */
GPIO_Init(LEDS_PORT, (LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN), GPIO_MODE_OUT_PP_LOW_FAST);
/* Initialize I/O in Input Mode with Interrupt */
GPIO_Init(BUTTON_PORT, BUTTON_PIN, GPIO_MODE_IN_FL_IT);

6、GPIO的操作函數
void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal);             //寫端口,8個腳一起設置
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); // 將指定腳設置為高
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);  // 講指定腳設置為低
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);  // 指定腳取反
u8 GPIO_ReadInputData(GPIO_TypeDef* GPIOx);  // 讀引腳
u8 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);  // 讀端口,上次鎖存到ODR中的數據
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin); // 讀制定腳的狀態,高電平返回非0,低返回0

// NewState取值為ENABLE或DISABLE,用于配置外部的上拉有效或無效?這個函數怎么用我不懂,還請懂的朋友告知,非常感謝!
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
  assert_param(IS_FUNCTIONALSTATE_OK(NewState));

  if (NewState != DISABLE) /* External Pull-Up Set*/
  {
    GPIOx->CR1 |= (u8)GPIO_Pin;       // CR1=1時,如輸入則上拉,如輸出則推挽
  } else /* External Pull-Up Reset*/
  {
    GPIOx->CR1 &= (u8)(~(GPIO_Pin));  //CR1=0時,如輸入則懸浮,如輸出則開漏
  }
}

回復

使用道具 舉報

ID:502505 發表于 2019-7-9 13:38 | 顯示全部樓層
收藏起
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 毛片的网址 | 久久综合一区二区 | 亚洲国产一 | 国产一级一级 | 九色在线观看 | 偷拍自拍网 | 国产精品成人在线播放 | 久久er精品 | 精产国产伦理一二三区 | 91亚洲国产 | av一级久久 | 欧美午夜视频 | 亚洲天堂男人的天堂 | 神马久久久久久久久久 | 国产精品视频播放 | 久久久久亚洲国产| 亚洲精品国产综合区久久久久久久 | 日本免费一区二区三区四区 | 欧美视频一区二区三区 | 天天夜碰日日摸日日澡 | 免费在线观看av片 | 中文字幕精品一区久久久久 | 9久久| 一区二区三区av | 国产小视频在线 | 亚洲一区二区中文字幕 | 国产精品精品视频 | 色就干 | 成人国产免费视频 | 国产精品久久久久久久久久免费看 | 欧美最猛黑人xxxⅹ 粉嫩一区二区三区四区公司1 | 国产日韩一区二区 | 91免费看片 | 国产高清视频在线观看 | 日日摸夜夜添夜夜添精品视频 | 色精品| 国产精品欧美大片 | 中文字幕一二三区 | 日韩国产欧美一区 | 97在线播放 | 亚洲国产精品自拍 |