|
使用Platformio平台的libopencm3开发框架来开发STM32G0,下面介绍SPI接口的基本使用。 ( H5 d# ^6 G, T' q" X! N/ ?' Y# u4 _
1 SPI配置以下为设置SPI1,引脚映射为PA5\6\7,使用软件控制CS-PA4; - 1/* Enable SPI1 Periph and gpio clocks */
$ \% o7 _& \/ I2 G8 M, y - 2 rcc_periph_clock_enable(RCC_SPI1);4 c7 `: e- [4 i* C
- 3 rcc_periph_clock_enable(RCC_GPIOA);
4 I/ ]5 U8 C- D - 48 y3 l6 z( n4 ^& K0 o) @" U- z, p# F
- 5/* Configure GPIOs:0 h" T8 u) |; m
- 6 * $ ^; y7 o* J# P3 X/ M
- 7 * SCK=PA5
4 D4 s4 Q2 b! a' R - 8 * MOSI=PA7
+ d& d# o6 K8 g - 9 * MISO=PA6
& t- D9 P9 u: ~4 `% j' Q) ] - 10 *
) H9 T: u9 P8 s2 r6 B# e% | - 11 * for SD card
; m( z9 @' |" U" x - 12 * SDCS PA4
2 A" Y- V* z/ p9 Y0 E - 13 */
- J9 H/ p8 A) C6 u8 g! Q - 14
% L" j G! \$ D t - 15//MOSI & SCK & MISO
+ ^7 C, U! s, P) @& I - 16gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO5|GPIO7|GPIO6);
% d# h: S; O. N2 F- } - 17gpio_set_af(GPIOA,GPIO_AF0,GPIO5|GPIO7|GPIO6);
- ]2 J; R0 Y/ v( \4 P - 18gpio_set_output_options(GPIOA, GPIO_OTYPE_PP,GPIO_OSPEED_LOW,GPIO5|GPIO7|GPIO6);/ k) m" u5 `* d$ u5 f* M+ B ]
- 19$ k# n) J% l8 D# u) m+ C
- 20//SDCS
' E) O0 |! x( J: I, z e3 n/ f5 | - 21gpio_mode_setup(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO4);
( A3 n7 T% F$ L, { - 22gpio_set(GPIOA,GPIO4);
3 z6 s) j1 @. B, ]( O( g - 23
7 K/ C8 K1 T1 ]9 n" h - 24/* Reset SPI, SPI_CR1 register cleared, SPI is disabled */& u9 }. p0 I, J
- 25spi_reset(SPI1);
+ z3 E `5 Y2 d( N% V& y - 26! c7 J6 i- k4 d; u% x
- 27/* Set up SPI in Master mode with:# p2 q2 P. ]/ y: ~8 w- b
- 28 * Clock baud rate
- g9 N$ c- ~! M/ X( Z& B$ n - 29 * Clock polarity4 K y: R; @& e/ U- m" b% F
- 30 * Clock phase
6 G$ P) C+ `' K+ t- S - 31 * Frame format MSB7 h- z! [/ H! d
- 32 */; [3 z# X6 r" d/ q+ b- `
- 33spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_128,
4 z- W' ^" f$ e' J - 34 SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE,
, s* `; x9 h) ^! |( E - 35 SPI_CR1_CPHA_CLK_TRANSITION_1,3 r$ x9 Y& q6 }- s% q Y }
- 36 SPI_CR1_MSBFIRST);
* v; E: O0 |9 ~/ [8 ~ - 37 W4 l M5 H9 {; {/ o
- 38 spi_set_data_size(SPI1,SPI_CR2_DS_8BIT);2 Y p- K8 {) Y# R
- 39 spi_set_full_duplex_mode(SPI1);# {* C+ c9 C- I, F2 y2 ?, B
- 40# g4 v/ z1 |3 {7 ?6 ?; a2 o
- 41/*
0 z7 ]3 N) }2 R4 ~$ w2 A - 42 * Set NSS management to software.$ e, M5 H& \% I' F: [; q8 C* h+ D" m/ m
- 43 *
7 u* u* `/ N [) G( a) G1 P5 [ - 44 * Note:
3 X6 I$ K. a0 g# w Q - 45 * Setting nss high is very important, even if we are controlling - a7 n0 ^8 P7 @) O! q0 s
- 46 * the GPIO
' {, A& y+ ]8 F e) N9 w - 47 * ourselves this bit needs to be at least set to 1, otherwise the spi6 {: a( q( h. K' i" ?0 q, k* d
- 48 * peripheral will not send any data out.
w' A; M8 K! _3 b( V7 q$ \5 P s - 49 */
8 c4 G, e' Z) q2 c c; _- ^8 u - 50spi_enable_software_slave_management(SPI1);" Q% d& \. c1 m1 k7 }' w+ C/ I
- 51spi_set_nss_high(SPI1);* i. X% t4 L5 C$ u, j* v1 |
- 52- |% r- r5 @. B/ z4 y1 k
- 53/* Enable SPI1 periph. */2 E* R$ Z! x, E' b* k
- 54spi_enable(SPI1);
复制代码
) W# Q" W3 L1 r+ [设置流程:打开外设时钟-> 设置SPI引脚 -> CS引脚 -> 配置SPI模式包括SPI速度、CPOL\CPHA -> SPI传输数据位数 -> NSS配置 -> SPI使能; ; c3 w5 P; s4 S, p2 ?8 ?
2 SPI读写- 1uint16_t spi_xfer(uint32_t spi, uint16_t data)
复制代码
0 Y$ s& S' l) _ W- 1void spi_send(uint32_t spi, uint16_t data); g* l/ e' y) M9 S$ r8 V
- 2
复制代码
' b0 q: j! t' b8 R- `2 @. p3 s. Q5 Z
接收
5 M0 y) ] _- a& T3 p0 C
- 1uint16_t spi_read(uint32_t spi)
复制代码
+ |" i, D, y6 O+ f
4 R* c2 D9 h- O* Q; X" B- 1spi_send8();7 q- U) l! |: A' O
- 2spi_read8();
复制代码 $ X" e. I3 k% u5 m
3 说明默认配置的SPI时钟是连续的,波形如下: 在某些时候需要在帧之间有些空隙,可以设置CR2寄存器的NSSP位或者直接在发送前进行延时: - 1SPI_CR2(SPI1) |= SPI_CR2_NSSP; //NSSP
复制代码
+ B6 D+ B0 A( `! w$ r
: B& D# ~; T, z: o波形如下: ; b% h: D' c" o* _# I
9 Z: ^ X' P7 q) P- H9 P* t5 f) k2 z- Q* R
|