SPI驱动写法的问题

发表在 SPI2019-10-24 10:29 [复制链接] 1 286

本帖最后由 bevis 于 2019-10-24 10:31 编辑
# ^8 I0 U) g9 q! X7 _6 h# l3 W5 v
( f. W& r! k6 F+ s, v( r根据文档SPI读写方式有几种,在实际应用中使用rt_spi_send_then_recv更容易失败 ,使用 rt_spi_transfer_message反而更容易成功,文档说两者都是一样的关系。以下是我写的两套写法,自认为读写流程都是一样的。结果使用rt_spi_transfer_message成功,前者接口却是失败的。5 N7 Z3 K+ q: u4 b9 L/ G
难道这两套流程不一样吗???函数名:
0 Q- ^1 d* P& J2 q3 _" F
  1. uint8_t spiTxRx(const uint8_t *txData, uint8_t *rxData, uint16_t length)
复制代码
; q% y! Q$ o# m" G2 e

. |5 G! a$ U- x第一段使用rt_spi_send_then_recv   -- 执行结果失败, 我说的失败,不是SPI驱动失败,而是SPI设备读写初始化运行失败5 N' D/ S; d3 J- Z* @' h7 s5 [/ N/ W  z
  1. if((NULL == txData) && (NULL == rxData))
    9 ~" o9 O8 ]4 }5 T
  2.         {
    - {5 u" b0 a9 E! g$ |- m
  3.             return i;! G! K, O; O" \
  4.         }
      A" K3 Q. F9 s1 x4 o- y& k" S
  5.         7 \1 t  a: e+ c8 K5 E9 j# k
  6.         if(length > 128). R0 _' J; w1 d, ]
  7.         {
    ! w# q. L# k; c6 V9 S2 G+ U/ h
  8.                         return i;4 U- h. D; P) F, M/ m5 h
  9.         }: X; c% X+ h4 T6 E8 @! I
  10.         if(txData != NULL)
    1 e1 W( P/ A) W! v# J0 v
  11.         {
    0 z4 ~4 i. ^3 u  ^4 o4 x" F
  12.                 memcpy(tx_buff, txData, length);
    " H' v0 W# f7 V9 C" U
  13.                 if(rxData != NULL)4 D% h7 h* A1 T: X& {. |( R% [
  14.                 {
    # y: R% V( t4 H7 C! f+ ]3 ]# D! a
  15.                         rt_spi_send_then_recv(spi_dev_st25r, tx_buff, length, rx_buff, length);- W8 a- ?; E, U2 M4 ^, b
  16.                         memcpy(rxData, rx_buff, length);
    3 F  k6 C: I/ [3 j5 j4 e) M& d/ R
  17.                 }4 Z3 O. l$ {- T" Y4 M$ c
  18.                 else // RX NULL, 输入缓冲不能为空
    2 Y7 Q) c% d5 X
  19.                 {
    # j3 g. h8 D6 }
  20.                         rt_spi_send_then_recv(spi_dev_st25r, txData, length, RT_NULL, 0);. [( \6 T5 v- l. p7 Y
  21.                 }) a4 ]4 w, H- x" J2 L3 I
  22.         }7 g% {5 \( L( t/ ~" _
  23.         else // TX NULL
      W- s0 N$ N1 {6 b7 ]% g
  24.         {  R) E* \4 {; ^' M# z$ x! ?9 {
  25.                 if(rxData != NULL)
    $ C0 B. L; q6 z- v
  26.                 {
    * Q& O9 O$ f( S2 x+ k  A
  27.                         rt_spi_send_then_recv(spi_dev_st25r, RT_NULL, 0, rx_buff, length);) g: m( c9 M/ h4 s, r: e1 I4 I
  28.                         memcpy(rxData, rx_buff, length);
    2 V7 S. s$ _7 Z7 z" U+ c
  29.                 }
    9 V. s# h' |% [4 D9 N
  30.         }
    8 j; I5 [  h0 d! R7 t" {8 q
  31.         rt_thread_mdelay(5);
    ) j# h, g4 w$ _2 x
  32.   return i;
复制代码

/ z3 `; A# D8 j: p: K' d- e
- p# ~  t* J8 F, N1 T$ a第二段rt_spi_transfer_message -- 成功
/ R/ p1 D. B' [  f
  1. uint8_t i=0;
    ' q5 G  z# ]! C$ H6 E, f, W
  2.         if((NULL == txData) && (NULL == rxData))
    3 J, q: E7 {( x1 Z! N6 e) M( B
  3.         {8 ~" {2 E5 ?! [9 T  i( q
  4.             return i;. y# t( K1 }  j; t
  5.         }
    * H0 c1 T. l" u" o2 y
  6.         7 `' u: m3 E  s! U+ Y8 S; ~( N
  7.         if(length > 128)
    / U' N2 m' x9 S, K- }' y
  8.         {
    : |( t0 v# l! {" \0 S3 q6 P
  9.                         return i;# ]8 `; Z6 Q1 r& b8 t
  10.         }% v) d0 ]5 ]: P# m) h2 }
  11.         struct rt_spi_message msg1, msg2;
    . @& ]* }' a1 |" m& R, L0 m" h2 H
  12.         if(txData != NULL)7 c$ K6 s  W+ a) F) n
  13.         {' ~8 g1 c, `6 j9 \
  14.                 if(rxData != NULL) // RX 非空  c# Q' M* p; @0 E' C, o8 f, D$ m
  15.                 {
    3 u+ h! w$ _. [' Q9 {' E- U
  16.                         msg1.send_buf   = txData; // 发送缓存
    # E- x! D  n2 `+ f6 F
  17.                         msg1.recv_buf   = rx_buff;// 接收缓存; E$ e- @% S) v" r
  18.                         msg1.length     = length;! @0 Z, o+ P! D! \7 e' s
  19.                         msg1.cs_take    = 1;$ e: ?7 L4 B7 R5 Q5 a& a
  20.                         msg1.cs_release = 0;% V  U6 [1 z% j7 `; W/ w
  21.                         msg1.next       = &msg2;( d9 v: R4 i* d) K

  22. % n  h* [  {8 U& M/ G' V3 S
  23.                         msg2.send_buf   = RT_NULL;
    * ]- X2 `8 s% e8 `, F5 Y
  24.                         msg2.recv_buf   = RT_NULL;
    8 P4 G8 Z/ V, Z4 C. R; f% h
  25.                         msg2.length     = 0;
    9 ^5 o& S" x! \
  26.                         msg2.cs_take    = 0;
    - }% }+ j4 \+ {6 {* R. F; t
  27.                         msg2.cs_release = 1;# e4 Q# O  H- u
  28.                         msg2.next       = RT_NULL;
    ( Q, i* F8 ?, I6 O. |9 u3 b
  29.                         rt_spi_transfer_message(spi_dev_st25r, &msg1);3 ~. Y- L8 {/ @
  30.                         memcpy(rxData, rx_buff, length);/ A' i! E2 I5 z+ f  p
  31.                 }
    , N! J$ m- R4 b% p
  32.                 else // RX NULL$ J# ?& K  m6 z) G
  33.                 {8 e* m1 K% Q' K* w
  34.                         msg1.send_buf   = txData; // 发送缓存
    % t! ^6 O4 \0 W3 w& a: U
  35.                         msg1.recv_buf   = RT_NULL;: u5 g7 X# j: m# M- B: l1 U2 g5 C5 b
  36.                         msg1.length     = length; // 发送长度, a, I( g9 C6 g/ |: x
  37.                         msg1.cs_take    = 1;
    . |2 J) s8 ^; R* H. C
  38.                         msg1.cs_release = 0;
    / g! h% v- Y" S
  39.                         msg1.next       = &msg2;. a! C; ]: p7 @' H, i
  40. % ]6 a( L$ |- F- P0 O& P
  41.                         msg2.send_buf   = RT_NULL;
    $ _+ T- O; u8 l' J1 m
  42.                         msg2.recv_buf   = RT_NULL;$ a1 q6 n: J8 d0 X) V* [2 V. H" v
  43.                         msg2.length     = 0;
    * x# R0 C. u  q$ k6 |
  44.                         msg2.cs_take    = 0;0 T0 y$ C$ |: |& {7 H+ k, T, U
  45.                         msg2.cs_release = 1;$ _% B9 b& ^. ^% u
  46.                         msg2.next       = RT_NULL;! B0 m2 v4 P' d, ^; Y6 L
  47.                         rt_spi_transfer_message(spi_dev_st25r, &msg1);5 K( R5 D5 x2 g
  48.                 }: @& |- o  R; @' J/ y: `
  49.         }
    ' \2 q( A# k( k* ]. J6 ~
  50.         else // TX NULL! i9 w* s/ w# x# ?* Y  t' j" s
  51.         {
      c, V( n6 S3 x! R; w
  52.                 if(rxData != NULL) // RX 非空
    / B- m+ [, x. l3 O
  53.                 {( E  T5 v$ U7 u9 d+ e
  54.                         msg1.send_buf   = RT_NULL;
    " |7 Z; z$ `/ a
  55.                         msg1.recv_buf   = RT_NULL;8 q' P1 T8 P# |, @. @
  56.                         msg1.length     = 0;$ w' W" R/ ~2 e
  57.                         msg1.cs_take    = 1;/ B1 w' {- e! E  l- p
  58.                         msg1.cs_release = 0;0 q9 v9 p# o- f9 r1 H
  59.                         msg1.next       = &msg2;
    5 G  \9 Y7 U1 S1 d" h! n2 I3 ~5 M

  60. 1 [+ _$ ?- a8 \4 v
  61.                         msg2.send_buf   = RT_NULL;
    . I# N0 f  g; {
  62.                         msg2.recv_buf   = rx_buff; // 接收缓存' Y- E# s/ W) R- W  Y$ G
  63.                         msg2.length     = length;# D0 j2 z- N  G+ a5 O) r* b" Y3 k
  64.                         msg2.cs_take    = 0;
    9 e$ c3 J* H) U. \, p, q; T
  65.                         msg2.cs_release = 1;
    & g. ]) O8 s& T% ?# X8 m6 [( \2 ~
  66.                         msg2.next       = RT_NULL;
    6 O$ E' S( H$ [6 h* u; _; H
  67.                         rt_spi_transfer_message(spi_dev_st25r, &msg1);
    ; Y* B0 p  K  O0 e3 ~2 \
  68.                         memcpy(rxData, rx_buff, length);
    6 e( R6 }% k4 \+ k, A9 ^
  69.                 }+ J1 y6 f* O- l( J
  70.         }
    + }2 v) j' A; L7 @2 Q
  71.         rt_thread_mdelay(5);% ?4 H/ g  i7 }6 O5 z+ S* x
  72.   return i;
复制代码

  }" j  y9 q- J( D1 Q9 R% a; t" o5 j! d4 X5 |2 _
8 ~* s$ K" H& Q

- t4 U0 Z, N& b+ N/ L) f6 K" a/ H
. s' N, N3 l  p% G+ V
2 [8 }8 ]& ^0 Z: Y0 E, s9 m1 d' [: D; R) C: l. ~8 S

8 n: F6 m' g! W5 T
" d" j$ ~# @( y" D  e" r6 o2 L
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2019-10-24 14:22:20 | 显示全部楼层
本帖最后由 aozima 于 2019-10-24 14:29 编辑
9 j9 U. K  K" Q& l+ l$ f( Y6 f" B; C
# V  t% |! l; x' c6 w9 h逻辑分析仪解君愁。
' r3 ^' P; R% d6 r2 w2 u. g$ B' \; O) o! j, U1 Q+ x6 A7 F. B. u
另外,
$ p3 d' a9 I# T2 m& \只发不收是 rt_spi_send,
: B0 \& m& {% S: ]& s3 u3 I3 @只收不发是 rt_spi_recv.
: b" ~/ u+ s/ @3 i# j先发再收是 rt_spi_send_then_recv # K$ b: R) ^9 S& R) w
* z6 N# N6 n8 w8 V% @

4 F) b! d. b9 Qrt_spi_send_then_send 和 rt_spi_send 是一样的,但是方便使用,他们底层都是通过 rt_spi_transfer 和 msg 搭配来实现的。7 n; V# w2 y+ B$ G

& s& [& Y6 w+ s* o
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  1. 77 主题
  2. 1150 帖子
  3. 1150 积分

Ta的主页 发消息

Archiver|手机版|小黑屋|RT-Thread开发者社区 ( 沪ICP备13014002号-1

有害信息举报电话:021-31165890 手机:18930558079

© 2006-2019 上海睿赛德电子科技有限公司

Powered by RT-Thread

快速回复 返回顶部 返回列表