理论学习; E% M+ m& O) p* ]3 |! o5 ~) I
GPIO配置相关的IO口寄存器: $ [. H( H6 ^! k. e
1 R+ }) {2 Z4 w1 \ q
! j4 c9 h6 L) i' o, m2 f
; |9 _' _% ^9 G# c实践学习. L% c. k. T8 R, r9 G( B, S
一、设计规划+ h- Z( e1 D+ x9 y* |1 s
1.1 实验目标
8 E1 I6 {# N) Y6 ?开发板上两个LED:DS0和DS1交替闪烁,实现跑马灯的效果。
9 w; \3 c% b0 |, s8 c
; G. H G, |; l6 l% T0 D# Q1.2 硬件资源5 ~0 G* X# |3 G, q" y- h6 g
0 k; c' [1 q- A* g2 p
/ V. g( {0 M4 A j
2 n9 h9 P# F6 g5 f$ s4 N ~二、程序设计
! {/ }7 N. C5 w" F3 U" z$ f) S! _2.1 工程文件! v; ~, J5 D6 m% F$ v, k
- g. g$ J7 {( F! ~" a) t, [) W5 H
5 B P: ?- ~; q+ S7 V( k* l4 W2 P m ]- g
添加工程目录(.c和.h)' z' `- I! _: N$ _3 |' a. {
4 U& T0 \9 p, ^/ K1 _. V! A2 J
/ I% r; f2 ^' h( w
2 e$ ~, h, j) t; {0 [
2.2 led.h文件- #ifndef _LED_H( b6 S1 S" c+ U* {0 r1 i% u+ c9 {' E0 x
- #define _LED_H
. O1 T% q1 ~) b* b3 ~1 o b# I - #include "sys.h" + z; C* w- s5 s7 a, ]
- ' Q" {5 L1 Q% g4 E& Y0 D
- //LED端口定义
( {& i: Q$ R* T - #define LED0 PFout(9) //DS0,基于sys文件的位带操作
' ?9 ^# L/ k' k3 D - #define LED1 PFout(10) //DS1# Z0 l/ d( j) Q1 M- b" t! w
- void LED_Init(void); //初始化函数声明
0 R" t% v- c0 L5 \ -
* x, ~, k( {+ e* P6 Z. g; Y; L- Z - #endif
复制代码 . k( {6 T) F" O% k: m+ y! N
2.3 led.c文件: ~- a; F& _5 _3 p
使用sys.c文件中的GPIO_Set函数对IO口进行初始化! J" Z( i/ G: ]' }
0 q1 S' ~) w9 Z& _' L, y
) w. O5 r* v8 K6 ?1 v/ {
( A- s3 ]" w% l$ a& a+ D' [: K) I RCC AHB1外设时钟使能寄存器(RCC_AHB1ENR)' }& R& K) P" y7 V' k
) K' ~0 _$ O/ D1 V9 s; E
% H: z) x" p" o! }0 J+ |# k
' P0 l6 f! B- r7 ~4 @5 t7 I位 5 GPIOFEN : IO 端口 F 时钟使能 (IO port F clock enable)9 M9 Z7 E; j+ d0 a/ R9 o* o
由软件置 1 和清零。
9 q! ]0 G4 H1 \; p$ p; W0 :禁止 IO 端口 F 时钟
5 _4 T1 r& B9 p1 :使能 IO 端口 F 时钟
' z1 I% o, a% Y3 v5 f0 ~- #include "led.h" x+ W. `( f6 i; R( C
- //初始化PF9和PF10为推挽输出0 L5 ^) Q* v% q6 f
- //LED IO初始化! x9 R; H0 ?4 J& H
- void LED_Init(void)7 K9 f; Z! }6 o4 x! v( n
- {
& \, S! i" q9 G6 Q - RCC->AHB1ENR |= 1<<5; //使能相关位的时钟
2 S% O9 s$ w- M( M: B - GPIO_Set(GPIOF,PIN9|PIN10, //设置相应的IO口
7 T" l+ K+ @1 A - GPIO_MODE_OUT,GPIO_OTYPE_PP, //MODE_OUT:输出 OTYPE_PP:推挽
0 k, h0 J( L. B2 t6 Q* o - GPIO_SPEED_100M,GPIO_PUPD_PU); //SPEED_100M PUPD_PU:上拉
6 P& ~ E3 L; I: |- \& s - LED0 = 1;& j8 M$ p9 M G
- LED1 = 1;5 i1 _" O( ]* Q/ P; B3 r
- }
复制代码 ! R) }& t5 p; V" f; n5 k
4 L5 D: R9 T, s: Y. { ^ 1<<5 = 0x0000 0010 $ @, p) P3 }5 c& K& {
1 K+ j7 } M8 x% N% dRCC->AHB1ENR = RCC->AHB1ENR | 0x0000 0010 //将寄存器与左移表达式按位或,即将第5位置为1,即GPIOF的时钟进行时钟使能。
4 r3 M; {5 M9 J) U* f. Z8 P
' n! P) H& ~" D' J然后通过sys.c程序中的GPIO_Set函数对IO口进行配置与使能。# a- i" }% R4 n
" ]% E7 X2 i" J$ g2.3 text.c文件: o+ J: N; p2 B4 z" @/ L6 v
Stm32_Clock_Init(336,8,2,7);
& Y( G+ r6 Y4 |) ~. nplln:主频系数 = 8*366 = 2688MHz
& y: H0 l: [" {* z/ [' Mpllm:主PLL = 2688 MHz / 8 = 366MHz; L* A7 p0 P3 Y' [' q5 }
pllp:系统时钟 = 366 / 2 = 168MHz
# I4 f& c% T7 zpllq:USB/SDIO/随机数产生器时钟 = 168MHz / 7% T a- a. I" k5 Q: K5 [# g
% T+ c! z/ T' `' a$ L; _; a: b0 G
. @4 [/ P$ r. r4 q
# n4 X, f6 a4 D9 @) ~
- #include "sys.h"
. d& F# p2 P" y ~! k8 @5 m* | - #include "delay.h" o* e4 K2 v1 o; J/ f
- #include "led.h"$ D9 u8 g8 l" ?) `
- 4 w z v. I, m1 z. g* o) W
- int main(void)
& \- h2 C" }4 f* K2 J0 h. s$ [ - {7 d. j5 Y6 }* d' W
- Stm32_Clock_Init(336,8,2,7); //时钟频率168M
2 v1 ^, f$ R' E- Y - delay_init(168); * P. @7 |1 |1 v, |
- LED_Init();
5 ^0 J2 [' n# n6 @* [ - while(1)
|4 r' `2 n1 v( h6 K2 `+ v) F! T - {5 a1 L" n9 I* v9 E1 a
- LED0 = 0;. p# [, |* n7 ~" [( H1 y
- LED1 = 1;( p( x! S' H( r, d2 m
- delay_ms(500);
' I( Z) ^# \2 l1 `! w3 E1 o - LED0 = 1;3 U! O" F+ q8 n E' j% `- p
- LED1 = 0;
& @: D4 n5 V$ w+ \ - delay_ms(500);- r+ D |8 n5 T. K8 o( A Y
- }0 i$ B- J% J3 P8 g( b% R
- }
复制代码
* r( y3 }' N0 ~) P* \+ { }三、在线调试
7 J" P1 z! ^' P" N
6 D$ r6 {- f' r7 s2 P' F, d4 C
2 U2 f. V/ N" a- Z- I# g
" C6 n3 X2 ?- K8 J# Z8 ~7 d 将代码下载到32开发板上,然后点击1进行代码在线调试。. q' H& Q* f+ q9 z! A, Q
点击2打开观察窗口,添加PF9和PF10两个GPIO的值,同时打开GPIOF的寄存器(最右面所示)
( a$ i1 z0 C' {6 [ h5 R如下图在线调试后代码运行到启动文件的_main程序,下一步将进入main中执行C程序。
! K7 Z' _" S" n7 g. Y- q* M
( \' v3 K( q# U# S/ U; h
9 \/ U# U- \1 m1 ]
7 b1 o' T4 F) G: q在LED_Init(void)中的GPIO_set后设置一个断点,来观察GPIO相关寄存器配置变化
5 \- W3 s- q5 x! S9 i, c$ r可以通过寄存器相关的位看出其GPIO模式的配置:MODER将GPIO9/10配置为01(通用输出模式)、OTYPER复位状态(输出推挽)、OSPEEDR将GPIO9/10配置为11(100MHz高速)、ODR将GPIO9/10两个位配置为1(初始化点亮LED灯)
9 l/ K9 i1 q% }( Q; N3 s L/ H5 \, @
" q X+ B2 [4 k! u( `3 W
$ d9 t; o9 T! I5 t0 U
整体运行代码,可以发现输出寄存器PF9/10在0、1两者进行转换。( w8 ?0 M8 M8 n) M# L# `
' [- a) M- z+ Q6 \/ E; j4 v
LED寄存器变化& r0 }8 d0 v& A
4 p+ N, P5 L+ Z' j1 k
) U1 z: j3 {8 w! W/ y5 q
四、上板验证( \ o# Y, ^: ?% o* t
代码编译后无错误,点击下载按钮: z$ R! `. n* N0 s; e
* |2 P x* V& `/ l" ~, ?: q
' r7 @) { a6 l# l# Q! z- p2 W. p* H% {( k5 G
, [* Z e m3 {# T2 P9 h( I; {& H0 Y
————————————————
5 Q0 U0 O/ S- x9 P' N; M版权声明:追逐者-桥 y$ z4 _3 [/ Z; q9 }) ^% t$ a
+ Q0 E* f2 O- Q9 g
, A* m, |, K/ Z. B: D; @ |