STM32F7xx —— 输出

STM32F7xx —— 输出

 

目录

STM32F7xx —— 输出

一、几个重要的IO口操作函数

二、几个重要的结构

三、封装两个GPIO初始化函数(普通GPIO,复用GPIO)

四、输出接口设计


 

 

一、几个重要的IO口操作函数

HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init);  // GPIO初始化

HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); // 输出高低电平

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // 读IO口电平

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // 电平取反

 

二、几个重要的结构

// GPIO口  GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH,GPIOI
typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint32_t BSRR;     /*!< GPIO port bit set/reset register,      Address offset: 0x18      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef; 
// GPIO引脚,模式,上下拉,速度,复用等
typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

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

  uint32_t Alternate;  /*!< Peripheral to be connected to the selected pins. 
                            This parameter can be a value of @ref GPIO_Alternate_function_selection */
}GPIO_InitTypeDef;
// GPIO引脚
#define GPIO_PIN_0                 ((uint16_t)0x0001U)  /* Pin 0 selected    */
#define GPIO_PIN_1                 ((uint16_t)0x0002U)  /* Pin 1 selected    */
#define GPIO_PIN_2                 ((uint16_t)0x0004U)  /* Pin 2 selected    */
#define GPIO_PIN_3                 ((uint16_t)0x0008U)  /* Pin 3 selected    */
#define GPIO_PIN_4                 ((uint16_t)0x0010U)  /* Pin 4 selected    */
#define GPIO_PIN_5                 ((uint16_t)0x0020U)  /* Pin 5 selected    */
#define GPIO_PIN_6                 ((uint16_t)0x0040U)  /* Pin 6 selected    */
#define GPIO_PIN_7                 ((uint16_t)0x0080U)  /* Pin 7 selected    */
#define GPIO_PIN_8                 ((uint16_t)0x0100U)  /* Pin 8 selected    */
#define GPIO_PIN_9                 ((uint16_t)0x0200U)  /* Pin 9 selected    */
#define GPIO_PIN_10                ((uint16_t)0x0400U)  /* Pin 10 selected   */
#define GPIO_PIN_11                ((uint16_t)0x0800U)  /* Pin 11 selected   */
#define GPIO_PIN_12                ((uint16_t)0x1000U)  /* Pin 12 selected   */
#define GPIO_PIN_13                ((uint16_t)0x2000U)  /* Pin 13 selected   */
#define GPIO_PIN_14                ((uint16_t)0x4000U)  /* Pin 14 selected   */
#define GPIO_PIN_15                ((uint16_t)0x8000U)  /* Pin 15 selected   */
// GPIO模式  输入 推挽输出 开漏输出 推挽复用 开漏复用
#define  GPIO_MODE_INPUT                        ((uint32_t)0x00000000U)   /*!< Input Floating Mode                   */
#define  GPIO_MODE_OUTPUT_PP                    ((uint32_t)0x00000001U)   /*!< Output Push Pull Mode                 */
#define  GPIO_MODE_OUTPUT_OD                    ((uint32_t)0x00000011U)   /*!< Output Open Drain Mode                */
#define  GPIO_MODE_AF_PP                        ((uint32_t)0x00000002U)   /*!< Alternate Function Push Pull Mode     */
#define  GPIO_MODE_AF_OD                        ((uint32_t)0x00000012U)   /*!< Alternate Function Open Drain Mode    */
// GPIO速度 低速  中速  高速  极速
#define  GPIO_SPEED_FREQ_LOW         ((uint32_t)0x00000000U)  /*!< Low speed     */
#define  GPIO_SPEED_FREQ_MEDIUM      ((uint32_t)0x00000001U)  /*!< Medium speed  */
#define  GPIO_SPEED_FREQ_HIGH        ((uint32_t)0x00000002U)  /*!< Fast speed    */
#define  GPIO_SPEED_FREQ_VERY_HIGH   ((uint32_t)0x00000003U)  /*!< High speed    */
// GPIO上下拉 无上下拉  上拉  下拉
#define  GPIO_NOPULL        ((uint32_t)0x00000000U)   /*!< No Pull-up or Pull-down activation  */
#define  GPIO_PULLUP        ((uint32_t)0x00000001U)   /*!< Pull-up activation                  */
#define  GPIO_PULLDOWN      ((uint32_t)0x00000002U)   /*!< Pull-down activation                */
// GPIO引脚高低电平
typedef enum
{
  GPIO_PIN_RESET = 0,
  GPIO_PIN_SET
}GPIO_PinState;

