你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F7xx —— 输出

[复制链接]
STMCU小助手 发布时间:2021-12-17 12:04
一、几个重要的IO口操作函数
  1. HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init);  // GPIO初始化

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

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

  4. void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // 电平取反
复制代码

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

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

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

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

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

三、封装两个GPIO初始化函数(普通GPIO,复用GPIO)
  1. // 这里只贴出代码片段,封装两个接口,一个普通GPIO初始化,一个带复用功能。
  2. #define GPIO_CLK_ENABLE() do{ \
  3.   __HAL_RCC_GPIOA_CLK_ENABLE(); \
  4.   __HAL_RCC_GPIOB_CLK_ENABLE(); \
  5.   __HAL_RCC_GPIOC_CLK_ENABLE(); \
  6.   __HAL_RCC_GPIOD_CLK_ENABLE(); \
  7.   __HAL_RCC_GPIOE_CLK_ENABLE(); \
  8.   __HAL_RCC_GPIOF_CLK_ENABLE(); \
  9.   __HAL_RCC_GPIOG_CLK_ENABLE(); \
  10.   __HAL_RCC_GPIOH_CLK_ENABLE(); \
  11.   __HAL_RCC_GPIOI_CLK_ENABLE(); \
  12. } while(0);

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

  16.   GPIO_CLK_ENABLE();

  17.   GPIO_InitStructure.Pin = pin;
  18.   GPIO_InitStructure.Mode = mode;
  19.   GPIO_InitStructure.Pull = pull;
  20.   GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;

  21.   HAL_GPIO_Init(gpio, &GPIO_InitStructure);
  22. }

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

  26.   GPIO_CLK_ENABLE();

  27.   GPIO_InitStructure.Pin = pin;
  28.   GPIO_InitStructure.Mode = mode;
  29.   GPIO_InitStructure.Pull = pull;
  30.   GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  31.   GPIO_InitStructure.Alternate = alternate;

  32.   HAL_GPIO_Init(gpio, &GPIO_InitStructure);
  33. }
复制代码


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

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

  8. #define OUTX_CONFIG(gpio, pin)    GPIOConfig(gpio, pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL)
  9. #define OUTX_READ(gpio, pin)      HAL_GPIO_ReadPin(gpio, pin)
  10. #define OUTX_ACTIVE(gpio, pin, tag) do{ \
  11.   if(OUTPUT_LOW_IS_ACTIVE == tag) \
  12.   { \
  13.     HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); \
  14.   } \
  15.   else \
  16.   { \
  17.     HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); \
  18.   } \
  19. } while(0);
  20. #define OUTX_NEGATIVE(gpio, pin, tag) do{ \
  21.   if(OUTPUT_LOW_IS_ACTIVE == tag) \
  22.   { \
  23.     HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); \
  24.   } \
  25.   else \
  26.   { \
  27.     HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); \
  28.   } \
  29. } while(0);

  30. #define OUT1_PORT                 GPIOA
  31. #define OUT1_PIN                  GPIO_PIN_0

  32. #define OUT2_PORT                 GPIOA
  33. #define OUT2_PIN                  GPIO_PIN_1

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

  4. static void output_config(GPIO_TypeDef *gpio, uint16_t pin)
  5. {
  6.   OUTX_CONFIG(gpio, pin);
  7. }

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

  13. static void output_active(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
  14. {
  15.   OUTX_ACTIVE(gpio, pin, tag);
  16. }

  17. static void output_negative(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
  18. {
  19.   OUTX_NEGATIVE(gpio, pin, tag);
  20. }

  21. static void output_toggle(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
  22. {
  23.   // 这里可以不用这么麻烦,使用HAL_GPIO_TogglePin
  24.   if(OUTX_READ(gpio, pin) == 0)
  25.   {
  26.     OUTX_ACTIVE(gpio, pin, tag);
  27.   }
  28.   else
  29.   {
  30.     OUTX_NEGATIVE(gpio, pin, tag);
  31.   }
  32. }

  33. typedef struct
  34. {
  35.   GPIO_TypeDef *gpio;
  36.   uint16_t pin;
  37.   void (* output_config_cb)(GPIO_TypeDef *gpio, uint16_t pin);
  38.   uint8_t (* output_is_enable_cb)(uint8_t index);
  39.   void (* output_active_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
  40.   void (* output_negative_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
  41.   void (* output_toggle_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
  42. } output_port_t;

  43. static output_port_t output_items[] =
  44. {
  45.   {OUT1_PORT, OUT1_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
  46.   {OUT2_PORT, OUT2_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
  47.   {OUT3_PORT, OUT3_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
  48. };

  49. static void output_init(uint32_t value)
  50. {
  51.   uint32_t i, mask = 1;

  52.   for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  53.   {
  54.     if(value & mask)
  55.     {
  56. #if(CONFIG_OUTPUT_TEST == 1)
  57.       config.output.total_switch = OUTPUT_MODE_OPEN;
  58.       config.output.sub_switch<i> = OUTPUT_MODE_OPEN;
  59.      </i> config.output.active_tag = OUTPUT_HIGH_IS_ACTIVE;
  60. #endif
  61.       output_items.output_config_cb(output_items.gpio, output_items.pin);
  62.       output_items.output_negative_cb(output_items.gpio, output_items.pin, config.output.active_tag);
  63.     }

  64.     mask <<= 1;
  65.   }
  66. }

  67. void OutputHigh(uint32_t value)
  68. {
  69.   uint32_t i, mask = 1;

  70.   for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  71.   {
  72.     if(value & mask)
  73.     {
  74.       if(output_items.output_is_enable_cb(i))
  75.       {
  76.         output_items.output_active_cb(output_items.gpio, output_items.pin, config.output.active_tag);
  77.       }
  78.     }

  79.     mask <<= 1;
  80.   }
  81. }

  82. void OutputLow(uint32_t value)
  83. {
  84.   uint32_t i, mask = 1;

  85.   for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  86.   {
  87.     if(value & mask)
  88.     {
  89.       if(output_items.output_is_enable_cb(i))
  90.       {
  91.         output_items.output_negative_cb(output_items.gpio, output_items.pin, config.output.active_tag);
  92.       }
  93.     }

  94.     mask <<= 1;
  95.   }
  96. }

  97. void OutputToggle(uint32_t value)
  98. {
  99.   uint32_t i, mask = 1;

  100.   for(i = 0; i < ARRAY_SIZE(output_items); ++i)
  101.   {
  102.     if(value & mask)
  103.     {
  104.       if(output_items.output_is_enable_cb(i))
  105.       {
  106.         output_items.output_toggle_cb(output_items.gpio, output_items.pin, config.output.active_tag);
  107.       }
  108.     }

  109.     mask <<= 1;
  110.   }
  111. }

  112. void OutputInit(void)
  113. {
  114.   output_init(0xFFFFFFFF);
  115.   OutputLow(0xFFFFFFFF);
  116. }

复制代码

收藏 评论0 发布时间:2021-12-17 12:04

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版