/* stdperiph_gpio.h */- h& x: L& e0 ?! ^* ~ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx.h" /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STDPERIPH_GPIO_H; i/ g8 |6 o% n3 V# l* P- @! Y' q #define __STDPERIPH_GPIO_H _5 B( G; p8 }' @! y1 l1 Q 0 T' f7 W9 K: f9 M* o- w extern void StdPeriph_GPIO_Config(void);* U3 b; p' M% [! m extern void StdPeriph_GPIO_Driver(void); 5 K2 M' }3 J6 _- R union OutPort {- n; h6 U" `; v! |0 S7 d, y uint8_t all;1 c: b% d7 h6 c2 o struct { uint8_t b0:1; // 0 bit0 uint8_t b1:1; // 1 bit17 j7 {' a1 D* w7 p& o# b& j: n uint8_t b2:1; // 2 bit2 uint8_t b3:1; // 3 bit3 uint8_t b4:1; // 4 bit4 uint8_t b5:1; // 5 bit5" {5 c! U% }% q uint8_t b6:1; // 6 bit62 n8 d3 q3 C: E$ W' Y' ~; \ uint8_t b7:1; // 7 bit7 }bit;# X- E: \2 q; {2 }: x };7 T$ z! w; z5 a9 N+ l. v extern __IO union OutPort Q1;8 s$ ?! T3 E C: c : G1 ^% J4 C+ A8 j #endif& z2 k# f: h- [2 J /* stdperiph_gpio.c */% d( N4 o- C) f1 z" {7 Z/ B | /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx.h" #include "stm32f4xx_gpio.h"' H: P' W! o" [6 Q$ p! R8 P #include "stm32f4xx_rcc.h" 4 z. J5 Z' b# N% y* C$ `4 s struct BITS { uint16_t GPIO0:1; // 0 GPIO0. h! j6 J! I% W) [! ~5 b) r. r uint16_t GPIO1:1; // 1 GPIO1 uint16_t GPIO2:1; // 2 GPIO2' V4 M3 u' Y; a. Z uint16_t GPIO3:1; // 3 GPIO35 [ b t) ~8 c1 i9 A4 S uint16_t GPIO4:1; // 4 GPIO40 @ t$ c1 x2 {, n ~& @ uint16_t GPIO5:1; // 5 GPIO5+ k6 Y0 l" L, M' D2 c; T uint16_t GPIO6:1; // 6 GPIO6- Y) Y) j: }, H# M uint16_t GPIO7:1; // 7 GPIO7 uint16_t GPIO8:1; // 8 GPIO8 uint16_t GPIO9:1; // 9 GPIO9 uint16_t GPIO10:1; // 10 GPIO10" k( ^3 F/ \+ p$ C" W+ e uint16_t GPIO11:1; // 11 GPIO115 h) i8 f* ~% f" I, k- u* x; C' j uint16_t GPIO12:1; // 12 GPIO12 uint16_t GPIO13:1; // 13 GPIO13& X/ V" W% ]& X( H# f uint16_t GPIO14:1; // 14 GPIO14 uint16_t GPIO15:1; // 15 GPIO15 }; ! d# S4 M& J0 M6 l5 o8 y6 K f9 i union BSRL_REG {* G/ X3 F$ k# d4 Q% p; g6 |" v+ D2 U uint16_t all;$ S P* s5 |. L4 n struct BITS bit; };1 S2 j/ E/ T8 [. C' N5 | / y" H9 h" V" o4 W union BSRH_REG { uint16_t all; struct BITS bit; };! X5 I: R# Y- F8 S0 [+ {( Q' M __IO union BSRL_REG GPIOE_BSRL_Shadow; __IO union BSRH_REG GPIOE_BSRH_Shadow;+ `: |: f/ W6 |, u; a9 n1 Y2 X union OutPort {2 k* G6 H1 Z6 b: ^8 F uint8_t all;8 x' u5 x$ `6 }: n5 J struct { uint8_t b0:1; // 0 bit0 uint8_t b1:1; // 1 bit18 I, i( \7 \6 d+ I( ` 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 & h3 G1 C6 c' D9 ], ]9 A }bit; };. A, G Z* ^# i* A/ f 7 d$ }$ {$ i9 @ @1 C" X# u: b __IO union OutPort Q1;0 f# y, p0 V& E! k' | void StdPeriph_GPIO_Driver(void) { /* 1: 打开MOSFET 0: 关闭MOSFET */3 ^% ~) O$ n8 E0 V8 Y GPIOE_BSRL_Shadow.all = 0;( N) E1 N9 A7 z7 x GPIOE_BSRH_Shadow.all = 0; if(Q1.bit.b0 == 0){ GPIOE_BSRH_Shadow.bit.GPIO0 = 1; } else {, ^7 w+ g1 _. J( B# | GPIOE_BSRL_Shadow.bit.GPIO0 = 1; }0 b+ Y8 \* n1 v0 ]8 a if(Q1.bit.b1 == 0){ GPIOE_BSRH_Shadow.bit.GPIO1 = 1;3 m8 M6 [7 `1 i5 G' L- b } else { GPIOE_BSRL_Shadow.bit.GPIO1 = 1;3 w9 C0 T+ t6 g1 P. R } if(Q1.bit.b2 == 0){ GPIOE_BSRH_Shadow.bit.GPIO2 = 1;9 d3 O; g9 d8 @7 P+ D } else { GPIOE_BSRL_Shadow.bit.GPIO2 = 1; } if(Q1.bit.b3 == 0){ GPIOE_BSRH_Shadow.bit.GPIO3 = 1;, ~# y; O4 q b$ B } else { o a! G J) q/ K8 G2 ^5 a GPIOE_BSRL_Shadow.bit.GPIO3 = 1;0 `8 l9 H, g4 ~ }% y. J. C8 w, z) J' T5 i( M ] if(Q1.bit.b4 == 0){ GPIOE_BSRH_Shadow.bit.GPIO4 = 1;& H0 Y6 S9 P. |; P: x; |* C& q } else {3 n/ x( s' V* Q GPIOE_BSRL_Shadow.bit.GPIO4 = 1; } if(Q1.bit.b5 == 0){ GPIOE_BSRH_Shadow.bit.GPIO5 = 1;1 ~3 i) y5 R0 E$ C } else { GPIOE_BSRL_Shadow.bit.GPIO5 = 1; } if(Q1.bit.b6 == 0){ GPIOE_BSRH_Shadow.bit.GPIO6 = 1; } else {' Q5 x- f, y2 s& C/ I" r% Q! L0 H GPIOE_BSRL_Shadow.bit.GPIO6 = 1;. J) O* ~$ q( S) \1 {4 j# s }/ b' H9 h: J p+ h: ?- }- ^ if(Q1.bit.b7 == 0){% b2 y; @1 D" ]. M i+ K: R GPIOE_BSRH_Shadow.bit.GPIO7 = 1;7 C' o$ F+ B4 ?4 p: H0 W } else {8 O" @, D) f0 @( Z+ E GPIOE_BSRL_Shadow.bit.GPIO7 = 1;8 T0 W8 c& K. S# A3 h0 { } GPIOE->BSRRL = GPIOE_BSRL_Shadow.all;, C" A7 A* F9 E# V. v# X$ o GPIOE->BSRRH = GPIOE_BSRH_Shadow.all; } 8 F. U% c8 O4 |1 D & {2 u0 P7 ~& A9 u; F$ V |
《RT-Thread设备驱动开发指南》书籍学习记录
STM32F407/STM32F417通过以太网实现在应用中编程 (IAP)
STM32固件库分享,超全系列整理
分享STM32F407的学习资料 附学习笔记
STM32F4中文资料--基础篇
基于STM32F407和Cubemx的ADC采集+DMA传输实现简易示波器经验分享
基于STM32F407的DMA采样+FFT时域经验分享
基于STM32F407中的RNG获取随机数经验分享
【中文文档】AN3965_STM32F40x和STM32F41x基于串口的IAP
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
: |$ W; g9 s+ H8 h
注意事项:
1. 可以在主程序或定时程序中调用StdPeriph_GPIO_Driver函数,刷新GPIOE.0~GPIOE.7的状态。
2. 在应用程序中,只需访问Q1的位即可。例如下一句# I$ _% n# X; I2 s+ ^. h; @+ c
"Q1.bit.b0 = 1;"就可以修改GPIOE.0的状态为高电平;同样地,"Q1.bit.b0 = 0;"可以修改GPIOE.0的状态为低电平。+ r& V& `8 a6 C, ^( J6 G
StdPeriph_GPIO_Driver函数调用的频率,建议在1~10ms,满足要求的即可。
在MDK-ARM V5.15开发环境,键入"Q1."则会出现自动提示,Q1.all 是访问所有的位, Q1.bit.b7是访问最高位。- A: o7 s$ _# {: e. s
+ k9 C) D5 u6 y) F# v& \
补充说明:+ T6 {, F4 F' |1 A+ x8 A9 g: J5 C
1. 驱动编程的目的和出发点在于,仅在一个地方调用StdPeriph_GPIO_Driver函数,# ^% R( Q6 N5 ]* _5 {6 }1 v( M. e
用户层只操作Q1输出端口的8个位,8位变量Q1是函数对应用层提供的接口。
2.宏定义的作用& W, a9 M* h3 q Y; X# q
宏定义直接操作GPIO,可以立即刷新GPIO的输出状态。
例如在SPI通信中函数中,代码开头使CS片选脚变低,代码结尾使CS片选变高。! d1 y' f1 _7 F
3 A, K* Q! @5 H- a% F2 l
但宏定义不能给用户提供一个统一的中间变量。; h7 m0 ~4 h5 x( v% G+ ?; F* _
假设有二个输出端口Q1、Q2,每个端口均是8路输出,分别安排在任意的GPIOA-GPIOE,! ^" y8 X& R' V0 u3 ?
可以设置16个宏定义,将这16路输出端口设置为高,另外再设置16个宏定义,
分别将这16个输出端口设置为低。显然,这种写法将对GPIO的操作复杂化了。
宏定义保证了效率,但对于应用层而言,不利于用户的使用和记忆。
- l) G+ r* u2 i. R' k: F# w
7 N5 I( n6 [' a( V
0 [ X+ T/ U! {, W6 k/ q7 U4 ]
! F3 N# U: Y9 C9 y