三、封装两个GPIO初始化函数(普通GPIO,复用GPIO)

// 这里只贴出代码片段,封装两个接口,一个普通GPIO初始化,一个带复用功能。
#define GPIO_CLK_ENABLE() do{ \
  __HAL_RCC_GPIOA_CLK_ENABLE(); \
  __HAL_RCC_GPIOB_CLK_ENABLE(); \
  __HAL_RCC_GPIOC_CLK_ENABLE(); \
  __HAL_RCC_GPIOD_CLK_ENABLE(); \
  __HAL_RCC_GPIOE_CLK_ENABLE(); \
  __HAL_RCC_GPIOF_CLK_ENABLE(); \
  __HAL_RCC_GPIOG_CLK_ENABLE(); \
  __HAL_RCC_GPIOH_CLK_ENABLE(); \
  __HAL_RCC_GPIOI_CLK_ENABLE(); \
} while(0);

void GPIOConfig(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_t pull)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_CLK_ENABLE();

  GPIO_InitStructure.Pin = pin;
  GPIO_InitStructure.Mode = mode;
  GPIO_InitStructure.Pull = pull;
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;

  HAL_GPIO_Init(gpio, &GPIO_InitStructure);
}

void GPIOConfigExt(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_t pull, uint32_t alternate)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_CLK_ENABLE();

  GPIO_InitStructure.Pin = pin;
  GPIO_InitStructure.Mode = mode;
  GPIO_InitStructure.Pull = pull;
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStructure.Alternate = alternate;

  HAL_GPIO_Init(gpio, &GPIO_InitStructure);
}

四、输出接口设计

为了灵活使用,我们将输出的有效电平设置成可配置。

// 配置的有效电平 初始  低电平有效  高电平有效
typedef enum
{
  OUTPUT_INIT_IS_ACTIVE = 0,
  OUTPUT_LOW_IS_ACTIVE  = 1,
  OUTPUT_HIGH_IS_ACTIVE = 2,
} output_active_t;

#define OUTX_CONFIG(gpio, pin)    GPIOConfig(gpio, pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL)
#define OUTX_READ(gpio, pin)      HAL_GPIO_ReadPin(gpio, pin)
#define OUTX_ACTIVE(gpio, pin, tag) do{ \
  if(OUTPUT_LOW_IS_ACTIVE == tag) \
  { \
    HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); \
  } \
  else \
  { \
    HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); \
  } \
} while(0);
#define OUTX_NEGATIVE(gpio, pin, tag) do{ \
  if(OUTPUT_LOW_IS_ACTIVE == tag) \
  { \
    HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); \
  } \
  else \
  { \
    HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); \
  } \
} while(0);

#define OUT1_PORT                 GPIOA
#define OUT1_PIN                  GPIO_PIN_0

#define OUT2_PORT                 GPIOA
#define OUT2_PIN                  GPIO_PIN_1

#define OUT3_PORT                 GPIOA
#define OUT3_PIN                  GPIO_PIN_2
// demo代码 只传递思想 
// 封装出对外的四个接口 初始化 输出有效 输出无效 输出取反 
// 以列表的形式封装 方便增加和删除

static void output_config(GPIO_TypeDef *gpio, uint16_t pin)
{
  OUTX_CONFIG(gpio, pin);
}

static uint8_t output_is_enable(uint8_t index)
{
  // 输出通道可用 这里也可以变成可配置 可以配置本IO口有效和无效
  return 1;
}

