/* stdperiph_gpio.h */ - d6 R& w! c- A9 ]7 P" C( j /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx.h"7 o5 s& N1 O' S, `9 p/ x /* Define to prevent recursive inclusion -------------------------------------*/7 ~' a* `/ H& ?$ H1 D #ifndef __STDPERIPH_GPIO_H. f) I7 u+ T" Z* [ #define __STDPERIPH_GPIO_H4 q4 `$ ]4 t" r/ C4 T/ v extern void StdPeriph_GPIO_Config(void);( H+ P4 D9 @$ S& @/ _ extern void StdPeriph_GPIO_Driver(void); union OutPort {6 A& k: s2 n, d T9 F uint8_t all; struct {8 s7 U9 t* y( {4 d+ X. x- W uint8_t b0:1; // 0 bit0' B: B5 Z) t" t! a( s' @2 y uint8_t b1:1; // 1 bit1: j' y$ f9 N5 q1 L9 r uint8_t b2:1; // 2 bit23 I) p+ U' n% V4 [( b* Y# F uint8_t b3:1; // 3 bit36 J% ]/ a" y" `$ g& m uint8_t b4:1; // 4 bit4 uint8_t b5:1; // 5 bit5/ s* ]- q9 G( C: A uint8_t b6:1; // 6 bit6/ \% F: w! w' @ uint8_t b7:1; // 7 bit7 }bit; }; extern __IO union OutPort Q1; 5 @6 x( p8 r6 [3 L/ @: | #endif2 t! |% |' k+ F" U2 x6 M 6 W+ y, m- a# J8 l Q /* stdperiph_gpio.c */ /* Includes ------------------------------------------------------------------*/* |9 q8 }0 ` S1 T' P9 t4 a. F #include "stm32f4xx.h" #include "stm32f4xx_gpio.h"6 Z& ^9 z W) A3 J. x) n #include "stm32f4xx_rcc.h", w) t/ |' k, L3 B4 v( c; `5 O3 g h* q# W& |3 N0 O- L: G& J" [ struct BITS {2 i8 F' ?4 c2 p# q uint16_t GPIO0:1; // 0 GPIO0 uint16_t GPIO1:1; // 1 GPIO1 uint16_t GPIO2:1; // 2 GPIO2; `& h' \" j% i- A- ^5 V uint16_t GPIO3:1; // 3 GPIO3 uint16_t GPIO4:1; // 4 GPIO4 uint16_t GPIO5:1; // 5 GPIO5- U$ S4 {( \3 W" A! S. e. J' }4 T9 A# g uint16_t GPIO6:1; // 6 GPIO6; L' l _0 i$ C! l2 K( O% l 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; \1 n2 z' }. N' f* J: \ uint16_t GPIO14:1; // 14 GPIO14 uint16_t GPIO15:1; // 15 GPIO15 }; 1 y3 w' Z# i# H- F% ?" ^ union BSRL_REG { uint16_t all;- @/ K' z( n7 U% A+ ~2 H9 C0 C f struct BITS bit;4 ]) o& Z. S1 | };* O! M, j" f4 v0 f# y6 o9 @ Y) j( g, a - o( E; h% f' |( u% T6 @ union BSRH_REG { uint16_t all;; y* `9 _3 M' L# ^ struct BITS bit; };0 _0 X3 p6 b( |* y" Z& n3 U / K0 p: E) U- Z7 m __IO union BSRL_REG GPIOE_BSRL_Shadow; __IO union BSRH_REG GPIOE_BSRH_Shadow; ' k" k; p( k0 t( a % `' ^% O6 e/ a" G0 Y4 C+ g, S union OutPort {6 J5 z+ [4 ^! \8 C: e uint8_t all; struct { uint8_t b0:1; // 0 bit0 uint8_t b1:1; // 1 bit1( W+ _% f0 t1 y5 Y! D 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 ; G. l0 S0 L' Q. }: T: T0 ^1 s7 P }bit;3 _; d* ?, S5 F }; . }" o* L7 S6 O+ B& E' N+ Z __IO union OutPort Q1; void StdPeriph_GPIO_Driver(void); X2 j. ~+ [$ o# `8 C% P {; c `! D; f% u3 v /* 1: 打开MOSFET 0: 关闭MOSFET */5 ?- ?, Z* t8 \0 {6 t GPIOE_BSRL_Shadow.all = 0;& W& v/ I+ [/ g- a GPIOE_BSRH_Shadow.all = 0; if(Q1.bit.b0 == 0){! C0 Y* D8 }; c" h GPIOE_BSRH_Shadow.bit.GPIO0 = 1;$ l8 O, q. O* C) r/ M& | U! w } else {, u* U4 y8 {( P GPIOE_BSRL_Shadow.bit.GPIO0 = 1;$ N8 y+ _5 S( B/ n }! x6 M% f3 D; b" {- ]2 ^7 ~0 w6 |% d if(Q1.bit.b1 == 0){) R. W3 S; H6 g) M GPIOE_BSRH_Shadow.bit.GPIO1 = 1; } else {# z! X7 W- f, u* S/ J8 E0 Z GPIOE_BSRL_Shadow.bit.GPIO1 = 1;) C& m! f0 y: v3 E' N } if(Q1.bit.b2 == 0){ GPIOE_BSRH_Shadow.bit.GPIO2 = 1; E; y' e, t2 c } else { GPIOE_BSRL_Shadow.bit.GPIO2 = 1; } if(Q1.bit.b3 == 0){ GPIOE_BSRH_Shadow.bit.GPIO3 = 1; } else {3 I9 i+ i2 Y! L0 n GPIOE_BSRL_Shadow.bit.GPIO3 = 1;4 L0 `; f) `$ m0 n' V } if(Q1.bit.b4 == 0){ GPIOE_BSRH_Shadow.bit.GPIO4 = 1;5 Y7 P3 I/ i: t3 G } else { GPIOE_BSRL_Shadow.bit.GPIO4 = 1; }- X# T2 D- l b! w" [" a if(Q1.bit.b5 == 0){! f- Z$ j9 J& A8 r GPIOE_BSRH_Shadow.bit.GPIO5 = 1;4 y9 ?/ x7 U, D( p } else {& ^0 b$ g" |' O GPIOE_BSRL_Shadow.bit.GPIO5 = 1;+ \0 Y6 Z1 R A2 x } if(Q1.bit.b6 == 0){$ M- n4 ^! n! n8 _& \+ l GPIOE_BSRH_Shadow.bit.GPIO6 = 1;; v* o! P3 ]+ X0 ]- v } else {7 H, k% |: Y/ u: B5 z) X, I# e1 D GPIOE_BSRL_Shadow.bit.GPIO6 = 1; }7 ?* q7 U! Z# z2 I/ r' n! I) w: z if(Q1.bit.b7 == 0){ GPIOE_BSRH_Shadow.bit.GPIO7 = 1;9 L! g) _" h: ]: f3 c } else { GPIOE_BSRL_Shadow.bit.GPIO7 = 1; }( u* N7 X$ R" s) T5 ` GPIOE->BSRRL = GPIOE_BSRL_Shadow.all;1 i5 Y, V. w% g3 b5 Q* D; y GPIOE->BSRRH = GPIOE_BSRH_Shadow.all; } 2 b5 P$ X1 s% T* X L |
《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设备(虚拟串口)自动切换
! |. s3 x; `$ t1 E2 D0 D
注意事项:
1. 可以在主程序或定时程序中调用StdPeriph_GPIO_Driver函数,刷新GPIOE.0~GPIOE.7的状态。, V8 P5 v0 @- U
2. 在应用程序中,只需访问Q1的位即可。例如下一句; G- I& i% ~' t
"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是访问最高位。; p9 I' S+ ?+ y/ R: J h
. p( M: S5 J/ i& u
补充说明:4 C3 k; {2 f7 {4 ^
1. 驱动编程的目的和出发点在于,仅在一个地方调用StdPeriph_GPIO_Driver函数,% n& p& |% T: k c% p/ q7 e
用户层只操作Q1输出端口的8个位,8位变量Q1是函数对应用层提供的接口。- a# A0 }2 w# _1 x A2 R. j `
" p" o6 c W4 A
2.宏定义的作用2 M C% y: H! x4 y
宏定义直接操作GPIO,可以立即刷新GPIO的输出状态。7 w: r3 b& k) k$ V
例如在SPI通信中函数中,代码开头使CS片选脚变低,代码结尾使CS片选变高。
但宏定义不能给用户提供一个统一的中间变量。# |5 ^# k# N8 e# u6 c
假设有二个输出端口Q1、Q2,每个端口均是8路输出,分别安排在任意的GPIOA-GPIOE,
可以设置16个宏定义,将这16路输出端口设置为高,另外再设置16个宏定义,
分别将这16个输出端口设置为低。显然,这种写法将对GPIO的操作复杂化了。
宏定义保证了效率,但对于应用层而言,不利于用户的使用和记忆。4 c: t- P; m4 V
$ w) _ M- p+ q
6 P3 D- B2 z+ }2 F2 W