|
ARM CMSIS Driver 学习 之 SPI; t: E6 I N, h4 a: F* v% V: m8 x
( u D: m) S7 w; K0 n! s% K) D& L CMSIS Driver 都有着相似的 API 函数和相似的调用方法,它是在 ST HAL 库的基础上又进一步的封装,使用和配置起来都要比 ST HAL 库要方便和简单许多,并且还是跨平台的,非常有学习和使用的价值。今天学习 SPI API 的使用,详细介绍见 CMSIS Driver SPI API
# {( G3 D& z, w- L: ^7 D6 b& J0 Z N
SPI 发送与接收% P o+ _4 y1 O% K
- /**; H- r1 I5 j4 }1 p
- ******************************************************************************- k3 ^2 t) Y; {
- * @file main.c
# Q5 J" }4 H x, [7 u( ^% G8 A - * @author XinLi
$ Z0 E* ]5 p) s0 n! o1 [ - * @version v1.0
" H' K" M1 A% X% n: r - * @date 20-March-2018& J2 `& z$ W1 {) ?
- * @brief Main program body.
* U1 P) q2 |/ ]: H* B - ******************************************************************************. z% ]4 D1 v a* d7 d9 @" ?$ ^
- * @attention& l3 T2 D& I, t% i
- *
. d; v0 J4 x3 r9 T( v - * <h2><center>Copyright © 2018 XinLi</center></h2>
$ X" }) c0 y d5 M7 e( _' ^ - *: ~! Y' M$ b' ` W' m
- * This program is free software: you can redistribute it and/or modify6 o) b" U4 g1 f2 Y( k( t
- * it under the terms of the GNU General Public License as published by
( A) L& A3 f2 |& ^$ [; e0 N - * the Free Software Foundation, either version 3 of the License, or- V& M3 L3 M1 H) Q2 I" }9 k) ~5 n) \, m
- * (at your option) any later version.
+ W" n$ J! l1 A$ S - *: C) K- g4 r# B L
- * This program is distributed in the hope that it will be useful,+ U7 {+ K# \6 Z% U
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1 @" |, y; r- ] - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
, v6 K F8 h: o! w - * GNU General Public License for more details.
x- v* ]- N8 W% |! X1 [0 s% H8 \ - *& c& |8 w8 f/ d: \- B! `
- * You should have received a copy of the GNU General Public License, I9 [9 V$ E }) R
- * along with this program. If not, see <http://www.gnu.org/licenses/>.( C, K N- R ~# h+ x' W! U* Y- H
- *
8 I9 b# _: ~7 Z/ R w3 I - ******************************************************************************/ \: D- z8 U, i/ _' f1 S
- */
; [9 Q: N9 I0 q" W- \0 g" f" U
6 `" {- X' R# ]# x2 O7 S' @" p* O- /* Header includes -----------------------------------------------------------*/
# W2 E- L6 U. V7 t/ v - #include "stm32f4xx.h"
5 s( `# V9 T5 R1 Q- t/ p8 B* b - #include "Driver_SPI.h"; u/ n& [! w2 F* L' x: w" I
- #include <string.h>( N2 J/ K1 w, J' S S6 C+ z
% U2 _, L- l# ]: }5 s! m. N, b- /* Macro definitions ---------------------------------------------------------*/
5 X. w3 t0 P' O8 _% t8 J5 M - /* Type definitions ----------------------------------------------------------*/3 _2 Q" c5 o0 p# f! [. d' e
- /* Variable declarations -----------------------------------------------------*/
3 H' u- O" `7 g9 v$ } - extern ARM_DRIVER_SPI Driver_SPI1;
$ j9 K+ w; d% j; r$ ~
2 N* ~" j: M7 K) Q- /* Variable definitions ------------------------------------------------------*/% |4 p* X' t9 O' ]& t) I H. k3 X
- static uint8_t txBuffer[5] = {0xAB};
, z ~' j$ e& m9 g# Z2 }9 g% I - static uint8_t rxBuffer[5] = {0};
" p, b# Y5 o2 M# Z% g+ Q - static uint8_t dataBuffer[5] = {0};8 u. x7 N- l6 B- b( h+ y
9 U* l) k" ~6 G. k' f5 p [- /* Function declarations -----------------------------------------------------*/
* e3 }& z: H3 T( B1 h - static void SPI1_Callback(uint32_t event);
# O5 e1 W* t7 f% F - static void SPI1_CS_Init(void);9 |9 {; [! P9 `7 t7 ?7 R
- static void SPI1_CS_Low(void);
) S3 \; ~" V, S: f - static void SPI1_CS_High(void);
9 G; V3 D: b Z ^$ M- Z3 K - static void SystemClock_Config(void);
' Z; V; M' E# k
! w+ s. J9 l4 Y8 ?4 T- /* Function definitions ------------------------------------------------------*/
6 ~# J! O# [! d7 |
' T* i9 Y3 W! [1 ^$ c- /**& [- W4 @+ [8 d9 c
- * @brief Main program.
* u% a7 E$ Z6 l3 u; m, r - * @param None.4 Y K p8 e8 c9 D; i9 i
- * @return None.
- |* k8 A) `- Q/ E: q. t - */
; Q5 \" {- U: W) A8 ?& ?' o$ `# K - int main(void)
6 R; E. U& p# B& h, s8 y5 M - {
" t# Z$ L+ v1 \0 d' ` - /* STM32F4xx HAL library initialization:" V# r$ y: T; n9 [/ p5 D
- - Configure the Flash prefetch, instruction and Data caches
1 A5 S# Y( [. g8 N1 O" D) a - - Configure the Systick to generate an interrupt each 1 msec
. W( b2 z- {. Y4 D/ x+ G - - Set NVIC Group Priority to 42 b& } X$ j$ y n2 l
- - Global MSP (MCU Support Package) initialization
% j1 ~- Y: e* G+ e4 j9 F4 g6 O( ` - */
/ m- I$ S' p% P7 f$ s# d - HAL_Init();
' {' t5 `& o, f8 P1 e. M# b - 3 j$ s$ m3 u& P- d+ C/ h
- /* Configure the system clock to 168 MHz */
. R/ e. v& U- @( U/ P4 H5 B' J - SystemClock_Config();
9 M* ? I( j; L6 ~2 [9 v( C -
/ `: ?0 n2 f; o$ f- P; z$ \& R - SPI1_CS_Init();
( _ t! w/ [! v" \ - 2 C7 O, S3 k+ F6 H: f" B7 c
- Driver_SPI1.Initialize(SPI1_Callback);
9 e5 J6 o8 N b! o - Driver_SPI1.PowerControl(ARM_POWER_FULL);
0 I" j2 u7 H" z% w3 W6 U - Driver_SPI1.Control(ARM_SPI_MODE_MASTER |
# m! q; u) E! @' u - ARM_SPI_CPOL0_CPHA0 |
6 d/ Q4 r5 @% v w! d7 K! A( L3 ` - ARM_SPI_MSB_LSB |6 ^# Z" p) m! I4 X
- ARM_SPI_SS_MASTER_UNUSED |
' Z; |8 I% L2 D. @: R f) C - ARM_SPI_DATA_BITS(8), 10000000);
! T- u9 ^ z$ Y+ i: I( | - 5 W2 b- H0 l' [% {: z6 e& c) M
- SPI1_CS_Low();$ J5 D7 e! N, X
- Driver_SPI1.Transfer(txBuffer, rxBuffer, sizeof(txBuffer));0 ~" t1 t2 d. y. _! [
- . N+ z; L5 v" [$ e6 q
- for(;;)
. R9 g- j2 M0 ^2 f0 I - { p; c/ `9 C8 f+ P5 `4 A* \+ v, u
- 0 [2 R7 {6 i5 _0 }+ s; q
- }
) u! e, d$ d( W: ^ - }
7 V* d% i3 H# p
5 p1 d! [9 A3 u; ^5 l- /**3 H, }5 X+ k# G" v& }6 Y. d6 H
- * @brief SPI1 callback function.; y$ {) J! g6 ]- M/ g
- * @param event: SPI events notification mask.2 s V" U& Z5 Y) a0 w+ ?/ i
- * @return None.
5 D6 \' U9 B8 N9 D5 [ - */
0 o0 t# [, M7 ^+ Y - static void SPI1_Callback(uint32_t event)
& b' G. T$ e3 J4 U6 M* ?6 t, @ - {6 i% ^+ N# t; p$ \
- if(event & ARM_SPI_EVENT_TRANSFER_COMPLETE)
' T0 f8 c0 F3 a$ j - {
' p: C: L+ |7 W. b* I6 M7 D - SPI1_CS_High();
/ z ?8 F/ Y- a! K) B+ D: y - memcpy(dataBuffer, rxBuffer, sizeof(rxBuffer));$ W6 [* e6 c* [6 }
- }% ~. h4 |# D7 i
- }% s6 M; H9 A, G: s) ^% r8 M' A/ m
# }$ r0 n2 I7 q( g- /**# m; p9 H& A* l3 j
- * @brief SPI1 CS pin initialize.
/ z2 \5 Y3 R7 x2 d$ t - * @param None./ _, Z, b5 K( o5 H% G5 Y0 _8 i) M
- * @return None.0 o$ w, S& q' m0 M7 |% D
- */! ^" h) [" q& O
- static void SPI1_CS_Init(void)* u; T: y$ `( A4 \, z* E- }3 |
- {) J5 r+ a# @& F1 |1 \
- GPIO_InitTypeDef GPIO_InitStruct = {0};
2 S% k t# j8 A5 ] p5 O - 6 B- C' [1 Y5 d0 E' `' d2 p
- /* GPIO Ports Clock Enable */' t& b) p- S; W4 E5 H/ b6 o2 B
- __HAL_RCC_GPIOB_CLK_ENABLE();
& G5 X2 u* U# ^7 O+ O% ^ - 2 F' x2 i4 a ] j. `) B2 P
- /* Configure GPIO pin : PtPin */
* F. I" F0 M/ L, T9 C - GPIO_InitStruct.Pin = GPIO_PIN_14;
2 W( n" i: G7 }) Y6 Y/ m3 W - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
9 Q6 I( Q: V& r$ D1 x2 M - GPIO_InitStruct.Pull = GPIO_PULLUP;
2 L% @5 D1 U; h. ]4 I+ z - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; ^: H# c$ V) b1 e) r" s
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);" D1 Y2 X2 @) G' b: h
-
0 ? n( X+ c m* k7 D9 H - /* Configure GPIO pin Output Level */
1 _$ u8 \. Z+ W - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
3 [4 e [% _# `# n& U3 y8 L& s" r - }$ s4 `( t8 t7 s& k5 v2 l& J L( y
- 0 ~( v9 @) y$ ^
- /**
( x. A" ^, \- x$ V: X - * @brief SPI1 CS pin level pull low.
0 ~7 N$ l X1 R - * @param None.$ w+ k- W) X" o# T; Z
- * @return None.
& L) u2 m8 H) z; ~" S - */" ?, i% b9 a& j: S; n+ U) D* s
- static void SPI1_CS_Low(void)
: s0 w% C8 |+ K: S - {
( `' t* p% p& k& E - /* Configure GPIO pin Output Level */
# C0 C/ E9 C0 R: {; u8 _0 E - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
6 Q. z1 C) ]. t% k: Y - }
+ d5 f% e* y: t1 T6 m - - Q8 U+ n/ |. O
- /**
2 X8 C& V# {4 L% v8 y$ _ - * @brief SPI1 CS pin level pull high.
' X; k5 Z" I" Q$ S8 h3 Y. ] - * @param None.
7 ^4 D+ u& Y0 ?! X" E% N - * @return None.
9 o3 m4 T! ~7 r0 J: r - */
3 Q j6 k5 g( K - static void SPI1_CS_High(void)
. f# ]' y& ~2 n) s# D$ u# e$ \2 w. H - {6 T+ b0 f) p, S6 J( n! j! H0 s. M U
- /* Configure GPIO pin Output Level */
3 A, X$ }1 T. t. S: B" A# n5 [ \$ k - HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
9 I/ u( G6 v1 x3 I8 w6 z. H - }
5 N+ J% |% V* T% K4 }& d5 S- } - 6 W) Z: L/ y7 }" \( M' k
- /**
/ T! J5 A, j6 O - * @brief System Clock Configuration
( i5 @0 r8 G3 J# Y1 U& i# R9 ~ - * The system Clock is configured as follow :
& Z$ N" ^! Q5 `; r7 \% v - * System Clock source = PLL (HSE)3 N# h8 k- \( _, ?" I/ Q* u
- * SYSCLK(Hz) = 168000000
9 X' _. ~9 @1 U - * HCLK(Hz) = 168000000
8 G" G* X f; M: { - * AHB Prescaler = 1
+ `7 X @+ o% k1 ^) v% [' G - * APB1 Prescaler = 4
' j$ w0 k9 }& U* p- f. @0 Z - * APB2 Prescaler = 2# d( }) t" G* D* h5 k( w" [' z4 ?
- * HSE Frequency(Hz) = 8000000( m/ G2 J* C$ T; ~& y0 f
- * PLL_M = 8
' E7 t' B) U3 V5 {3 ] - * PLL_N = 336
# o8 s' n8 O- _# G/ `# v - * PLL_P = 2 D" T$ [ t$ j9 k( t% ]
- * PLL_Q = 7
* e4 m* a7 J; u6 R. L: a; K, V - * VDD(V) = 3.3+ w9 m( a/ V: m. ]7 z4 j
- * Main regulator output voltage = Scale1 mode
2 O5 V& Q0 n. @ - * Flash Latency(WS) = 5
* z/ j8 U3 S- O - * @param None
; b, E4 E, J# C! t' w3 n - * @retval None4 G5 Z' j, G& R5 C) ~- u ^" _( b
- */9 P" `9 g/ P2 K( T1 _4 d
- static void SystemClock_Config(void)
/ t! i0 _( o) k2 c7 R - {
. q# Y% Y. s% } - RCC_ClkInitTypeDef RCC_ClkInitStruct;
; @# r- E3 y; Y( e2 Z; k - RCC_OscInitTypeDef RCC_OscInitStruct;4 B, O$ P9 O2 R+ J& O4 H/ r
' n6 L" i: {8 l' }9 X$ T6 e* ?+ \5 r. A- /* Enable Power Control clock */
5 o% c( I4 G! _) H7 i6 {5 C) u - __HAL_RCC_PWR_CLK_ENABLE();! ~; r- I: n" s7 r
% i+ P9 w2 V3 {! M2 E7 n- /* The voltage scaling allows optimizing the power consumption when the device is
) G: \% p/ z' q! ?2 q# @" w' [' E7 n( ]# k - clocked below the maximum system frequency, to update the voltage scaling value * c1 R- u! m. ?4 o. [
- regarding system frequency refer to product datasheet. */
- H) k/ ~5 O) S# ?6 _9 T - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
4 N6 p' n) d& e' }- o - ) |1 s% a2 K% j8 e
- /* Enable HSE Oscillator and activate PLL with HSE as source */
$ E1 G" w% \9 ?; E R - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- ^; v4 N7 S% c# u9 q - RCC_OscInitStruct.HSEState = RCC_HSE_ON;7 v" c* Q# y% B) H# F: D
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
8 H' S3 A. b9 E' w3 j5 r5 V - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
3 J( f( ]: z" F0 q* B - RCC_OscInitStruct.PLL.PLLM = 8;
" K$ n+ a( `, |+ y. t - RCC_OscInitStruct.PLL.PLLN = 336;
& C/ ~- e1 ]/ @5 U - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
* L1 Z: n! \5 ?9 B" b9 W) h4 v - RCC_OscInitStruct.PLL.PLLQ = 7;
9 t* _/ v! o6 c, F/ @: \- t - HAL_RCC_OscConfig(&RCC_OscInitStruct);! w) c4 {2 k/ R; m5 X7 H
-
8 t* L5 U% a; m - /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
+ ?" K, f" o1 G6 Q. X, b& M$ G, y - clocks dividers */
- N8 F, ?2 G& a( G - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
0 b* b, S0 V/ H2 Y% m" ]) U2 V - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
8 e, p3 o% s- ] - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;. r9 k# L) o0 r Y; V! r' L; `
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
) M6 o' z2 D/ e1 O - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; , ]+ I" M# z( q' y4 b
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);$ \2 l5 E) |' g0 P' J
/ Z8 A( o3 E& ^- /* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
+ h. W) E0 B, l7 N - if (HAL_GetREVID() == 0x1001)4 L w2 ^' q* h5 ` R6 d+ Z
- {
0 S1 \2 z* O$ W9 I \0 E& Z. d4 o - /* Enable the Flash prefetch */) i0 o) L/ k$ w- p; i: A1 {
- __HAL_FLASH_PREFETCH_BUFFER_ENABLE();& n. f, G; O( @& e
- }
4 x; j" Y) ~! {; _6 q+ _ - }# f# o" H" J; i
复制代码 9 n5 q: d) h H) @
归档链接 ]4 {7 M* L6 A
ARM CMSIS Driver 学习 之 USART
2 a6 M8 u0 g. y% X$ k |