static void output_active(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
{
  OUTX_ACTIVE(gpio, pin, tag);
}

static void output_negative(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
{
  OUTX_NEGATIVE(gpio, pin, tag);
}

static void output_toggle(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
{
  // 这里可以不用这么麻烦,使用HAL_GPIO_TogglePin
  if(OUTX_READ(gpio, pin) == 0)
  {
    OUTX_ACTIVE(gpio, pin, tag);
  }
  else
  {
    OUTX_NEGATIVE(gpio, pin, tag);
  }
}

typedef struct
{
  GPIO_TypeDef *gpio;
  uint16_t pin;
  void (* output_config_cb)(GPIO_TypeDef *gpio, uint16_t pin);
  uint8_t (* output_is_enable_cb)(uint8_t index);
  void (* output_active_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
  void (* output_negative_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
  void (* output_toggle_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
} output_port_t;

static output_port_t output_items[] =
{
  {OUT1_PORT, OUT1_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
  {OUT2_PORT, OUT2_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
  {OUT3_PORT, OUT3_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
};

static void output_init(uint32_t value)
{
  uint32_t i, mask = 1;

  for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  {
    if(value & mask)
    {
#if(CONFIG_OUTPUT_TEST == 1)
      config.output.total_switch = OUTPUT_MODE_OPEN;
      config.output.sub_switch[i] = OUTPUT_MODE_OPEN;
      config.output.active_tag[i] = OUTPUT_HIGH_IS_ACTIVE;
#endif
      output_items[i].output_config_cb(output_items[i].gpio, output_items[i].pin);
      output_items[i].output_negative_cb(output_items[i].gpio, output_items[i].pin, config.output.active_tag[i]);
    }

    mask <<= 1;
  }
}

void OutputHigh(uint32_t value)
{
  uint32_t i, mask = 1;

  for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  {
    if(value & mask)
    {
      if(output_items[i].output_is_enable_cb(i))
      {
        output_items[i].output_active_cb(output_items[i].gpio, output_items[i].pin, config.output.active_tag[i]);
      }
    }

    mask <<= 1;
  }
}

void OutputLow(uint32_t value)
{
  uint32_t i, mask = 1;

  for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  {
    if(value & mask)
    {
      if(output_items[i].output_is_enable_cb(i))
      {
        output_items[i].output_negative_cb(output_items[i].gpio, output_items[i].pin, config.output.active_tag[i]);
      }
    }

    mask <<= 1;
  }
}

void OutputToggle(uint32_t value)
{
  uint32_t i, mask = 1;

  for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  {
    if(value & mask)
    {
      if(output_items[i].output_is_enable_cb(i))
      {
        output_items[i].output_toggle_cb(output_items[i].gpio, output_items[i].pin, config.output.active_tag[i]);
      }
    }

    mask <<= 1;
  }
}

void OutputInit(void)
{
  output_init(0xFFFFFFFF);
  OutputLow(0xFFFFFFFF);
}

 

 

 

 

 

 

Version: 2.12.0 (2019-07-17) Keil.STM32F7xx_DFP.2.12.0.pack Download Updated Pack to include subset of STM32Cube_FW_F7 Firmware Package version V1.15.0 using HAL Drivers V1.2.7 Added support for Low Level (LL) drivers. Corrected RTE_Device.h file (I2C3_SDA) Corrected condition for selecting HAL RCC MX_Device_h.ftl: Updated parsing of USART virtual mode Updated generation of macros: Added handling for '(' and ')' symbols Corrected launching STM32CubeMX via "play" button for existing projects overwrites with a new STM32CubeMX project file instead of loading existing. Updated Board Examples: graphics examples use Segger emWin version 5.50.0. examples enable Event Recorder in debug targets Updated LCDConf.c (ready for GUI_USE_ARGD = 1) CMSIS-Driver: CAN: Corrected SetBitrate function to leave Silent and Loopback mode as they were. Corrected SetMode function to clear Silent and Loopback mode when NORMAL mode is activated. Corrected MessageSend function to only access required data for sending. EMAC: Corrected __MEMORY_AT(x) define to be compliant with Arm Compiler 6. Corrected: ETH DMA initialization moved to enable of MAC transmitter or receiver solving netInitialize/netUnnitialize/netInitialize sequence. I2C: Corrected transfers for data sizes greater than 255 (Complete Reload handling). Corrected I2C_SlaveReceive functionality. Corrected code alignment. MCI: Added data cache handling. USART: Added check for valid pointer to USART_PIN prior to use. Corrected POWER_OFF sequence. DMA is DeInitialized after it is aborted. USB Device: Updated USBD_EndpointConfigure function to check that maximum packet size requested fits into configured FIFO (compile time configured). I/O output speed is configurable SPI: Updated SPI_TRANSFER_INFO structure - tx_buf type changed from uint8_t * to const uint8_t *. Added check for valid pointer to SPI_PIN prior to use.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值