|
ARM CMSIS Driver 学习 之 SPI# [9 O# s& c* z! w1 M
& Q3 h. c# J9 \* L9 `, A CMSIS Driver 都有着相似的 API 函数和相似的调用方法,它是在 ST HAL 库的基础上又进一步的封装,使用和配置起来都要比 ST HAL 库要方便和简单许多,并且还是跨平台的,非常有学习和使用的价值。今天学习 SPI API 的使用,详细介绍见 CMSIS Driver SPI API
( S" N1 B: x; u$ m4 }2 f- A
3 I5 \) A2 Y$ r7 P( W! @SPI 发送与接收4 d8 ]7 p9 R) ?# u1 |: T
- /**0 Q2 N0 C, C! M2 A4 v! G
- ******************************************************************************
& w0 M2 C8 _ R* @ - * @file main.c& s% h+ w; V/ F/ Q# n
- * @author XinLi
1 ^' O6 C1 m' [1 M1 j3 P6 J, e) J - * @version v1.08 R& o6 O/ C+ `+ }6 T* S
- * @date 20-March-2018
% ]% A: R: Y, w9 \/ o4 G+ J - * @brief Main program body.
+ n# u3 A! W. _ w2 ]' Z s. r - ******************************************************************************( V; r' ]2 G5 E% d- Q1 d
- * @attention
* U+ g9 P9 ?; Z$ x: m% B7 V - *7 S+ {/ p- L+ z+ O. x
- * <h2><center>Copyright © 2018 XinLi</center></h2>
) V0 g8 Z- s$ A - *
4 O8 A) M7 A0 p) B+ L, ] - * This program is free software: you can redistribute it and/or modify# g* j: m! p- N# @: }0 i
- * it under the terms of the GNU General Public License as published by
7 c+ `8 t2 R4 A - * the Free Software Foundation, either version 3 of the License, or* |7 Z# U) ], k+ ~
- * (at your option) any later version.
* z" m5 @" O! C$ b t# h8 h) g - *+ R- R' j. x2 h! z: }6 Y( T- `
- * This program is distributed in the hope that it will be useful,% [: p; l' q2 K5 K
- * but WITHOUT ANY WARRANTY; without even the implied warranty of# y& |: a+ N, ?: t5 Q
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the: g; F4 s- @% v d9 N5 L
- * GNU General Public License for more details.. @! ]% P% i0 K; w+ _
- *2 N0 M! G8 g% l1 Q
- * You should have received a copy of the GNU General Public License( s- l y& O1 e! d) w; n* B9 P1 w4 a
- * along with this program. If not, see <http://www.gnu.org/licenses/>.2 d( @. D! r% k; n% N
- ** b; O& U1 i: B) l1 h) |8 u
- ******************************************************************************
1 r( S+ Y% }' @+ W% d/ e: r6 M - */. K" v3 b: s2 b
- # K, J! }8 V! r& I1 ?! U. q
- /* Header includes -----------------------------------------------------------*/$ Q8 M* W! r& f; }( A
- #include "stm32f4xx.h"
. L# u: n Y/ K5 r# K - #include "Driver_SPI.h"
M; W! T0 W0 ?/ K9 S% F$ E - #include <string.h>
' P: J% d+ O6 Q3 f% e: m
# l) `# U. X# A2 Z8 Z- /* Macro definitions ---------------------------------------------------------*/; Z2 v! e: `: U: W' b8 m
- /* Type definitions ----------------------------------------------------------*/6 X" Q- w, ?8 I0 S$ X* d
- /* Variable declarations -----------------------------------------------------*/
9 t, t2 r$ G2 B5 e: P9 G0 o6 T - extern ARM_DRIVER_SPI Driver_SPI1;" W& P& z: v3 o% M% \% E8 D- P r
- ) R& a3 ^$ N% ~4 y
- /* Variable definitions ------------------------------------------------------*/
- w- s1 c+ @ F - static uint8_t txBuffer[5] = {0xAB};
2 H2 M ]4 A; Q" |' t - static uint8_t rxBuffer[5] = {0};
9 n; j& x4 f' W9 g( m0 r9 Q; b - static uint8_t dataBuffer[5] = {0};
4 u2 J6 d( h! k- f; E' ?6 B& I
/ \9 i' Q6 C/ d4 V3 A2 G6 L! B9 f6 h- /* Function declarations -----------------------------------------------------*/
; |4 h I4 V( x. Z. a - static void SPI1_Callback(uint32_t event);6 f# @: I7 s$ z" S& V, u
- static void SPI1_CS_Init(void);& L6 H, {7 V4 B2 ~7 e0 Z6 C
- static void SPI1_CS_Low(void);
j: _, t: U) ]( ^ j - static void SPI1_CS_High(void);
. P' t( v$ A* |- @0 ?, y8 m - static void SystemClock_Config(void);
3 [, I7 W& ~' G" W! S8 ?/ z ~4 E
+ S& ?0 ~1 K3 W" c% e- /* Function definitions ------------------------------------------------------*/
) U# A4 S* A5 @$ P) p, f6 R2 M
4 S; f1 }' r3 c( r" H- ?9 }- /**! z! A3 Q% h. ^6 |
- * @brief Main program.
" d8 d7 v2 ?3 ]2 g- M$ B( Q" W3 d - * @param None.
- `( I. h% z5 L, y - * @return None.
6 c" s8 P/ [, B+ o" ]% r5 S - */: Q# A# L t6 S: _+ B
- int main(void)
! C' h% V" G% b) p# T - {
. E" r( F m( o9 @5 u* e - /* STM32F4xx HAL library initialization:
/ G0 [+ S: T$ F; ]* e4 ?+ p - - Configure the Flash prefetch, instruction and Data caches8 J' ~& X6 _6 t9 d" A# T
- - Configure the Systick to generate an interrupt each 1 msec" n/ f' O( _: t u' Z9 i% H/ B
- - Set NVIC Group Priority to 43 M, K# C/ T) Q
- - Global MSP (MCU Support Package) initialization5 l! r: G# q- O3 }
- */2 g% K2 [ y+ E2 Q; K
- HAL_Init();8 `* a! j7 o8 _
- 0 N! R! |% Y! L$ p( m0 D# C. R3 \8 a
- /* Configure the system clock to 168 MHz */$ X) C% G8 F, b' G1 x4 u8 P
- SystemClock_Config();5 Q* R6 Z4 n4 {( M
- 9 J. e- D3 t0 Y8 [( i7 E
- SPI1_CS_Init();/ y$ D: h* B' k* r0 o
- 4 O$ I% T* }' E% v$ J* I5 y4 D$ P
- Driver_SPI1.Initialize(SPI1_Callback); J9 {' C+ u: l" H9 s; ^ i
- Driver_SPI1.PowerControl(ARM_POWER_FULL);" Y! F8 Z% y& s
- Driver_SPI1.Control(ARM_SPI_MODE_MASTER |
: ]5 ?/ x# _6 q - ARM_SPI_CPOL0_CPHA0 |
9 e! l/ i& b( n. x1 s - ARM_SPI_MSB_LSB |9 s9 `; y- M0 E2 B( s
- ARM_SPI_SS_MASTER_UNUSED |
2 a! m$ ^2 i3 l) X) }8 h( A - ARM_SPI_DATA_BITS(8), 10000000);' g- {0 w& l$ n3 Q t3 N
- - u7 Y1 t9 v& k5 G" H, \& u
- SPI1_CS_Low();5 H. C, I$ o% b* m s* y% b
- Driver_SPI1.Transfer(txBuffer, rxBuffer, sizeof(txBuffer));
, r9 K2 m2 F+ J0 w/ G" U -
7 c6 R' h& [; z m( T: p4 X1 J" F - for(;;)
5 ?9 {1 Z; Q C h o2 R - {3 [1 q4 f9 d! u u
- / ^: `% ]+ Q+ u2 H7 G3 X/ T
- }! V2 [) t* D4 W
- }
S7 u. T; F2 W3 C- Q
9 {; Q/ }+ z& H7 z- /**
+ @+ Y; s' y+ T2 E - * @brief SPI1 callback function.
1 p3 E h: u' m7 c8 m, O0 ]+ D: g - * @param event: SPI events notification mask.
0 ]! p! }8 m2 i6 }7 G7 T1 p - * @return None.
3 _& j$ {% Q0 `7 i4 ~ - */
6 x! z. Q7 ^4 [" M8 M* L4 j - static void SPI1_Callback(uint32_t event)- a( \, ^ H [4 d6 q/ {
- {' c0 b; ~8 Y% B; h9 B
- if(event & ARM_SPI_EVENT_TRANSFER_COMPLETE)
3 W4 h9 ?; \; @3 C - {# i9 e( d6 q8 N* ?) q& d" f
- SPI1_CS_High();
0 R* i* Z( o5 [1 g% q7 |- X2 Q - memcpy(dataBuffer, rxBuffer, sizeof(rxBuffer));
! i( @6 r/ H# h* [* ?0 ~) P, ~; q - }
. _* O. ?" s; y3 ~ - }
6 d: }- }. Y1 c! {( l- ^
' q4 S! E5 j: \+ Z; W5 h- /**. t! R* p, `! W/ Z. C' c/ V+ q
- * @brief SPI1 CS pin initialize.5 G, c" n. U( t3 X; o" `
- * @param None.9 j L" v. n: S* `+ Z" n
- * @return None.+ Y% k& D. @7 C e. C s
- */
8 Y3 {+ u$ k: k! v8 W9 d4 c B7 V - static void SPI1_CS_Init(void)
; H& |/ w" _& d4 ^9 m - {
3 b5 |: I% z9 H; Z( O9 G - GPIO_InitTypeDef GPIO_InitStruct = {0};1 X* s# p# N# p+ N7 i9 H$ Y' {2 \/ i0 q
- , M) I2 _; ]! G' W
- /* GPIO Ports Clock Enable */
x" ]6 X5 l/ F/ h7 ? - __HAL_RCC_GPIOB_CLK_ENABLE();
& D, Y( H( Z" j [# v - / F# X& F. [% Q7 Q- J [
- /* Configure GPIO pin : PtPin */
- W5 t. \; N, r5 h4 A - GPIO_InitStruct.Pin = GPIO_PIN_14;/ i- q4 P4 p V! ~
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
" @6 g J3 s9 R. W# R - GPIO_InitStruct.Pull = GPIO_PULLUP;8 q4 u& x9 {/ v$ {, \# r
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
5 |4 |: f+ b8 |9 i: J - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);, X8 m) h, F2 @8 [- [, t3 N
- 7 z0 q: w$ B. {
- /* Configure GPIO pin Output Level */3 [" B9 Y1 g+ J! O+ M- W
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
& g9 y, q1 `0 X" ` - }
6 s1 q* q6 T% ]/ P4 U/ h- W9 c
% R* o. F( Q# Z6 Y: s4 s; A# g- /**
z# G9 @# Q$ D, W, z8 H' U I - * @brief SPI1 CS pin level pull low.
& a* e E8 l E- B - * @param None.! U7 ]. `( @7 O2 p3 M" G+ x
- * @return None.
- `# ?7 P8 E% I% D4 p4 r G* q - */
# _7 V+ }, `9 [0 T* m5 i - static void SPI1_CS_Low(void)
: u! ]1 e, @4 ~) K! I - {5 ?# Z, c. x/ g
- /* Configure GPIO pin Output Level */
/ e4 ?+ z! J) j& q7 B - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);4 K4 k+ c5 P+ ~' j: B" E
- }! C6 N6 m' H$ j6 R6 ^
; O6 Q3 W: K& n# {: b- /**: L1 [8 p4 `9 p& ^1 b
- * @brief SPI1 CS pin level pull high.
; ^6 J5 v1 U. f5 K6 Z K$ j2 L - * @param None.
& @# ]1 V& R' V7 ~: o - * @return None.5 P7 L- S5 c! p; S8 Y
- */
' c% j( x$ Y* N, p - static void SPI1_CS_High(void)* W. I( P0 g9 u2 U# h8 I
- {
9 y8 q6 i3 [# a3 ] - /* Configure GPIO pin Output Level */
4 }+ n# ~7 F/ S- m - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
. U6 @: ?. M' d5 F( C! L - }
7 U# i% ~+ g1 U - 0 ^) k7 j0 b* i- v
- /**1 t" N" O8 o. X4 O
- * @brief System Clock Configuration
" y. b8 I) B9 {7 C' L1 k! C a* e G - * The system Clock is configured as follow : & A4 H$ ?! r' E/ W$ W5 v
- * System Clock source = PLL (HSE)" P: u1 X+ I( r( R5 C
- * SYSCLK(Hz) = 168000000& }' _. |$ C% Y$ {/ g
- * HCLK(Hz) = 1680000004 n8 u( z! R& @8 D3 Y( C9 n* { S4 `
- * AHB Prescaler = 1
A! r" l! m& ^6 M5 K1 L: f" U - * APB1 Prescaler = 4
5 L; P O, s, e2 @4 s& c3 f - * APB2 Prescaler = 2# z' l) y1 t8 J& Q% v. \
- * HSE Frequency(Hz) = 8000000) y, i3 ~5 a% P: s1 P
- * PLL_M = 8
* p7 u9 Q# P1 K( {7 S0 O - * PLL_N = 336/ t, V7 e6 W/ \6 b' U
- * PLL_P = 2/ X% ]4 b& t/ F" o
- * PLL_Q = 7
O9 W+ X* q) V- z) m { - * VDD(V) = 3.3+ n; n' r- g L% ~
- * Main regulator output voltage = Scale1 mode0 o3 v% O: I& p! n1 h% o: r
- * Flash Latency(WS) = 5/ J' [4 p1 u0 Y. ~0 `
- * @param None8 E/ J. H& f% X8 n7 P% t
- * @retval None
6 D n& T0 h* l! w3 @ - */
9 _: N* B0 ^1 n! C* M8 Z2 Y - static void SystemClock_Config(void)5 J+ R' l, x1 b+ E9 m7 S
- {
/ Z' G" o1 Y% a$ `: O8 R& h - RCC_ClkInitTypeDef RCC_ClkInitStruct;
/ A; p/ s2 |3 l, i! o5 f. b - RCC_OscInitTypeDef RCC_OscInitStruct;
, Y' Q6 W# c% [2 O6 M% _8 \% _- J- x
* Y6 y' r( u5 t4 D- /* Enable Power Control clock */' B' O" e8 G; N- V
- __HAL_RCC_PWR_CLK_ENABLE();- E4 C6 T5 `9 i6 T+ ]
' |! D# r1 H9 ^- p5 F- /* The voltage scaling allows optimizing the power consumption when the device is
1 G1 g9 @$ X$ ^1 [ - clocked below the maximum system frequency, to update the voltage scaling value 7 u# z6 y+ A9 q C+ W
- regarding system frequency refer to product datasheet. */
3 o/ @; W2 A" l e6 E - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);2 m% a+ ^; i. ], h/ w
- $ U, S' h4 M! O" i% Y
- /* Enable HSE Oscillator and activate PLL with HSE as source */- \7 k+ K S/ l
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;! c0 J3 f, s& G- D% n) @( ]
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
: j Z* X+ L1 p' g$ a7 S& n9 b' C - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
& n8 d" {. l, A4 h - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
$ ^% k. U8 [0 e _0 g0 V Z - RCC_OscInitStruct.PLL.PLLM = 8;$ H( _. m( D; x9 _
- RCC_OscInitStruct.PLL.PLLN = 336;
j: p% x2 x% n& }) o - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
! m% ` Y( M f3 O) H7 x - RCC_OscInitStruct.PLL.PLLQ = 7;! m2 Z8 \9 W' l9 J: s& d6 T; _5 q
- HAL_RCC_OscConfig(&RCC_OscInitStruct);
7 J/ V x* I& Z0 `2 L/ l8 G) t -
# i& a+ a5 b1 Y: g3 R2 @& P, U: V# c - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
8 R) A* Z+ f9 y$ ^ - clocks dividers */% D' y3 g1 f7 E2 ~
- RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);* C2 a9 X) j3 [7 z2 W2 g/ H4 D" B
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;$ K+ o% F2 P2 U/ J [# g( r
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
" d9 W' }2 t0 } - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
% a+ {& Q3 I' ~ - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; ( k3 _) l4 D2 Q4 f" A
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);: q! a* Y, M4 \. ~5 q2 V$ [' N
- Z& n1 D! ~+ g' {; `
- /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */7 m8 _7 U6 ^6 e" F
- if (HAL_GetREVID() == 0x1001)3 F1 F/ o. W# V0 s( s( g" P
- {
$ a( d& a4 B; B9 O- W% l - /* Enable the Flash prefetch */
, Y, g! {) e4 q. `8 v' k - __HAL_FLASH_PREFETCH_BUFFER_ENABLE();* {- J, Z% e6 U+ j' C: ~' S
- }3 [" ~! z6 l. n6 \$ p2 B# [3 @
- }
* c/ l$ l9 v( T
复制代码 " t4 h3 \$ |2 ?: d, }; h
归档链接% l2 r3 P) M, G5 E J: X
ARM CMSIS Driver 学习 之 USART5 y) b& |& y" ?" w0 Q
|