你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】基于STM32使用HAL库硬件SPI驱动WK2124一拖四SPI转四路串口芯片

[复制链接]
STMCU小助手 发布时间:2022-4-9 22:59
STM32基础工程生成3 \& x  [1 z. I& T
首先使用STM32CUBEMX生成STM32的基础工程,配置时钟到72M主频:* f1 n+ J3 h; J/ F
1 e/ {0 I& Y  q6 C* T+ Y. U
20210712163230798.png
- t. ]$ S. B) `6 q, V7 b1 d. J5 Z! K9 D; H( `7 U6 w
配置SPI前,首先查看WK2124的芯片手册,手册里面说明了WK2124的SPI最高支持到10M并且使用SPI模式0,SPI的模式0就是时钟空闲电平为低电平且在第一个时钟延采样:3 }$ \' W! ]' i, I
# r! ^6 j. q% T9 E5 c. W7 Z
9W47%D}PLND[Y8HO8C05BXS.png 0 ^7 h4 h& H3 d; Z0 X. `( S' |
+ N" H. s  p$ J% b# Y9 x' r/ N
所以STM32CUBEMX需要这样配置:
; E& F4 y3 V3 C$ d, E# B( Y2 Q& o8 X% O  l  K4 o/ r
W]TW7XP@HG4%Q1V_Q{{B.png
$ ?" @/ R8 G! \9 a
; l6 \% _# K9 O' w3 ^' k. RIO配置:8 z+ `5 A  ~+ b- k5 K$ s* D$ l3 K
WK2124的硬件复位引脚,这个引脚最好接上,使用STM32的IO进行控制
1 b$ w/ _9 h  G# z/ ]WK2124的片选引脚" }' b6 i% D& s& X
如果用WK2124的中断,那么还需要配置一个IO为外部中断
: \/ n8 _, c1 [: u9 r8 KWK2124驱动代码
' [. X/ G: z  _  a
代码已经测试通过无问题,贴一下:, s5 e3 {6 g5 P/ {$ }& n& [

/ m% r) U8 Z' m, `头文件
6 a) O6 j% o  e+ v$ e. ^) [7 ]
  1. /*0 X9 V4 c% [4 _. v" B6 D0 I
  2. * wk2xxx.h
    9 t! s* Z" G  _( U% ?
  3. *
    4 F' {1 \8 F- v& J. b
  4. *  Created on: Jun 17, 2021
    1 x+ w6 r0 E3 ?
  5. *      Author: hello# p1 E. S8 }% }7 n4 }
  6. */
    - c& b: E+ @2 P

  7. 8 J  H* Y1 G+ J% Z* t* h! c7 a
  8. #ifndef SRC_WK2XXX_H_
    ( r% t% h5 K2 z+ P
  9. #define SRC_WK2XXX_H_
    4 t) R9 c3 O! s: w9 X+ J2 h. h

  10. ) E3 s* ?$ M7 z' E' ]' y
  11. #include "main.h"
    3 d/ D  c4 q. m8 Y

  12. & O+ O6 I& b6 E( L

  13. / J! j3 t" Y5 |: q
  14. #define         WK2XXX_GENA     0X00
    - j) U& t) m7 a0 g
  15. #define         WK2XXX_GRST     0X017 Q( m# X  r, U$ n% y
  16. #define                WK2XXX_GMUT     0X02
    3 D8 J3 _" W  s/ ?/ ?' F7 X9 l
  17. #define         WK2XXX_GIER     0X10; J$ v( y" ?8 ~5 W# |* }& A- c
  18. #define         WK2XXX_GIFR     0X11
    ) a/ T* b& _5 \' k3 \, B
  19. #define         WK2XXX_GPDIR    0X21' F4 p1 v# s' z) e8 r% Y; o& d
  20. #define         WK2XXX_GPDAT    0X317 v, T5 v! i$ ]4 \* o
  21. //wkxxxx  slave uarts  rigister address defines4 a8 v8 b  O: Y, V- M

  22. % i7 }" D$ O, l& J6 {
  23. #define         WK2XXX_SPAGE    0X03
    / Z; P9 I- v) J7 v6 ?+ C
  24. //PAGE02 N: e0 C+ {+ S$ q9 A
  25. #define         WK2XXX_SCR      0X04  Q2 u5 P' C" c; y5 y
  26. #define         WK2XXX_LCR      0X05# e/ D: Z5 Q2 p% K; T4 [( b
  27. #define         WK2XXX_FCR      0X06# ~# X/ a' r. S' f: y3 s
  28. #define         WK2XXX_SIER     0X07
    . _1 B# R$ X; Q* S7 T; l4 v8 ~" H+ ^
  29. #define         WK2XXX_SIFR     0X08
    ) J$ h! x  A; z8 F7 R  j! S
  30. #define         WK2XXX_TFCNT    0X09
    3 a( \  |! B2 ~, q
  31. #define         WK2XXX_RFCNT    0X0A
    / L, t" S1 {! Y! l$ u+ |
  32. #define         WK2XXX_FSR      0X0B
    & Q: t) _7 L  h+ V
  33. #define         WK2XXX_LSR      0X0C
    2 k: F" o8 x+ _1 T; B) ~1 |
  34. #define         WK2XXX_FDAT     0X0D
    / C5 z( ^5 {5 @0 z
  35. #define         WK2XXX_FWCR     0X0E# I2 N; r& t; W$ l: |/ i
  36. #define         WK2XXX_RS485    0X0F
    - }0 [! A/ M. J. L1 L* p5 @
  37. //PAGE19 N2 g/ U$ o" d) W& m7 c
  38. #define         WK2XXX_BAUD1    0X04
    & J- ~0 t4 L5 P3 x
  39. #define         WK2XXX_BAUD0    0X05, T( K; i0 R5 I( }3 c
  40. #define         WK2XXX_PRES     0X06
    4 _* z7 N$ `9 p$ N% c  B3 T+ i- P/ c  c
  41. #define         WK2XXX_RFTL     0X07
    % j- F* W1 o7 Z# K, p' l" Q) k
  42. #define         WK2XXX_TFTL     0X08* G  F# S* v  @* x# }" T
  43. #define         WK2XXX_FWTH     0X094 j" N: e9 z* t( n- W6 Y7 U5 n/ l. q9 ?5 f
  44. #define         WK2XXX_FWTL     0X0A
      j9 l5 K, }& I* {9 l& X
  45. #define         WK2XXX_XON1     0X0B
    2 x; E4 `2 ?- e  H# w4 D+ E
  46. #define         WK2XXX_XOFF1    0X0C
    & }* @, ?0 b( ^! H( E' _
  47. #define         WK2XXX_SADR     0X0D
    2 ]- u7 R& O9 P0 j  R0 q
  48. #define         WK2XXX_SAEN     0X0E
    ' {6 V8 [) |) ~6 U: W( |
  49. #define         WK2XXX_RTSDLY   0X0F5 s" W0 ~* W$ v6 R

  50. 6 f) q( M7 G. I) T
  51. //WK串口扩展芯片的寄存器的位定义$ K/ x2 O( Z$ c
  52. //wkxxx register bit defines
    * z7 x% S+ e2 j6 F9 n
  53. // GENA0 P9 b) u8 z& W0 B* Z
  54. #define         WK2XXX_UT4EN        0x08, B8 |5 L' s1 L* H  Q
  55. #define         WK2XXX_UT3EN        0x04
    ; |  d/ e! ?: o9 c# X3 `! K% E/ I
  56. #define         WK2XXX_UT2EN        0x02
    ! Z1 z/ Z' v. F
  57. #define         WK2XXX_UT1EN        0x01
    1 y  R6 {2 W; r1 Z% f
  58. //GRST+ m$ n% m+ H8 w% z# I. F, O/ b- A
  59. #define         WK2XXX_UT4SLEEP        0x80
    ' g9 _. T9 G5 z$ A+ `
  60. #define         WK2XXX_UT3SLEEP        0x40- L3 c- z5 r3 q9 T( b( _1 L
  61. #define         WK2XXX_UT2SLEEP        0x20
    * {9 k. X% g: m
  62. #define         WK2XXX_UT1SLEEP        0x10
    3 l) ?. y+ u0 n, o
  63. #define         WK2XXX_UT4RST        0x08
    7 {5 u4 O" E* j$ o; i3 ^$ Y% ~
  64. #define         WK2XXX_UT3RST        0x04
    " t' j( Y6 {% [! ]6 [( r+ b
  65. #define         WK2XXX_UT2RST        0x02) Y8 R! _9 m" N% t1 I
  66. #define         WK2XXX_UT1RST        0x012 h$ n; e; C0 \9 Y% i6 D
  67. //GIER" J8 d1 J8 e- d7 C" K& u$ u
  68. #define         WK2XXX_UT4IE        0x086 B) Z1 T& Q3 z5 G* C
  69. #define         WK2XXX_UT3IE        0x04( x. b: X6 C7 K
  70. #define         WK2XXX_UT2IE        0x02. x0 D6 H' k. m0 M- }
  71. #define         WK2XXX_UT1IE        0x01
    , F) e8 }8 W7 E! g* w8 I# Z' j
  72. //GIFR' X# L" M' |. K5 q% |
  73. #define         WK2XXX_UT4INT        0x08- z1 n& |! q' D
  74. #define         WK2XXX_UT3INT        0x04
    8 b! H: C6 I7 }/ D
  75. #define         WK2XXX_UT2INT        0x026 g1 E, Q( }7 k/ g
  76. #define         WK2XXX_UT1INT        0x01" `' S+ b  Z! T, j/ {- w1 y
  77. //SPAGE5 e( v, m  D& p
  78. #define         WK2XXX_SPAGE0          0x00
    1 |/ w6 m' |0 h% M) m( r, c
  79. #define         WK2XXX_SPAGE1   0x01. F8 a( k( P' }" y4 l
  80. //SCR
    , X. o2 ]2 I. f" {% N
  81. #define         WK2XXX_SLEEPEN        0x049 A6 f9 \" B. _$ N; `" X
  82. #define         WK2XXX_TXEN     0x02
    9 ^& x  }6 P6 X) L, h! Q; f4 U8 [
  83. #define         WK2XXX_RXEN     0x01
      H% U' B+ W) `4 j& a& E
  84. //LCR
    " B5 R6 B5 ~! @" u5 |/ }* i
  85. #define         WK2XXX_BREAK          0x20. P+ b* W% x2 S- ^$ U( E
  86. #define         WK2XXX_IREN     0x10& q7 p. y' ?2 b8 o0 Q- t; K2 K: q; J
  87. #define         WK2XXX_PAEN     0x08. ?* J" ?/ @. g: f
  88. #define         WK2XXX_PAM1     0x04
    ; i' S  @2 h9 K2 j  X5 z
  89. #define         WK2XXX_PAM0     0x027 K) K! l% _& d' D4 J
  90. #define         WK2XXX_STPL     0x01. @+ r, k! i' r; A
  91. //FCR
    2 R7 }4 S, M8 v& |2 M
  92. //SIER
    6 M& W# e3 |& q5 r6 ~6 N
  93. #define         WK2XXX_FERR_IEN      0x80+ {* M( s4 |4 p! S6 Z
  94. #define         WK2XXX_CTS_IEN       0x40' L2 {1 z$ x' I  q9 e
  95. #define         WK2XXX_RTS_IEN       0x20: y' q0 w4 [# Y
  96. #define         WK2XXX_XOFF_IEN      0x10# B7 L( @; z8 N1 ]  d; `/ P
  97. #define         WK2XXX_TFEMPTY_IEN   0x089 ^% y0 f2 @3 o7 R) g
  98. #define         WK2XXX_TFTRIG_IEN    0x04
    * G! U- a; H. r8 f5 d% r: W2 p
  99. #define         WK2XXX_RXOUT_IEN     0x02) S3 `- u; H! W" i1 \; u
  100. #define         WK2XXX_RFTRIG_IEN    0x01
    + \. A2 Q; `4 l( c/ G% B- h0 r) s9 X
  101. //SIFR0 a- E. g6 ^' W$ ~
  102. #define         WK2XXX_FERR_INT      0x80" q# P* A7 z1 |# r; h* |6 I8 W
  103. #define         WK2XXX_CTS_INT       0x40
    # M  g, @, _5 I3 T3 X+ o" ^% z" R
  104. #define         WK2XXX_RTS_INT       0x20
    - J, t4 c) a* t0 l( x1 Z
  105. #define         WK2XXX_XOFF_INT      0x10  h9 h: r& J7 G) C' v
  106. #define         WK2XXX_TFEMPTY_INT   0x08* q" u7 ~' [4 P
  107. #define         WK2XXX_TFTRIG_INT    0x04
    3 k  t. l" T& j; w
  108. #define         WK2XXX_RXOVT_INT     0x025 s4 d# Z1 I1 Q: h8 C2 h/ |- w
  109. #define         WK2XXX_RFTRIG_INT    0x01& p1 z7 B2 I' F* [8 [5 i

  110.   U5 p& t3 {/ N5 \! f5 z# Q6 q
  111. 8 Z1 |/ u% E) B' S
  112. //TFCNT0 F/ q! d; \$ {$ b; z4 d( p
  113. //RFCNT
      ^1 O7 L7 K+ ~. v
  114. //FSR* W3 D0 k+ T- e
  115. #define         WK2XXX_RFOE     0x80
    . O5 I: i* j8 _% ?% d
  116. #define         WK2XXX_RFBI     0x40
    ' S  V7 B7 L: I& R+ X
  117. #define         WK2XXX_RFFE     0x20
    + P! |' g! T" m' g1 |
  118. #define         WK2XXX_RFPE     0x10
    : B3 m- ?, f1 C  m1 c2 s- y
  119. #define         WK2XXX_RDAT     0x08
    3 h/ S0 O) L8 y: j" t, r' f
  120. #define         WK2XXX_TDAT     0x04
    4 o% q: N3 P3 W1 L6 u7 ?
  121. #define         WK2XXX_TFULL    0x02; Q) j+ b) M( E( c( U( {
  122. #define         WK2XXX_TBUSY    0x01- R, h1 R( ~' h2 e$ _
  123. //LSR
    # I/ J( a$ K+ `! U* T* S6 e: K! F
  124. #define         WK2XXX_OE       0x081 U8 f5 [3 p$ H% x
  125. #define         WK2XXX_BI       0x04+ C' Q6 M" d" x6 H. Z: h" X8 O7 O* y
  126. #define         WK2XXX_FE       0x02  E5 H. N. h  _: v4 V
  127. #define         WK2XXX_PE       0x01
    ' C! d$ A1 n- q' N$ \# ^" _
  128. //FWCR
    4 F9 q! R+ {& L4 b6 S% i
  129. ' u# G1 e3 M2 Z/ f& ^2 @( P$ v
  130. uint16_t WK_PortSendData(uint8_t port, const void* buf, uint16_t len);# a1 d$ Q, ]1 k$ p$ h
  131. uint16_t WK_PortRecvData(uint8_t port, void* buf, uint16_t len);5 @9 e* W9 [* D. ]
  132. void WK_PortInit(uint8_t port, uint32_t fosc, uint32_t baudrate);
    9 I: i( ]- D2 H& K0 f+ ]
  133. void WK_IRQHandler(void);
    # H1 r# S4 l7 n, Z; P$ X# L; G: e
  134. void WK_Rst(void);5 {2 w# {, e* B# s
  135. ; s7 F4 I9 M  ^* m& g3 Q( c6 ?
  136. #endif /* SRC_WK2XXX_H_ */
复制代码
2 O: `0 M- l* n
源文件
: f' O) r4 S9 H3 d& s
  1. /*# y. T. U: h% Z0 N- q6 j& [9 }5 F6 d
  2. * wk2xxx.c
    4 g3 a. n8 }! _% q" C
  3. *
    # y& w1 S% D; b  _+ q
  4. *  Created on: Jun 17, 20213 g- H& J% y, ?; ~
  5. *      Author: hello: b6 d* o9 F4 N  n
  6. */6 M' P/ `9 E1 c  r4 \; i; p0 c
  7. / U! l) I2 t! [, O' d" {& v
  8. #include "wk2xxx.h"
    $ E: {2 P4 j# `$ u* h
  9. #include "spi.h"' F& ]' ]- r- x8 _
  10. : W( z3 h" _1 M, D

  11. 7 j5 R4 @3 x8 z
  12. //
    6 V& H7 l3 C' I
  13. ///
    8 w. a0 d$ M1 f" p9 J: @4 c
  14. ///                            移植修改区域9 Q, c# X+ P3 F/ P% w& Z% P) Q
  15. ///5 r- U$ S6 c' {: X3 A3 `2 I% v
  16. //* K$ M0 H7 `8 ~& v  E6 S% @% `# _  {% @

  17. # n7 d! ]7 N+ I' n( S( E! ]; S
  18. /// HAL库SPI句柄7 h; C7 F& B- Y: Q
  19. #define WK_SPI_Handle (&hspi2)
    / o$ ^* y; ?. f) \  S7 [
  20. : Y( y$ i+ a# u1 h) z
  21. // 拉低RST引脚
    4 Y: w( k% Q- T% Q% \- i
  22. #define WK_GPIO_RST_L()    HAL_GPIO_WritePin(WK2124_RST1_GPIO_Port, WK2124_RST1_Pin, GPIO_PIN_RESET)9 j: C* @: A- Z- {

  23. 5 p! k1 ^. G6 F) q- c# k
  24. // 拉高RST引脚
    ) ^5 s& v! K6 f  O1 W  J
  25. #define WK_GPIO_RST_H()    HAL_GPIO_WritePin(WK2124_RST1_GPIO_Port, WK2124_RST1_Pin, GPIO_PIN_SET)3 [: Q- i2 Z6 [

  26. 1 \- L4 J7 e. B: B5 s% z
  27. // 片选引脚拉低
    ; N  Z+ N  c$ J4 t) ?  M3 u: @, R
  28. #define WK_GPIO_SEL_L()    HAL_GPIO_WritePin(WK2124_CS1_GPIO_Port, WK2124_CS1_Pin, GPIO_PIN_RESET)
    : w6 I# G* z! p5 s, N4 T  A# R
  29. 0 I' S( u7 S( g2 P
  30. // 片选引脚拉高! E! @! o2 o0 I
  31. #define WK_GPIO_SEL_H()    HAL_GPIO_WritePin(WK2124_CS1_GPIO_Port, WK2124_CS1_Pin, GPIO_PIN_SET)/ l# i1 D* V, y* J+ m: t* X7 T- I

  32. : e. ]% G) A* p. T/ ?; i

  33. ' F" b: ~0 @4 _8 j* F6 Q; S( i
  34. static void wk_delay_ms(uint32_t nms)
    . G) X& Z5 \2 M+ z7 g3 a
  35. {
    0 G0 c9 L4 W3 L1 G3 T1 d) d- d
  36.         HAL_Delay(nms);& B" y- r, P4 ?: s
  37. }2 {# h% ~! B' p/ W) T6 ^' d6 w

  38. 6 A6 v; k/ `9 \6 w
  39. static uint8_t WK_SPI_ReadWriteByte(uint8_t TxData)
    ; i9 C0 C, M  t7 x
  40. {
    * t2 Y# e5 G9 s! n4 T5 |
  41.         uint8_t RxData = 0X00;
    ' C) W( Z+ g- X
  42.         if (HAL_SPI_TransmitReceive(WK_SPI_Handle, &TxData, &RxData, 1, 10) != HAL_OK)
    2 }; R4 ?2 X: N  ^) n4 A
  43.         {% \' @0 e  w  V8 S
  44.                 RxData = 0XFF;/ F. e2 @# y0 ^8 u  n* a' F2 G
  45.         }! E$ ?" h$ w7 v8 G* O+ Q
  46.         return RxData;3 _; K. Q5 @9 L" g+ ~8 W
  47. }- r5 B! H* r6 w8 K; s8 e

  48. 2 U0 e2 |  p$ }, [* W

  49. " \6 G! N* Y0 Q2 ^/ u8 H5 c
  50. , r8 k% ~) `% T# Z! G- }) a4 B3 C
  51. ( l' M% E) l/ c
  52. //( W: {7 Y! W6 l3 f; |* i. w
  53. ///
    ' G: G3 z7 ]3 J9 ^0 D
  54. ///                            驱动程序代码# h$ K+ c3 c, W  O. I! X7 z" ?
  55. ///
    " @4 J- H) N2 L3 e' E) ]1 |7 y% j/ |! @
  56. //$ E6 t4 N) b  M) o8 t! i& }
  57. + @. ~6 F- C5 S  @
  58. 6 z9 Z5 C5 ?9 ]9 V  B- A

  59. : S0 r( h7 H9 A0 k0 E  }2 n& P
  60. /// 硬件复位(拉低复位引脚最低10毫秒进行复位)
    & L, x$ J/ O' \+ q0 H, l+ K
  61. void WK_Rst(void)3 A6 i" S) _/ Q5 C  D( n
  62. {5 G5 F: y' D7 y% n, x
  63.         WK_GPIO_RST_L();
    7 Y5 q" _5 L2 C9 f5 q  l
  64.         wk_delay_ms(50);. @/ C$ q6 q  ?- S& F$ y  |
  65.         WK_GPIO_RST_H();& q. q/ g+ q) I
  66.         wk_delay_ms(50);
    / }0 B  q; z9 V- i/ @" F, W
  67. }: J; o# z+ \6 V9 j9 |

  68.   |; J. n' a& ]9 I+ x
  69. void WK_WriteGReg(uint8_t reg, uint8_t value)8 ?/ N; X; w' R: r/ O8 ^5 o/ P
  70. {* J2 k! R( C% z
  71.         WK_GPIO_SEL_L();
    9 J5 J% K( ^( q, V
  72.         WK_SPI_ReadWriteByte(reg);, \3 b+ q, |% a. u- J; z
  73.         WK_SPI_ReadWriteByte(value);
    , H4 M) }) \( |: p2 \7 i" e* ^
  74.         WK_GPIO_SEL_H();
    3 R* M& c; ~- }- S
  75. }: `* f9 p: W- C( a

  76. * g, A0 E# C/ |2 ~! |
  77. uint8_t WK_ReadGReg(uint8_t reg)% m, K3 N, D0 `; @) f, Z, v& l# J
  78. {
    + [+ W% B# w# p/ }& T* v
  79.         uint8_t value = 0X00;
    , E. y6 M8 {# r$ O8 X& m4 Q5 f
  80.         WK_GPIO_SEL_L();
    . }9 f' T$ ]3 _% \, g& _8 r
  81.         WK_SPI_ReadWriteByte(0X40 | reg);+ a8 ^  a9 ?* {5 u3 l; u. a. n: @5 }
  82.         value = WK_SPI_ReadWriteByte(0X00);- R* w9 T! K% h( H3 s
  83.         WK_GPIO_SEL_H();
    % @- d! \4 H' E
  84.         return value;9 C! J7 l; ~) [) j" D
  85. }% z) U4 k4 M$ O6 G4 E3 f5 z

  86. - i7 F' w# N, F& F$ G& W) B: |
  87. void WK_WriteSReg(uint8_t port, uint8_t reg, uint8_t value)0 u: D  Y  q1 }7 ]
  88. {
    $ H+ j3 J4 O* U  ^+ t
  89.         WK_GPIO_SEL_L();
    7 S# ?. _# P* K
  90.         WK_SPI_ReadWriteByte(((port - 1) << 4) | reg);
    $ S- d' m$ Y9 U
  91.         WK_SPI_ReadWriteByte(value);; U( D9 c; z; Y) ^: S* \7 L3 B
  92.         WK_GPIO_SEL_H();
    $ g) o4 m, }3 N; [
  93. }1 x! D+ x$ Z& D4 |7 P  P
  94. 4 y7 x  Z) ]7 \' ~
  95. uint8_t WK_ReadSReg(uint8_t port, uint8_t reg)6 G* R! y0 U- j+ J, u3 i' k
  96. {
    4 M" w1 Y8 S8 C& ]! _- z
  97.         uint8_t value = 0X00;
    0 o2 U3 n& T% U5 g& I' p
  98.         WK_GPIO_SEL_L();1 j  q9 q* G: a$ W7 g! k/ y4 r( q
  99.         WK_SPI_ReadWriteByte(0X40 | ((port - 1) << 4) | reg);
    8 a! x2 I" z  w0 }
  100.         value = WK_SPI_ReadWriteByte(0X00);
    . H9 N" q* ]) j/ L7 u
  101.         WK_GPIO_SEL_H();/ \. r- d7 i7 _! y! i' J: v' e
  102.         return value;
    - `% p" r/ S: c1 e
  103. }5 m- @* L9 R6 N0 [+ q; m
  104. # d: K' k6 X* [' f* M
  105. void WK_WriteFIFO(uint8_t port, const void* buf, uint16_t len)5 e" X4 [7 `/ Z3 }4 {, }( J
  106. {
    ; a5 }* }3 I9 Q
  107.         const uint8_t* p = (const uint8_t *)buf;+ U! A+ w: p4 w. L, o1 N1 ?9 S. U
  108.         WK_GPIO_SEL_L();8 V  I$ c) b: ], I+ n
  109.         WK_SPI_ReadWriteByte(0X80 | ((port - 1) << 4));8 `# W. N) K1 @
  110.         while (len--). E$ ^3 ~9 s# x" }2 x
  111.         {3 N3 F! _! ]+ ]: {) e0 M' ~
  112.                 WK_SPI_ReadWriteByte(*p++);9 p, Z, d+ d( o) t
  113.         }* B7 }) d% m: m$ K2 r% |  o
  114.         WK_GPIO_SEL_H();
    ; u7 E6 E; k, N$ k
  115. }
    " ?+ L% O- f4 h  b; c/ W

  116. / x' l, J! e, G) y3 ^+ e
  117. void WK_ReadFIFO(uint8_t port, void* buf, uint16_t len)
    1 M# m( t5 L3 }9 x
  118. {
    + s, m5 K  k* s
  119.         uint8_t* p = (uint8_t *)buf;
    * l* H  k: i( _( W& l0 k
  120.         WK_GPIO_SEL_L();1 ?/ p1 C6 z0 {  ^( ~
  121.         WK_SPI_ReadWriteByte(0XC0 | ((port - 1) << 4));
    & k4 ?5 `+ r4 @  }( {- Y
  122.         while (len--)
    , a4 l# M+ C9 x6 y/ o6 h
  123.         {  F& y. n: ?5 j/ `9 f; J
  124.                 *p++ = WK_SPI_ReadWriteByte(0X00);- s* }5 `9 R1 M. b5 f4 A: M* Y
  125.         }
    ' J- [# G+ J+ u3 }2 z; \( m) K. C
  126.         WK_GPIO_SEL_H();& o( B* N$ r$ @4 Z, g
  127. }
    / G3 k+ k1 V& i3 r

  128. : V  w# q1 f# _
  129. void WK_PortCalcBaudrate(uint32_t fosc, uint32_t baudrate, uint8_t* BAUD0, uint8_t* BAUD1, uint8_t* PRES)2 l0 [! o* ?' h8 n* D2 c
  130. {) U; ]5 M6 @' A4 n% I+ p5 N: F" B
  131.         float value = (float)fosc / (float)(baudrate << 4);
    4 `/ C) G7 u1 G% O
  132.         *BAUD0 = (((uint32_t)value) - 1) & 0XFF;0 N8 n4 @$ Q7 ~$ l9 g# l. S' s
  133.         *BAUD1 = ((((uint32_t)value) - 1) >> 8) & 0XFF;  d& ]8 [2 Y" y
  134.         *PRES  = ((uint32_t)(value * 10)) % 10;
    6 P$ ~1 W" ^1 X; _5 D9 V/ U
  135. }- t, Q! w, l# ~5 t% |
  136.   q$ ?/ ?% A$ i3 f
  137. uint16_t WK_PortSendData(uint8_t port, const void* buf, uint16_t len)- a$ Q0 |. k0 X/ }7 k
  138. {
    8 d. i  u. h' \: S$ k
  139.         uint8_t  state = 0;7 B7 z8 m7 y' J) A2 q
  140.         uint16_t nsend = 0;
    % w- W9 A: m$ i1 }1 t$ Y
  141.         state = WK_ReadSReg(port, WK2XXX_FSR);
    0 ]# [% |3 n8 G- S! ~& s
  142.         if (state & WK2XXX_TFULL)                    // 发送FIFO满
    : T5 j/ J# W. ^7 p7 u' W  ?
  143.         {
    ' m* q$ \/ Q$ d& I: \
  144.                 nsend = 0;
    4 P9 @7 y+ b% q1 O) ?1 Z
  145.         } else
      X$ e3 e) W9 P) n5 H" }0 U. E( E
  146.         {
    2 W: o9 Q3 W0 M5 B  r* |7 a5 y0 d
  147.                 state = WK_ReadSReg(port, WK2XXX_TFCNT); // 读取发送FIFO已用空间4 F# z, X* _; J1 X" b
  148.                 nsend = 256 - state;! Z7 X! D% }/ {+ m, ^5 K! o
  149.                 nsend = nsend >= len ? len : nsend;) ]4 B; C* L% }: E& M4 W/ |
  150.                 WK_WriteFIFO(port, buf, nsend);          // 将待发送的数据写入FIFO
    , A" Z2 ]+ b/ T; R$ O( z
  151.         }
    * y6 i/ [2 p0 f: H# z$ a* K0 j
  152.         return nsend;                                // 返回实际发送成功的数据量
    5 Q6 i: H( w# \6 _+ i; S% t% D+ t
  153. }
    3 p( f7 t0 t5 ]* u4 l* ]' a0 B
  154. ' c. @0 P' S+ B
  155. uint16_t WK_PortRecvData(uint8_t port, void* buf, uint16_t len)1 A  k' N! h  O+ i& A' `
  156. {3 H0 X5 y" D6 u) t7 M
  157.         uint8_t state = 0;- N+ y4 K$ U! Y; q
  158.         uint8_t nread = 0;/ C7 h  g( H' M) \. r  ~7 A
  159.         state = WK_ReadSReg(port, WK2XXX_FSR);- h6 F- h4 c2 ^
  160.         if (state & WK2XXX_RDAT)                      // 接收FIFO非空
    5 `4 d, g, A7 o/ O0 t4 C( |
  161.         {
    & u# A+ s8 a+ [7 R  ?
  162.                 nread = WK_ReadSReg(port, WK2XXX_RFCNT);  // 查询FIFO中的数据量
    & n# T/ A8 V( M' G. G! X3 Y& o! s
  163.                 nread = len >= nread ? nread : len;, H: _- a7 a# L$ D5 k' Q5 |
  164.                 WK_ReadFIFO(port, buf, nread);            // 读取FIFO中的数据
    4 J- b5 ^* X, W5 Z
  165.         }2 b5 C& d! _  c, E$ h  `: O0 I
  166.         return nread;                                 // 返回实际读取到的数据量' [" b1 K7 q( J
  167. }& s1 \. s! Y4 {0 h

  168. : N+ F# I: x5 S1 w7 d+ q% p
  169. void WK_PortInit(uint8_t port, uint32_t fosc, uint32_t baudrate)
    9 u/ I" a- K  T( f% `! ~
  170. {
    + j/ o3 c5 N0 ~
  171.         uint8_t BAUD0 = 0, BAUD1 = 0, PRES = 0, value = 0, ret = 0;' ^$ g, I( y1 Z8 Y. Z, r1 K8 S  l
  172. ! ]4 k: ?, [6 z9 j
  173.         //# }8 ^# m. m, y: d) Q( N/ h( |
  174.         // 使能子串口时钟! O2 F3 U' o! W$ l$ a" y2 Q+ P2 l
  175.         //+ O8 ^* g" R4 m# T* H0 @( j
  176.         value = WK_ReadGReg(WK2XXX_GENA);: I3 n; d" _$ b6 c, ?' W
  177.         value |= (1 << (port - 1));
    2 [. g9 U* j% V/ d
  178.         WK_WriteGReg(WK2XXX_GENA, value);* n  Y9 a/ T4 d. z: j# ~% b
  179.         ret = WK_ReadGReg(WK2XXX_GENA);
    7 X0 @0 F! Y* p; g2 I4 ^

  180. 4 `  i+ H  R/ n! T* q3 B( B6 r$ \
  181.         //
    " u5 y! [+ J9 d- ?( p
  182.         // 软件复位子串口/ S8 ^) C% g2 f8 H
  183.         //
    ; Z$ {' b9 H: q8 w
  184.         value = WK_ReadGReg(WK2XXX_GRST);: M, G$ N& f1 ~5 \5 B% c
  185.         value |= (1 << (port - 1));: T4 U& m  o1 ]9 e
  186.         WK_WriteGReg(WK2XXX_GRST, value);. S* ?% {4 W. i, v9 O( t+ p
  187.         ret = WK_ReadGReg(WK2XXX_GRST);
    % J% a2 f* s9 Q* @

  188. 0 ^3 Z0 u# |8 K
  189.         //
    + L* A* u0 Z# ^( y
  190.         // 使能子串口总中断- y! d7 F- B, i9 g
  191.         //
    ' h2 D0 K4 _# e4 V
  192.         value = WK_ReadGReg(WK2XXX_GIER);
      ~" R3 b6 m& ?: h: y, u+ d" h
  193.         value |= (1 << (port - 1));
    - \+ U3 F& _0 J- u% `6 F
  194.         WK_WriteGReg(WK2XXX_GIER, value);  j/ v2 q. F% F) W. ^
  195.         ret = WK_ReadGReg(WK2XXX_GIER);
    4 Q9 B) t7 \5 M8 ]

  196. 9 I( d/ R0 I$ c, `2 o
  197.         //2 s8 Q5 l" _4 H) {
  198.         // 使能子串口FIFO相关中断
    : w$ N7 m' W2 B" ^: F
  199.         //
    9 y$ i6 @) Q2 F! U
  200.         value = WK_ReadSReg(port, WK2XXX_SIER);$ ^) V: r4 Y* Y" N5 _. r
  201.         value |= WK2XXX_RFTRIG_IEN;                  // 接收FIFO触点中断
    5 |4 M2 d: @7 `6 G$ M) \
  202. //        value |= WK2XXX_TFTRIG_IEN;                  // 发送FIFO触点中断2 J. d2 o1 J2 d3 t+ g5 d' {+ @! Q
  203. //        value |= WK2XXX_RXOUT_IEN;                   // 接收FIFO超时中断
    % r' T6 O9 I- p9 Y- v4 ?
  204.         WK_WriteSReg(port, WK2XXX_SIER, value);/ \# r4 |& U3 M3 t
  205.         ret = WK_ReadSReg(port, WK2XXX_SIER);- K) U4 J# P$ `' x1 T; X$ o/ {; J: V2 p

  206. ! K# O7 g( k# Y7 m; h$ I) U
  207.         //) \7 w8 B( A7 x6 ^3 B, n' W
  208.         // 设置FCR寄存器  J& X1 ~& i0 ]/ z( k3 F
  209.         //8 ]6 x9 d0 Z+ v7 P; B
  210.         value = 0;
    ( e- G# u" M0 r  f  d2 g! d
  211.         value |= (1 << 0);  // 复位接收FIFO! `* A, w" N+ v$ [% u5 w6 B( @* V( H- g
  212.         value |= (1 << 1);  // 复位发送FIFO3 a) F) j: A8 d7 U2 w+ ?; E" F
  213.         value |= (1 << 2);  // 使能接收FIFO(这一步必须)
    1 W7 e/ ^: h( y
  214.         value |= (1 << 3);  // 使能发送FIFO(这一步必须)
    ( m- {+ e2 s  P" Q
  215.         value |= (0 << 4);  // 设置接收FIFO触点固定为8字节
    ( ]# t! R4 W$ I
  216.         value |= (0 << 6);  // 设置发送FIFO触点固定为8字节
    $ l, \1 ~: Y8 _6 I+ \3 w
  217.         WK_WriteSReg(port, WK2XXX_FCR, value);
    / B5 Y& m+ ]1 f" N
  218.         ret = WK_ReadSReg(port, WK2XXX_FCR);. ^) \, v  P8 g. v8 b) H

  219. ' }% t0 _6 P' f2 a& W2 F9 V
  220.         //. ~& S0 c9 p. [& \- S% P( o1 v. Q
  221.         // 切换到page1设置中断触点和波特率
    7 [* Z$ I  c( Y, F
  222.         //
    & @8 P& G0 v( H4 t$ C
  223.         WK_WriteSReg(port, WK2XXX_SPAGE, 1);
    : ?' l1 |' j" m- R; `2 Q1 `
  224.         ret = WK_ReadSReg(port, WK2XXX_SPAGE);/ U* P1 ~% C1 y* c5 C$ C; l
  225. 0 L. Q1 S, W$ p0 l1 h( ~$ z6 P
  226.         WK_WriteSReg(port, WK2XXX_RFTL, 10);      // 设置接收触点为10个字节/ V5 J# {, j! B2 m1 T$ j9 e% N5 s
  227.         ret = WK_ReadSReg(port, WK2XXX_RFTL);
    : D" H  `# P9 C  l5 k# k3 H$ c, ?( s
  228. 2 h/ h5 B* y9 C% w0 U/ J9 U
  229.         WK_WriteSReg(port, WK2XXX_TFTL, 10);      // 设置发送触点为10个字节
      t: g; l3 ~9 [
  230.         ret = WK_ReadSReg(port, WK2XXX_TFTL);
    8 U9 b) v0 }4 b& _( P5 f& r
  231. 1 l( i5 F2 `$ z1 N2 N2 }: S; V. N: h
  232.         WK_PortCalcBaudrate(fosc, baudrate, &BAUD0, &BAUD1, &PRES);  // 计算波特率3 G- j' l8 v: v4 Q

  233. . q1 H: D0 }# ^$ r* W
  234.         WK_WriteSReg(port, WK2XXX_BAUD1, BAUD1);  // 设置BAUD1
    6 ]7 f- {/ U  \  Y) q; P$ V( j
  235.         ret = WK_ReadSReg(port, WK2XXX_BAUD1);6 E1 w+ B5 l7 [3 U- e" D

  236. 9 Y; [( B8 h' }3 ^7 k
  237.         WK_WriteSReg(port, WK2XXX_BAUD0, BAUD0);  // 设置BAUD0
    ; E& Z, q, a0 t% e; B3 }  |7 D# T' S4 y
  238.         ret = WK_ReadSReg(port, WK2XXX_BAUD0);  V( f+ F: o) Y7 W, L" Z: c

  239. - c1 c" P& L$ Y; N0 L8 |* k
  240.         WK_WriteSReg(port, WK2XXX_PRES, PRES);    // 设置PRES
    0 e( o) P$ N" k7 A0 L' @6 l& T, w3 N
  241.         ret = WK_ReadSReg(port, WK2XXX_PRES);
    * l/ g& m* w$ T4 _& W) y5 I
  242. 1 S8 a7 P+ X  \& C7 n
  243.         //
    , Y. j4 J' v+ ~7 ?
  244.         // 切换回page0" K7 y  m3 U; |
  245.         //
    , x' H& {- @3 M$ v
  246.         WK_WriteSReg(port, WK2XXX_SPAGE, 0);
    5 k3 i# l6 s6 R8 B* t  f$ o( P3 H
  247.         ret = WK_ReadSReg(port, WK2XXX_SPAGE);
    8 L; [0 q* k# C9 J0 A
  248. . v) H. A$ _' C
  249.         //9 S3 t9 t% O: j2 E  B& R: g& x
  250.         // 使能子串口收发3 y( l# A0 y+ A3 n7 G: U4 b
  251.         //; E# o( z& e7 U6 H9 Y4 F" A
  252.         value = WK_ReadSReg(port, WK2XXX_SCR);; b2 M- F5 R3 P
  253.         value |= WK2XXX_TXEN;
    ) }5 ^7 C4 S* A; p+ Z0 H
  254.         value |= WK2XXX_RXEN;
    $ @6 K2 S/ w% ?, q5 q" ]# G
  255.         WK_WriteSReg(port, WK2XXX_SCR, value);
    # ]8 h' G. i5 C" f9 B" F  R
  256.         ret = WK_ReadSReg(port, WK2XXX_SCR);
    ! j/ \  g, B: H0 r
  257. }
    & E+ I3 }. c* U2 D) @
  258. # [- E+ J" ^1 i) e

  259. 2 {( Q9 h% \6 g
  260. // 如果irq引脚接入了单片机的外部中断引脚,将该函数放入外部中断处理函数内。
    ) X; [. \+ X) h; N; ~
  261. // 对于WK2124所开启的中断可以这么处理:
    , D( f5 Q2 b( ]! s2 y6 n9 ], o. s! a
  262. void WK_IRQHandler(void)4 D6 H/ S' [8 f/ P
  263. {
    $ a% M- V* @* l# Y2 F
  264.         int i = 0;
    8 {2 M5 h8 j) S1 q7 P2 o* f
  265.         uint8_t GIFR = 0, SIFR = 0;
    ; O* y- q/ X' ^- G* d

  266. % e# V5 Y) }7 e$ ^+ A; f
  267.         // 读取子串口全局中断寄存器
    * K- R* |5 O! }: P" R# f
  268.         GIFR = WK_ReadGReg(WK2XXX_GIFR);7 V1 M4 r) c9 B! h

  269. : S3 @) |- H) E/ ]2 R" n
  270.         // 查询4个子串口是否发生中断8 t. Y% n6 e/ m/ @: s, x; p
  271.         for (i = 0; i < 4; i++)
    ( K* b9 k; v  j* ]) G- i
  272.         {
    4 |5 A9 }% z: e. q9 G! n' e( _
  273.                 if ((GIFR >> i) & 0X01)
    + a7 a# {' I; S4 }6 b  {
  274.                 {+ `' {) y, ^: a$ k3 d
  275.                         SIFR = WK_ReadSReg((i + 1), WK2XXX_SIFR);
    * ~8 [! P: `& `8 Q" |: X

  276. " Y: M+ D( r1 R8 K2 F) J
  277.                         // 有接收FIFO触点中断
    ( X! G" o4 e9 a+ \3 I' Y* k2 N
  278.                         if (SIFR & WK2XXX_RFTRIG_INT)
    5 o9 X5 {3 \( h9 M; p% N$ g6 h
  279.                         {% m) x; F9 B6 Z, H' e2 l7 A/ r3 v
  280.                                 // 调用WK_PortRecvData接收数据4 q5 K& S) r8 M# r% K
  281.                         }
    / m, T- V) k" Y% e" B5 E
  282. 8 Y% K# P- b) g+ x
  283.                         // 有接收FIFO超时中断; r4 J# f% D  q, a: j  ]/ F: d( m
  284.                         if (SIFR & WK2XXX_RXOVT_INT)
    ; _! e9 \6 a+ \
  285.                         {6 y6 k8 p( d- c( D" e6 y) E/ H2 m# V& ~/ @
  286. : S7 M6 I) A7 w) r. V2 a6 j- r
  287.                         }
    / o8 t3 Q0 ~% Q8 z" I# \; O( G5 Q

  288. 2 P( d/ n8 h  L4 p1 K: W( G( [2 b" N
  289.                         // 有发送FIFO触点中断
    # C  m8 @3 B2 T" w
  290.                         if (SIFR & WK2XXX_TFTRIG_INT)
    ' }& O( P0 y4 F( ?
  291.                         {" J% w- A' m# Q& x
  292. : S3 @% O3 ]: o1 N
  293.                         }
    " P; Z8 h1 P8 m6 V- S. ^

  294. * B' D( _" D5 Z$ C
  295.                         // 有发送FIFO空中断1 @. ]! U  L2 {  ?, [
  296.                         if (SIFR & WK2XXX_TFEMPTY_INT)
    ! q" Q. p8 o. ^" _; o" b
  297.                         {
    9 k' Q$ L9 R! S% |. |) G1 x
  298. 5 _5 @: B4 s! ^8 C* `$ p
  299.                         }5 [# D' d9 A, `- z& b* h
  300.   z6 S# K) K9 H% v5 v6 x/ x3 w# G  [
  301.                         // 有接收FIFO数据错误中断
    6 ?) f+ p7 R$ j: v, U* `* x
  302.                         if (SIFR & WK2XXX_FERR_INT)& l  l  S. i# i& K: c
  303.                         {
    0 `, i, f( M1 W! [

  304. % `  g' u  k7 c
  305.                         }
    " X( X) ]5 ^' O
  306.                 }( h" y+ E% Z3 T* a. h* @
  307.         }' P* G2 l  D5 g8 a  B
  308. }
    ) a) r4 j# l/ V" T9 d+ F+ p" v

  309. , A, l3 g8 d; T2 G. Z8 ^! F
  310. /*
    & G" p: ~( @$ I
  311. $ L: D3 ?9 D: s$ b9 ~
  312. int main()
    # [# L, Z! @; r2 C
  313. {
    3 O( c1 I$ @) P6 B* D1 P( }. }
  314.         int nrecv = 0;$ E% }5 C$ V, ^6 n4 P
  315.         uint8_t buffer[256];
    4 ]9 f+ I' K" |
  316.           M" C2 b# g  p, y! e9 d
  317.         // 硬件复位一下) W% I$ g0 e( r) e/ ?+ J9 _& n
  318.         WK_Rst();
    2 Z, V5 J5 l( G# Q( F
  319.         
    2 s* s! v0 `* ?8 {! W
  320.         // 初始化四个端口
      u, V, t; g+ h! J+ {) ]
  321.         WK_PortInit(1, 11059200, 9600);  // WK2124晶振我用的是11.0592MHz的,这个值根据实际进行修改
    3 U. q0 X) q8 p' x3 Q" t  A
  322.         WK_PortInit(2, 11059200, 9600);6 l$ b/ \5 L* ^3 Y+ E5 t  K
  323.         WK_PortInit(3, 11059200, 9600);2 p" Z+ x& h' @+ {" d
  324.         WK_PortInit(4, 11059200, 9600);
    * Y& P7 g0 t0 `# U
  325.         . ^  b( f# D9 Q0 {/ Z0 o. {: j2 `+ t
  326.         // 发送数据) \, E( e" ~& e* ]+ ~
  327.         WK_PortSendData(1, "helloworld\r\n", 12);% X6 _$ o$ e8 J& D
  328.         WK_PortSendData(2, "helloworld\r\n", 12);
    6 i4 o" c$ v6 z
  329.         WK_PortSendData(3, "helloworld\r\n", 12);( [- S3 F( H. p7 S# o) C
  330.         WK_PortSendData(4, "helloworld\r\n", 12);
    2 z1 J' {# v+ ^
  331.         " l! V, Z$ W7 f; y- y
  332.         // 接收数据,轮训方式( e3 B. a4 L- a" Z2 u
  333.         nrecv = WK_PortRecvData(1, buffer, sizeof(buffer));9 H# N- o- Q- n' ?1 M
  334.         
    & M# Y) T) i+ ?* t" }
  335.         if(nrecv != 0)
      o1 q3 ?' v. U% [
  336.         {
    7 c) J  k% p2 p7 r6 I
  337.                 // 处理数据
    ' I+ T$ m$ F$ I/ {9 T9 B
  338.         }
    ' [; I+ z0 ~0 G  C( U9 ^
  339.         6 D, B  z; A8 }" U
  340. }
    1 b8 r' u4 j" f$ F2 }1 N
  341. . W+ y; k6 K( G/ F3 Q8 b; V5 k
  342. */
    . U3 \4 F$ h, n9 A. y9 \

  343. ; W* q8 j, y$ R" A- z

  344. " v4 T8 f2 e) U4 ~) n

  345. , C* \+ `; L4 s" q1 e

  346. 9 f/ W$ k' \# B6 k/ L

  347. # k; [( I6 g8 C' V2 b! h

  348. # x( w6 y9 r0 A
复制代码
$ ~9 w1 m6 o& i2 d) `( }* B
8 b/ n! u; s8 [6 ]  g2 A( ]
赞 收藏 评论0 发布时间:2022-4-9 22:59

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版