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

STM32F4xxx简洁GPIO驱动,参考DSP库,定义了位变量.

[复制链接]
wjandsq 发布时间:2015-7-29 21:10
/* stdperiph_gpio.h */

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STDPERIPH_GPIO_H
#define __STDPERIPH_GPIO_H

extern void StdPeriph_GPIO_Config(void);
extern void StdPeriph_GPIO_Driver(void);

union OutPort {
  uint8_t all;
  struct {
    uint8_t b0:1;            // 0      bit0
    uint8_t b1:1;            // 1      bit1
    uint8_t b2:1;            // 2      bit2
    uint8_t b3:1;            // 3      bit3
    uint8_t b4:1;            // 4      bit4
    uint8_t b5:1;            // 5      bit5
    uint8_t b6:1;            // 6      bit6
    uint8_t b7:1;            // 7      bit7   
  }bit;
};

extern __IO union OutPort Q1;

#endif

/* stdperiph_gpio.c */
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"

struct BITS {
   uint16_t GPIO0:1;            // 0      GPIO0
   uint16_t GPIO1:1;            // 1      GPIO1
   uint16_t GPIO2:1;            // 2      GPIO2
   uint16_t GPIO3:1;            // 3      GPIO3
   uint16_t GPIO4:1;            // 4      GPIO4
   uint16_t GPIO5:1;            // 5      GPIO5
   uint16_t GPIO6:1;            // 6      GPIO6
   uint16_t GPIO7:1;            // 7      GPIO7
   uint16_t GPIO8:1;            // 8      GPIO8
   uint16_t GPIO9:1;            // 9      GPIO9
   uint16_t GPIO10:1;           // 10     GPIO10
   uint16_t GPIO11:1;           // 11     GPIO11
   uint16_t GPIO12:1;           // 12     GPIO12
   uint16_t GPIO13:1;           // 13     GPIO13
   uint16_t GPIO14:1;           // 14     GPIO14
   uint16_t GPIO15:1;           // 15     GPIO15
};

union BSRL_REG {
   uint16_t all;
   struct BITS bit;
};

union BSRH_REG {
   uint16_t all;
   struct BITS bit;
};

__IO union BSRL_REG GPIOE_BSRL_Shadow;
__IO union BSRH_REG GPIOE_BSRH_Shadow;


union OutPort {
  uint8_t all;
  struct {
    uint8_t b0:1;            // 0      bit0
    uint8_t b1:1;            // 1      bit1
    uint8_t b2:1;            // 2      bit2
    uint8_t b3:1;            // 3      bit3
    uint8_t b4:1;            // 4      bit4
    uint8_t b5:1;            // 5      bit5
    uint8_t b6:1;            // 6      bit6
    uint8_t b7:1;            // 7      bit7   
  }bit;
};

__IO union OutPort Q1;

void StdPeriph_GPIO_Driver(void)
{
  /* 1: 打开MOSFET 0: 关闭MOSFET */
  GPIOE_BSRL_Shadow.all = 0;
  GPIOE_BSRH_Shadow.all = 0;
  if(Q1.bit.b0 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO0 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO0 = 1;
  }
  if(Q1.bit.b1 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO1 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO1 = 1;
  }
  if(Q1.bit.b2 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO2 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO2 = 1;
  }
  if(Q1.bit.b3 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO3 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO3 = 1;
  }
  if(Q1.bit.b4 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO4 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO4 = 1;
  }
  if(Q1.bit.b5 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO5 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO5 = 1;
  }
  if(Q1.bit.b6 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO6 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO6 = 1;
  }
  if(Q1.bit.b7 == 0){
    GPIOE_BSRH_Shadow.bit.GPIO7 = 1;
  } else {
    GPIOE_BSRL_Shadow.bit.GPIO7 = 1;
  }
  GPIOE->BSRRL = GPIOE_BSRL_Shadow.all;
  GPIOE->BSRRH = GPIOE_BSRH_Shadow.all;
}


评分

参与人数 1 ST金币 +15 收起 理由
沐紫 + 15 赞一个!

查看全部评分

收藏 评论9 发布时间:2015-7-29 21:10

举报

9个回答
wjandsq 回答时间:2015-7-29 21:22:00
本帖最后由 wjandsq 于 2015-7-30 22:29 编辑

注意事项:
1. 可以在主程序或定时程序中调用StdPeriph_GPIO_Driver函数,刷新GPIOE.0~GPIOE.7的状态。
2. 在应用程序中,只需访问Q1的位即可。例如下一句
   "Q1.bit.b0 = 1;"就可以修改GPIOE.0的状态为高电平;同样地,"Q1.bit.b0 = 0;"可以修改GPIOE.0的状态为低电平。
   StdPeriph_GPIO_Driver函数调用的频率,建议在1~10ms,满足要求的即可。
   在MDK-ARM V5.15开发环境,键入"Q1."则会出现自动提示,Q1.all 是访问所有的位, Q1.bit.b7是访问最高位。

moyanming2013 回答时间:2015-7-29 21:31:37
2.jpg
lkl0305 回答时间:2015-7-29 21:58:50
学习学习
mark0668 回答时间:2015-7-29 22:46:28
3.jpg
党国特派员 回答时间:2015-7-30 08:13:52
学习学习 null.png null1.png
yanhaijian 回答时间:2015-7-30 08:35:39
要简洁用宏定义。
风子 回答时间:2015-7-30 09:04:53
学习学习
stary666 回答时间:2015-7-30 09:17:58
看看,,,,,,,,,,,,,
wjandsq 回答时间:2015-7-30 20:15:46
本帖最后由 wjandsq 于 2015-7-30 22:35 编辑

补充说明:
1. 驱动编程的目的和出发点在于,仅在一个地方调用StdPeriph_GPIO_Driver函数,
   用户层只操作Q1输出端口的8个位,8位变量Q1是函数对应用层提供的接口。

2.宏定义的作用
  宏定义直接操作GPIO,可以立即刷新GPIO的输出状态。
  例如在SPI通信中函数中,代码开头使CS片选脚变低,代码结尾使CS片选变高。

  但宏定义不能给用户提供一个统一的中间变量。
  假设有二个输出端口Q1、Q2,每个端口均是8路输出,分别安排在任意的GPIOA-GPIOE,
   可以设置16个宏定义,将这16路输出端口设置为高,另外再设置16个宏定义,
  分别将这16个输出端口设置为低。显然,这种写法将对GPIO的操作复杂化了。
  宏定义保证了效率,但对于应用层而言,不利于用户的使用和记忆。




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