天天看點

STM32_GPIO一般使用配置置位與清零關于volatile類型

一般使用配置

打開Portx時鐘(RCC->APB2ENR)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx | RCC_APB2Periph_GPIOx, ENABLE); 
           
  • 下面是用到的宏定義。
#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)
#define RCC_APB2Periph_GPIOE             ((uint32_t)0x00000040)
#define RCC_APB2Periph_GPIOF             ((uint32_t)0x00000080)
#define RCC_APB2Periph_GPIOG             ((uint32_t)0x00000100)
           
typedef enum {DISABLE = , ENABLE = !DISABLE} FunctionalState;
           

配置使用的引腳、模式和速率

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x;   
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_x_x;  
//如果引腳設定為輸入模式則不需要配置速率
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_xMHz; 
           
  • 以下是用到的結構體、枚舉變量和宏定義。
typedef struct{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
           
#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */
           
typedef enum{
  GPIO_Mode_AIN = ,           //模拟輸入
  GPIO_Mode_IN_FLOATING = ,  //浮空輸入        
  GPIO_Mode_IPD = ,          //下拉輸入 
  GPIO_Mode_IPU = ,          //上拉輸入
  GPIO_Mode_Out_OD = ,       //開漏輸出
  GPIO_Mode_Out_PP = ,       //推挽輸出
  GPIO_Mode_AF_OD = ,        //複用開漏輸出
  GPIO_Mode_AF_PP =          //複用推挽輸出
}GPIOMode_TypeDef;
           
typedef enum{ 
  GPIO_Speed_10MHz = ,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
           

初始化GPIOx(GPIOx->CRH、GPIOx->CRL)

GPIO_Init(GPIOx, &GPIO_InitStructure);  
           
  • 以下是用到的宏定義。
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
           

置位與清零

置位(GPIOx->BSRR)

GPIO_SetBits(GPIOx, GPIO_Pin_x | GPIO_Pin_x);
           

清零(GPIOx->BRR)

GPIO_ResetBits(GPIOx, GPIO_Pin_x | GPIO_Pin_x);
           

擷取單個引腳資料(GPIOx->IDR)

GPIO_ReadInputDataBit(GPIOx, GPIO_Pin_x);
           

關于volatile類型

core_cm3.h

#ifdef __cplusplus
  #define     __I     volatile                /*!< defines 'read only' permissions      */
#else
  #define     __I     volatile const          /*!< defines 'read only' permissions      */
#endif
#define     __O     volatile                  /*!< defines 'write only' permissions     */
#define     __IO    volatile                  /*!< defines 'read / write' permissions   */
           

__I

是隻讀,作為輸入口,程式不應該試圖去修改它。如隻讀的狀态寄存器。

__O

是隻寫,作為輸出口。

__IO

是讀寫,作為輸入輸出口。

  • 實作一個volatile型參數的平方。如下是錯誤的。
long square(volatile int *ptr){   
    return *ptr * *ptr;  
}  
           
  • 由于

    *ptr

    的值可能被意想不到地改變,是以兩個

    *ptr

    可能不同。以下是正确代碼。
long square(volatile int *ptr){   
    int a;   
    a = *ptr;  
    return a * a;   
} 
           

繼續閱讀