ARM CMSIS Driver 学习 之 SPI' _# d3 x, t% v. j3 O0 p. r& I
. ]# ?- k. ]2 w6 {) g8 [' y3 [ CMSIS Driver 都有着相似的 API 函数和相似的调用方法,它是在 ST HAL 库的基础上又进一步的封装,使用和配置起来都要比 ST HAL 库要方便和简单许多,并且还是跨平台的,非常有学习和使用的价值。今天学习 SPI API 的使用,详细介绍见 CMSIS Driver SPI API
1 V+ z9 K) U4 @. v$ S+ u
9 b' J, h& O: j/ z. tSPI 发送与接收
- B6 w& U+ K/ w' s- /**
$ Y. j4 `0 X8 ?& w4 W& a+ U - ******************************************************************************
% T' c$ n% T$ p% K) d- g. j% P1 V - * @file main.c9 s9 G5 }: F: U
- * @author XinLi
3 [8 V8 k, i! N - * @version v1.0! h2 g# W) l$ ]# a# F/ i
- * @date 20-March-20180 K% K) W6 [& E# u* j( A
- * @brief Main program body.; D' f* X7 \$ M1 _: @- c0 x1 W% k: u
- ******************************************************************************
$ h2 B ~, w2 y - * @attention
! r& B* ?% J# y9 i. r$ e% Z& e: d - *
) j1 w' ~8 Q; w" f+ Q - * <h2><center>Copyright © 2018 XinLi</center></h2>
$ j" V! O/ f5 g t5 W - *7 L$ g8 A: F% n* X% |, C
- * This program is free software: you can redistribute it and/or modify
) r6 {0 L A2 M; g - * it under the terms of the GNU General Public License as published by6 W; ? l( N$ n; B. ]
- * the Free Software Foundation, either version 3 of the License, or0 O+ U! D) {% I
- * (at your option) any later version.9 h0 W9 y2 k6 r, ]5 z* b. y
- *
2 o0 ]' B* q& O; I% Q - * This program is distributed in the hope that it will be useful,
6 p2 _5 |: v/ g3 O5 E - * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ v4 P4 E% ^' g) P _; S - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the! }8 ?0 L5 y- c: |# P/ H) R: t, Y
- * GNU General Public License for more details.
$ X4 Q4 M7 j2 S. Z. W4 ~' j - */ F% Q9 B, v# }1 X
- * You should have received a copy of the GNU General Public License7 ?- ?, r) j9 w3 \
- * along with this program. If not, see <http://www.gnu.org/licenses/>. Z/ U1 {8 u0 ?" b O
- *
/ T7 u: q1 O. _ - ******************************************************************************+ F9 B. N3 U# L+ w/ d
- */8 p2 P1 S0 j; a% O, W* L, ~
+ K! s1 x3 i/ O% ~- e- /* Header includes -----------------------------------------------------------*/
! z$ H/ @8 t* L+ h - #include "stm32f4xx.h") W! j& z9 g- w& }. W
- #include "Driver_SPI.h"! [6 l2 b& ?) L$ W
- #include <string.h>
6 m; R+ U& I* e# S - 0 g' ~; Y# P2 \- R4 b2 ?
- /* Macro definitions ---------------------------------------------------------*/
# y/ x3 v9 ~$ S5 W1 p3 D! J, g - /* Type definitions ----------------------------------------------------------*/# K* Z/ b5 N, F+ w
- /* Variable declarations -----------------------------------------------------*/1 S. `% @* X4 H3 _& v; H) r
- extern ARM_DRIVER_SPI Driver_SPI1; Y% b" C' E# F2 H4 m4 s/ ^
$ _$ n# M. k1 R2 {# h* n7 w+ o- /* Variable definitions ------------------------------------------------------*/2 \) K/ F( s* z1 K+ @5 P# G
- static uint8_t txBuffer[5] = {0xAB};
& S& x8 p+ T4 m+ k' n5 J8 h/ D& ` - static uint8_t rxBuffer[5] = {0};
9 Z5 O( c* n# |- o- I: Q8 z - static uint8_t dataBuffer[5] = {0};
+ I# _7 m) w3 v; g% J
( Y7 x% m. L+ t: ^4 I/ y- /* Function declarations -----------------------------------------------------*/) K: v- [2 p% o" A5 K; {3 C
- static void SPI1_Callback(uint32_t event);/ d' B* W) u0 A4 C9 y2 y5 ~: ]
- static void SPI1_CS_Init(void);
2 X, I/ x+ _8 B8 q: E& u - static void SPI1_CS_Low(void);
5 }, }- J- H, d3 B3 s5 r - static void SPI1_CS_High(void);" m- l' Q7 _# @) P' S1 ~. [/ q. m8 W0 Z
- static void SystemClock_Config(void);" }& i, j- t% V9 s3 z' T3 J% c2 H
- 6 {, N5 Z1 T& J- w0 r
- /* Function definitions ------------------------------------------------------*/
0 E8 I, n" q9 i+ S0 x - 1 s7 |0 G2 H2 q0 P5 F8 [) i" {, v
- /**
5 y t% S, e1 j( n% d - * @brief Main program.
5 D7 X8 E+ T1 f - * @param None.
+ k6 G6 ]% @$ H% b0 e# ^8 | - * @return None.: o- C2 `, q/ s/ _
- */
& c, C! \2 M* O: G) w& M2 q v# o - int main(void)
6 G; i2 E9 l9 i" a( n" ^2 d( B - {3 p% d: ^- m- c- }3 z
- /* STM32F4xx HAL library initialization:
/ T2 i9 `! M. Z: |! y - - Configure the Flash prefetch, instruction and Data caches
( v' q2 e( @$ x2 o7 E, t H0 _ - - Configure the Systick to generate an interrupt each 1 msec- V9 _( _# ~$ G" u' z% f
- - Set NVIC Group Priority to 4 q8 n' j3 I6 U! j% b" K$ Z
- - Global MSP (MCU Support Package) initialization5 l9 v7 p% v% D$ z3 r# M
- */5 l n+ S1 s8 g/ Z, U
- HAL_Init();5 Z8 e5 F% \2 w" N9 `
- 6 a- \. O0 H2 M
- /* Configure the system clock to 168 MHz */& }) T# M5 Y+ q5 O
- SystemClock_Config();8 x3 {" k& o a0 ?
-
2 j! \ V: K2 @7 a" ~+ `1 R. r - SPI1_CS_Init();
( m% G/ h2 O- j3 B& _ P -
6 }5 X& d; {* T, j2 t9 v - Driver_SPI1.Initialize(SPI1_Callback); U9 E( X4 ]6 A. f" k
- Driver_SPI1.PowerControl(ARM_POWER_FULL);. h4 a( \# o9 ]# {% `; W
- Driver_SPI1.Control(ARM_SPI_MODE_MASTER |8 V: R _! C/ }
- ARM_SPI_CPOL0_CPHA0 |
2 n; G/ [/ r/ [+ Y9 B/ i( E, { - ARM_SPI_MSB_LSB |" u% h. _$ G0 [& t
- ARM_SPI_SS_MASTER_UNUSED |$ {% R% D! B2 l5 l) G: |
- ARM_SPI_DATA_BITS(8), 10000000);3 {7 j* Y7 m0 B$ d- M' @- A/ g
-
, Q: ] W8 d1 _ - SPI1_CS_Low();
3 p( `8 e5 l8 Y' i - Driver_SPI1.Transfer(txBuffer, rxBuffer, sizeof(txBuffer));
: Y1 q) | D9 w. }. u -
% b$ F: W8 J7 O3 T/ E7 w) P( G( ] - for(;;)/ n8 c) r; r9 J% M9 t
- {: b# ?+ S( D/ J* x
-
6 _$ N* Z; B% j; s7 F5 v - }
+ M& @0 D) S6 A T: B$ j* W - }* x9 J. _! l$ @, x3 \) i5 B
- 7 M5 m, t# D* c- {
- /**! e4 d9 K8 G- q; |1 t) o
- * @brief SPI1 callback function.
% ~/ X0 ]4 `# q; Z% ]+ i - * @param event: SPI events notification mask.$ z( w, j% d% Q# h6 s
- * @return None.
: q x E$ ?3 T; Z* Z: n: D$ l - */
7 @9 I! }) [7 t3 w1 ` - static void SPI1_Callback(uint32_t event)) G1 z3 H7 W: \" c+ @6 u m
- {7 x1 F* {1 `, K; k4 p
- if(event & ARM_SPI_EVENT_TRANSFER_COMPLETE)
% \! t; X+ [8 _4 \* A4 L* n) B1 U - {2 d) J3 a5 H/ a4 u5 V
- SPI1_CS_High();2 n- N( b4 o: |4 B4 D7 z
- memcpy(dataBuffer, rxBuffer, sizeof(rxBuffer));
* I6 C1 r0 h5 c1 d. [' B* j* | - }
) J1 S/ W/ x8 y& q" t - }
1 ^2 h+ c' C" ^) R( P1 x - ! m/ C0 t; Y0 a7 a" W" B# p
- /**7 P% B% T K; D
- * @brief SPI1 CS pin initialize.. m: R: \8 P, s6 v
- * @param None.! E" G3 O3 I5 z: l3 {" S
- * @return None.
1 @- u- N1 N% w* e$ q4 I! p - */
8 ~& l7 s+ f# }! L9 | - static void SPI1_CS_Init(void)
1 e) V* c6 l; s, b - {9 ?- l6 |9 p. n% T# R
- GPIO_InitTypeDef GPIO_InitStruct = {0};3 v7 ? W6 {+ ~* W. L1 p' R
-
* ~" C. a& Z* l4 L* f - /* GPIO Ports Clock Enable */8 E, U* Q G% Z& v: B
- __HAL_RCC_GPIOB_CLK_ENABLE();! L" n; t8 g9 I X ?* t% `
- 7 r0 z3 o1 h. ~. n }/ X
- /* Configure GPIO pin : PtPin */
% u5 ~( C! }1 K! I, P - GPIO_InitStruct.Pin = GPIO_PIN_14;
8 h$ Z. W7 p! W - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; Z! S. H$ _! V% S) Z! [9 p
- GPIO_InitStruct.Pull = GPIO_PULLUP;! z, {6 E( N* U y$ n% Z" W5 g! X
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1 `2 ^/ h8 I7 F1 n' \ - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);$ E5 n, X" \7 c1 G5 F
- 0 z' M8 s4 A, p4 o, @. G2 v
- /* Configure GPIO pin Output Level */8 F$ C5 v1 q S9 X. |+ M; r% b. d
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);& q; d% [: r5 {% Q" {4 \
- }
9 P2 I" \2 U) `5 s - 7 V' `+ S7 N$ a7 F2 Q: L2 c* K
- /**+ ^4 y" ~2 `) Z3 b* Y: y
- * @brief SPI1 CS pin level pull low.
* G& a+ B5 l2 S0 U/ I1 W H - * @param None.
6 T. ` f5 ]6 V9 \ - * @return None.
{( E: _& D E3 h( d - */
3 l0 L# s+ H3 A; ~0 f4 K, q - static void SPI1_CS_Low(void)
+ h; G& H' }7 s- U6 m - {$ i8 w, J3 }5 ^0 N. J" C
- /* Configure GPIO pin Output Level */
7 t; V6 E! H A K* N; ^$ q" J - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
3 _8 m0 p: e3 h1 [7 r, E+ Y - }0 R* X( X4 I W% w
8 I& ?5 \8 ]4 d0 {- /**9 h! B) N7 P& [- p7 Z: V- Y( f
- * @brief SPI1 CS pin level pull high.6 {$ G5 D6 g# C8 v" f2 v/ Y
- * @param None., g4 M+ D4 v, t/ E) N
- * @return None.0 k- t0 g- i S! `+ e2 f( V( q
- */
_1 \2 G) u) `/ K8 x2 g1 b- } - static void SPI1_CS_High(void)
5 G q5 E+ n* D8 ^, u& B - {
: N- @% G: q: u! X" M2 k - /* Configure GPIO pin Output Level */7 ]( W A# {& X+ h, f0 d
- HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
7 e( z5 t N6 A$ ^# G; N/ O! G! t: Y - }. k h2 @$ `4 ~% [ I
( u5 ^' h2 q ^9 Q6 R, p1 {1 E- /**
$ }- Y& [( o: N1 T9 E - * @brief System Clock Configuration( F P) ?7 D+ G% a
- * The system Clock is configured as follow :
8 d0 P# T! j" V - * System Clock source = PLL (HSE)
- G/ t$ [) O! y+ y. N/ I4 s9 C3 K2 N - * SYSCLK(Hz) = 168000000
6 f" w4 ]( _( M - * HCLK(Hz) = 168000000, o3 q# C: s3 P e* P3 |& z: M3 ?
- * AHB Prescaler = 1
8 G" d, O9 d7 n- ^7 G( i9 Z4 ?; w - * APB1 Prescaler = 4) x% A+ t! R8 c. K
- * APB2 Prescaler = 27 Q" Y) {$ S3 ~5 |' N
- * HSE Frequency(Hz) = 8000000
- l! ?+ w# ^% v) n - * PLL_M = 8
& x* u* c) c1 Y6 k p - * PLL_N = 336: B8 M* L2 N4 \9 x" ?
- * PLL_P = 2# r$ {$ c! W4 d( r6 E# b
- * PLL_Q = 7; ^2 G7 Q: _ B+ |( z( j6 [6 c
- * VDD(V) = 3.3
! w- b5 w, |4 E- M0 N" G - * Main regulator output voltage = Scale1 mode) [9 e0 ~) y" h
- * Flash Latency(WS) = 5
9 r0 O% R7 g1 J) G - * @param None, N, q! `" z3 Y% s" U: r+ H( E5 X
- * @retval None
. y7 L* Y i; Z8 b% N+ j* b) W - */. B0 b- E7 [3 p0 |) d# o" w4 S) z8 k
- static void SystemClock_Config(void)
, x6 M- _# z0 T2 |. f( i - {& ]3 l7 D0 @' v4 ^2 b- L
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
4 `: g$ O) B% Q- S z# o+ {" R# G - RCC_OscInitTypeDef RCC_OscInitStruct;
2 t5 d) I; i3 Q4 H( ^" r - ) N8 m8 J+ o/ }! A
- /* Enable Power Control clock */
1 Q( W3 r# r+ @3 ?4 B0 L - __HAL_RCC_PWR_CLK_ENABLE();( X1 o# G9 S l8 U }* E
+ G6 [1 H! O6 Z2 g+ X8 O& `: w3 F7 A- /* The voltage scaling allows optimizing the power consumption when the device is
0 ?, \5 s1 R( g( R3 |: m - clocked below the maximum system frequency, to update the voltage scaling value & f" u7 W9 {% H
- regarding system frequency refer to product datasheet. */3 Y3 G. M9 S# H
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
( j: n8 Q# Q( {/ F. { - * u% a7 H t- H9 H4 K! O
- /* Enable HSE Oscillator and activate PLL with HSE as source */! k# e7 S7 ?+ A
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
* P5 _' Z2 j7 _5 P - RCC_OscInitStruct.HSEState = RCC_HSE_ON;
0 w! w8 F: o; f8 f9 o! c2 [% } - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
! |9 Q; S: X' ^8 Q0 B6 I1 ^9 D9 B - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
$ U) f' ?- U% u# N6 {; w i0 ]& q - RCC_OscInitStruct.PLL.PLLM = 8; T( A5 B( ?. W% R! y
- RCC_OscInitStruct.PLL.PLLN = 336;. t9 y! P% K/ z" Z
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;& j: N* i9 d. {0 m0 q2 B
- RCC_OscInitStruct.PLL.PLLQ = 7;
1 u5 i) J( L9 c - HAL_RCC_OscConfig(&RCC_OscInitStruct);
9 y" p( S5 i7 h/ \ -
7 l8 }; M+ c/ G* c9 r$ {4 n2 [ - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
) h& J1 U" b0 O; p - clocks dividers */2 |, } \0 I2 f9 l: |
- RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
& \( Q% n6 t" B0 n* D8 j' n6 \ - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
4 J1 q& H3 Z8 t( S - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;& h% e) ~) C2 ~2 n
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 8 e( o) k2 n' N
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; $ ?3 D5 {0 [9 G: l* {; @: {2 I
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);8 E9 i" c4 W( `
* i( m% D, N- d- /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
' r# [: U4 @2 p1 N8 x3 j0 Y - if (HAL_GetREVID() == 0x1001)
; x+ W& W: u$ E5 l# q - {9 \" `1 b! O- V& } n# t
- /* Enable the Flash prefetch */& Z V' ^8 R: R1 V% }" S
- __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); @9 S) g" x7 W2 _, Y
- }) B8 w/ b& ^+ e: P$ T4 a: _, t1 z
- }2 M3 U# f3 l" H, o N$ n
复制代码
# o! m+ T7 U/ k$ i8 U归档链接9 H5 W" J- k4 Q
ARM CMSIS Driver 学习 之 USART
, T# T% S3 C8 M6 v4 K e |