|
/* stdperiph_gpio.h */ * Q0 N4 d% C* n4 V- S l4 N3 j& U% r /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx.h" /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STDPERIPH_GPIO_H #define __STDPERIPH_GPIO_H: x" W) [) a# w8 E& N 7 q% A% z( q8 M& Q0 N extern void StdPeriph_GPIO_Config(void); extern void StdPeriph_GPIO_Driver(void); 8 h* v0 ?" W+ U$ n. F2 B union OutPort { uint8_t all;! r5 q0 s' L7 x struct { uint8_t b0:1; // 0 bit0$ `+ P( A- w8 W uint8_t b1:1; // 1 bit1 uint8_t b2:1; // 2 bit2 uint8_t b3:1; // 3 bit3& B3 \8 [, m+ w5 _+ g uint8_t b4:1; // 4 bit4 uint8_t b5:1; // 5 bit51 O% u$ d5 f4 x7 }. K& z2 | uint8_t b6:1; // 6 bit6 uint8_t b7:1; // 7 bit7 }bit; }; extern __IO union OutPort Q1;1 Z7 M" R4 B# s# y: l( n1 b! R #endif4 R% a. _# b% A$ A 7 h. r+ O( y& ^0 A2 d' r* H /* stdperiph_gpio.c */6 D3 g ?- R2 O {2 {3 A7 S( Q, s /* Includes ------------------------------------------------------------------*/0 ~. \$ H5 x/ i$ f' I. \ #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" struct BITS {( U$ e& M2 }' X, n- M' P/ m uint16_t GPIO0:1; // 0 GPIO09 D% [ I8 k* J/ z: Z uint16_t GPIO1:1; // 1 GPIO12 G1 D! |9 e ^4 \& l uint16_t GPIO2:1; // 2 GPIO2 R _% |- t- l& Z8 u) ^7 \ uint16_t GPIO3:1; // 3 GPIO3 uint16_t GPIO4:1; // 4 GPIO4 uint16_t GPIO5:1; // 5 GPIO5 uint16_t GPIO6:1; // 6 GPIO6. U; L: o7 F! q5 M/ `3 x uint16_t GPIO7:1; // 7 GPIO77 K/ d: U, i! _ uint16_t GPIO8:1; // 8 GPIO87 u: K& U C' p, X, G uint16_t GPIO9:1; // 9 GPIO94 r& s6 L6 L- ^2 T uint16_t GPIO10:1; // 10 GPIO10 uint16_t GPIO11:1; // 11 GPIO11 uint16_t GPIO12:1; // 12 GPIO122 n# S+ T" P/ M# O2 C% e; y# z' f uint16_t GPIO13:1; // 13 GPIO13 uint16_t GPIO14:1; // 14 GPIO14 uint16_t GPIO15:1; // 15 GPIO15 };% d0 V0 @, _7 ]9 C; Y: k& B union BSRL_REG { uint16_t all;4 i; W; {8 v# J2 I- ] struct BITS bit;+ @& P0 ^$ P, _6 a( H: d };' X Q S, Y p7 B union BSRH_REG {7 H9 f! y. w; S7 c( }# d uint16_t all;3 o. d. R* M- j- v struct BITS bit;. v% _' j! W% r6 s$ N5 m3 e' C }; __IO union BSRL_REG GPIOE_BSRL_Shadow; __IO union BSRH_REG GPIOE_BSRH_Shadow; $ l- y( I% T6 I union OutPort { uint8_t all; o k9 U, B% \/ C x" ]8 H5 b8 W; ` struct {( A: D# W* S3 C, e+ o7 K: F, W uint8_t b0:1; // 0 bit0 uint8_t b1:1; // 1 bit1 uint8_t b2:1; // 2 bit2+ R1 g$ A3 n8 w1 ~' S5 M uint8_t b3:1; // 3 bit3 uint8_t b4:1; // 4 bit4 uint8_t b5:1; // 5 bit5 uint8_t b6:1; // 6 bit6* o4 K+ r7 ~: _ d# ?7 v uint8_t b7:1; // 7 bit7 & |4 D$ [' q u0 q }bit;8 O) z% j0 s2 m6 v };7 W( T6 `: ~7 b, [0 w 5 l3 R# z) u M __IO union OutPort Q1; void StdPeriph_GPIO_Driver(void) { /* 1: 打开MOSFET 0: 关闭MOSFET */ GPIOE_BSRL_Shadow.all = 0;5 j4 h1 p* Q3 m: d GPIOE_BSRH_Shadow.all = 0;* f- m" D1 r* E: V) g if(Q1.bit.b0 == 0){% w; p' J C' O L/ f3 | GPIOE_BSRH_Shadow.bit.GPIO0 = 1; } else { B: ?6 a2 s9 n5 R GPIOE_BSRL_Shadow.bit.GPIO0 = 1; } if(Q1.bit.b1 == 0){ GPIOE_BSRH_Shadow.bit.GPIO1 = 1;0 [3 Z- H+ b1 \" H5 p: V } else { GPIOE_BSRL_Shadow.bit.GPIO1 = 1; } if(Q1.bit.b2 == 0){ GPIOE_BSRH_Shadow.bit.GPIO2 = 1;1 K# R. ]! N( E+ z) z( ~ } else { GPIOE_BSRL_Shadow.bit.GPIO2 = 1; } if(Q1.bit.b3 == 0){5 Q2 z' T! V2 z# {$ [7 {3 x GPIOE_BSRH_Shadow.bit.GPIO3 = 1;, j" M2 k' D1 Z0 X' k1 {0 L } else { GPIOE_BSRL_Shadow.bit.GPIO3 = 1; } if(Q1.bit.b4 == 0){ GPIOE_BSRH_Shadow.bit.GPIO4 = 1; } else {& k/ M- ~ F6 G GPIOE_BSRL_Shadow.bit.GPIO4 = 1; }; ]3 X; r* O+ x' t0 i @ if(Q1.bit.b5 == 0){; @6 u( \6 ]% D GPIOE_BSRH_Shadow.bit.GPIO5 = 1;; } j. f% l( S/ x/ |/ T, A) q } else {2 Y4 W3 Y: o: v! n GPIOE_BSRL_Shadow.bit.GPIO5 = 1; } if(Q1.bit.b6 == 0){5 P3 U; Y; N$ p" u2 ~) [' b GPIOE_BSRH_Shadow.bit.GPIO6 = 1; } else {& g5 C4 t0 H8 l/ c/ p3 ^ GPIOE_BSRL_Shadow.bit.GPIO6 = 1; } if(Q1.bit.b7 == 0){4 H# G" n& P. x* Y! p n0 M4 P9 N9 c GPIOE_BSRH_Shadow.bit.GPIO7 = 1; } else { GPIOE_BSRL_Shadow.bit.GPIO7 = 1;7 B0 o6 i6 V5 H4 U: H5 z" ~ }8 f$ w4 R( k Y( [- i y' H GPIOE->BSRRL = GPIOE_BSRL_Shadow.all; GPIOE->BSRRH = GPIOE_BSRH_Shadow.all;, q1 m# N( |0 c/ Y B, U } , [6 s+ [7 z- C# E0 U * j( T" A. T% y% {: g |
【福利三:雨露均沾·逢7狂欢】之四:用一个定时器同步另外两个定时器输出PWM
【逢7发帖赢大礼】STM32开发之WIFI实时时钟
【逢7发帖赢大礼】STM32开发之指纹识别!
【逢7发帖赢大礼】STM32开发之环境空气质量监测
【逢7发帖赢大礼】STM32开发之人体实时运动信息监测!
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
【逢7发帖赢大礼】全网最简单的Arduino_STM32开发环境搭建教程!
STM32F4中文用户手册
STM32F400、STM32F402 Cortex-M4超值单片机
SPI 高温读错最后一位?STM32F42xx 官方根治方案
微信公众号
手机版
2 O: j8 {7 k- v2 R4 r5 ?! i
注意事项:
1. 可以在主程序或定时程序中调用StdPeriph_GPIO_Driver函数,刷新GPIOE.0~GPIOE.7的状态。, Z! ~# m3 T7 V5 `! W
2. 在应用程序中,只需访问Q1的位即可。例如下一句
"Q1.bit.b0 = 1;"就可以修改GPIOE.0的状态为高电平;同样地,"Q1.bit.b0 = 0;"可以修改GPIOE.0的状态为低电平。% u6 F" A8 y+ ?' ~7 A
StdPeriph_GPIO_Driver函数调用的频率,建议在1~10ms,满足要求的即可。
在MDK-ARM V5.15开发环境,键入"Q1."则会出现自动提示,Q1.all 是访问所有的位, Q1.bit.b7是访问最高位。 i( k* [* E* f; C
[" i' C3 D2 m% m' t
补充说明:
1. 驱动编程的目的和出发点在于,仅在一个地方调用StdPeriph_GPIO_Driver函数,
用户层只操作Q1输出端口的8个位,8位变量Q1是函数对应用层提供的接口。& p6 J, d9 X" o
2.宏定义的作用! K; n0 ~' e x! Z
宏定义直接操作GPIO,可以立即刷新GPIO的输出状态。8 B+ g& L$ ]" Z1 A& r' F% v3 X6 b
例如在SPI通信中函数中,代码开头使CS片选脚变低,代码结尾使CS片选变高。
. ~& i. n3 _! E' Q' H6 J
但宏定义不能给用户提供一个统一的中间变量。5 {( [" m7 z$ {. m
假设有二个输出端口Q1、Q2,每个端口均是8路输出,分别安排在任意的GPIOA-GPIOE,
可以设置16个宏定义,将这16路输出端口设置为高,另外再设置16个宏定义,: t; f0 G& P3 J2 e3 g
分别将这16个输出端口设置为低。显然,这种写法将对GPIO的操作复杂化了。0 n$ X, a* I3 j" C3 }5 [
宏定义保证了效率,但对于应用层而言,不利于用户的使用和记忆。
# g0 t$ z8 F# V( A
0 K0 a+ F0 s3 P& d- K
) c7 E7 r# ?' ^. ?: ?0 a# @' |! y# @