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

STM8L 调试硬件3线SPI 分享

[复制链接]
horsdy 发布时间:2018-6-26 11:19
这次调试SPI, 在网上查了不少资料, 特别是论坛上的, 现在硬件3线SPI已调通, 跟大家分享下.1 ?3 M" S3 O0 p" v
由于外设是3线spi,MCU不得不也跟着使用3线SPI.
/ B% m+ f* h' L3 Q/ [' ~# R# m& X9 O# K6 |' t/ D. f1 |. U  v9 U. `
MCU: STM8L051F3& a0 }( X! A2 c8 L2 _, q$ `
外设: A7139
; v, S3 ^9 |. n0 D8 `. E操作寄存器方式: 官方库函数. I+ G& z( _$ A9 k# B4 E
SPI: 3线 # I9 J7 u, e2 `" m

- m+ @- L; I2 P3 w主要步骤:
8 p5 l8 b, ]- ^; D5 v/ ]5 ]1 初始化' l% u3 b( q1 z/ y3 @8 \
  • 主设备的时钟极性, 时钟相位一定要与从设备保持一致,即CPOL CPHA;
  • 设置单线双向;
  • 主从的速率不能相差太多;(本人的读写数据存在错误,一直以为是读写函数逻辑的问题,后来降低速率,读写变得正常了,原来是速率的问题)/ |9 C1 }7 }/ R$ F0 z
& `2 m8 e3 r, ^# K- |
/**( s9 C+ ]; r  @' [
  * @brief  Initializes the SPI and CS pins." N9 B4 s  K8 k" P' P
  * @param  None
  L# N& V, a3 m. }* O1 p  u1 \4 Y  * @retval None7 z* x  Y$ Y0 s& t* k
  */
/ o* {# T  X1 A& Y% ^& Cvoid SPI_LowLevel_Init(void). w% m8 b/ [- ^  z. b; R
{
. U$ q, f" ?6 F+ ~" h, J( Z* x) g5 A  /* Enable SPI clock */4 |# |" ?- k3 X. w% b8 O  i& N% j* `
  CLK_PeripheralClockConfig(SPI_CLK, ENABLE);1 k9 J! H- c, `" O  w- }7 Y
$ d) `, l( {9 C6 `( S: R/ B
  /* Set the MOSI,MISO and SCK at high level */
( f$ C* d& R, n# k  s  E& U# h  GPIO_ExternalPullUpConfig(SPI_SCK_GPIO_PORT, SPI_MISO_PIN | SPI_MOSI_PIN | \
& \$ \: {2 H: U6 T3 w                            SPI_SCK_PIN, ENABLE);8 m+ m- `, w6 l& \8 Y  e

% m8 I- T  j- J/ r- I  /* SPI Config */
$ K. A% M" e- z. ~  SPI_Init(SPI, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,
) r+ {: b$ g* ~0 Q8 r) X# {           SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_1Line_Tx /*SPI_Direction_2Lines_FullDuplex*/,6 _+ D( f8 L7 q* _
           SPI_NSS_Soft, 0x07);
) B8 y: b$ ?' L9 E2 l, C' d3 T7 V& n$ _8 s5 t9 z" H+ h; U3 E
  /* SPI enable */* A- v0 V8 `! [4 ^
  SPI_Cmd(SPI, ENABLE);
( Q. T1 S* n, T: @) ~! D6 w, t2 ]: m+ R; F% G
  /* Set MSD ChipSelect pin in Output push-pull high level */3 x  T% c4 n0 ^: h
  GPIO_Init(CS_GPIO_PORT, CS_PIN, GPIO_Mode_Out_PP_High_Slow);
# o/ k) P& K* ^. \}
* k) X& _0 ?/ F# H- \8 V7 @+ \( \4 V. }: p
2 读写函数5 ^  T1 G- c4 Q: E
  • 注意当SPI处于单线双向的RX模式时,CLOCK是一直存在的;
  • 注意在适当时候设置SPI为RX模式或TX模式, 本人的做法是要初始化设为TX, 要接收时先设置为RX,接收完再设置为TX;
  • 注意使用BUSY标志;
  • 写函数注意当数据被赋值给SPI的DR,数据没有立即发送出去,一定要等到BUSY=0;
    9 e& o" O/ l  e( w
2 _' ^8 V0 m8 [. p
/**
  N5 l- a4 u; w7 v# X, m, G: A  * @brief  Write a byte .; C; z8 j" C1 v$ K/ M
  * @param  Data: byte to send.3 S4 B9 l5 \, R) ?! Q
  * @retval None
3 s" a( J" P) w4 F! c* A3 K; W  g  */
* v: P" b2 {8 auint8_t SPIx_WriteByte(uint8_t Data)
) H' B5 U2 Z( U; ~/ l+ d- \) y7 c{4 N2 a9 g" h/ F: @7 H0 U) A
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx); //设置单线为发送
9 @$ h3 h8 j' d& x3 O' }" o( g7 q+ h7 P! J* Z
  /*!< Wait until SPI is not busy */  
- ~& j0 t* o1 }; S- q. Z& @  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)
# O  ~) L6 I6 U0 F$ S* o  {}
* a% ]3 S: G, c( [; ]4 i! @  i
+ W8 O9 ?$ @" H' _4 |$ e1 G  /*!< Send the byte */
1 Z) \. J4 G/ c  SPI_SendData(SPI, Data);
% [9 M. B3 h/ y2 C. z4 z* i8 T
2 ?7 ~# y% I- ?) \# y  /*!< Wait until SPI is not busy */2 n8 B4 k# p: f% d9 k
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)2 O) L+ H% {$ d0 Y* Y
  {}
( s; u6 p5 z) q6 a6 I
  b. |& O% d' [6 R( D$ d  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收$ V$ c# Y' ^. o- Z1 r2 a
  return 1;6 F5 o8 g& d$ ~8 o
}
1 e" A3 q" T! i8 u- b7 ^/ \. ~0 D: \5 z5 g# {3 s4 A; R+ S
/**9 ?; z. L. q, h6 U4 C9 k) X' o
  * @brief  Read a byte .% ]3 b8 H7 u" C9 g2 B
  * @param  None' C1 V* W0 o, a
  * @retval The received byte.4 h  a' }0 E( S$ ~4 u% j' P5 c2 j
  */
/ ^' L5 w( E# ]uint8_t SPIx_ReadByte(void)
' |% v3 a: s* w9 ~9 ~5 F0 p{4 j) R4 i. p8 L3 f4 N
  uint8_t Data = 0;
5 _6 x6 [5 d& c! j: X% k2 y  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收. h9 @/ H/ l0 K
  //SPI_Cmd(SPI, ENABLE);
1 g& {- X" U% m  w, n- D5 k# Z8 k/ C
& y6 v7 }6 Y% s* K9 a7 Y! X  /* Wait untils SPI is working */
+ e& E" s2 c5 Q2 e+ m( L  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) == SET);0 r! ]! u/ M- h7 A! ?+ z! s

! K, }/ U% d0 O  r' V8 o  I8 U0 U% v  /*!< Wait until a data is received */& e" b' \0 B; Q
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_RXNE) == RESET)
) d4 M! e4 f* ?0 o$ u2 N5 m  {}3 z/ ^: X6 F/ r1 W
  /*!< Get the received data */
2 a) F9 c7 {  s" W: M4 r  Data = SPI_ReceiveData(SPI);9 |4 W0 H+ b% ^6 C' U

7 S4 ~; M. m" y2 n  //SPI_Cmd(SPI, DISABLE);' O" R4 O2 ?+ D) r7 W4 I1 @
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);1 ~+ _4 z3 u6 F2 ^) {
  /*!< Return the shifted data */* {; e( l- c& E! w& E8 f* d
  return Data;
* d' q+ q, U; ^% |}6 v+ i. M0 C, n# o
  P9 g/ `8 u6 _' @
void A7139_SetCID(Uint32 id)
2 Z8 D# Q# v5 u9 J& |) r9 w& e$ z{
. m5 u0 D; J5 A  }        SPI_CS_LOW(); //SCS=0;
7 L; b) F$ V2 z! Q( D* G' s! g        SPIx_WriteByte(CMD_CID_W);
+ m. C1 S* h" }) O2 A        SPIx_WriteByte((Uint8)(id>>24));
  R& O. }, r+ @$ H4 K! Q  g        SPIx_WriteByte((Uint8)(id>>16));
' @  _) N/ y" q        SPIx_WriteByte((Uint8)(id>>8));
. C# Z6 V: ~2 B8 `! v  `        SPIx_WriteByte((Uint8)id);
  k& Z  d9 o' u& e/ N/ @! m        SPI_CS_HIGH(); //SCS=1;1 J3 F! Y# K* K" R. B: S
}, n1 {0 Y/ ?0 f& j# X$ G$ m
  `$ c. r" Q/ ^+ o! U% P7 G
Uint32 A7139_ReadCID(void)
5 A5 M2 H: A: L  S{$ X5 t4 V, W9 x6 y' |
        Uint32 data = 0;, Z$ D  H( K: X/ |  P6 d! t
        Uint8 i = 0;
+ l( W4 V+ a5 T! e        Uint32 byte[4] = {0};7 n* g% t2 {% O5 |2 t* X

; j: s9 y. Z+ F' @, }& J+ A) W        SPI_CS_LOW();
% s# d/ w( K8 @, h4 d        SPIx_WriteByte(CMD_CID_R);
! ?9 ]7 G* i, ?+ G* R        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收. s& F- x' V, ~* P0 \
//        for (i = 0; i < 4; i++)
* ~, q' h0 Q7 p, u//        {
4 V  w0 ~1 m6 w# f/ V9 ]//                data = data << 8;
- |1 q! Q; p3 w0 K% w7 J' I4 `//                data |= SPIx_ReadByte();' O' W9 b5 z5 S  G$ ^
//        }
+ x* k  y$ w: G9 e! @        byte[0] = SPIx_ReadByte();
9 E3 ^. T* Q8 `        byte[1] = SPIx_ReadByte();9 H4 E+ R  N. [. p1 X
        byte[2] = SPIx_ReadByte();
( d. l# K! r( C# |+ a        byte[3] = SPIx_ReadByte();
: b5 {$ n0 z6 ]" [
2 G: F, T% O  Q# v  q/ w        data = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];0 W$ X% i- `3 T( F# }6 v' S/ f6 J+ O
        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);
4 O( ~5 B2 |! f1 X% z+ a+ g        SPI_CS_HIGH();
8 g( S" m! L9 t3 O( U8 @' d7 q
7 X( b$ g' T3 U) K% X        return data;& N& r: T, e! _) a$ d
}4 D/ d' H" Z5 Z& l9 b+ x  I& n

  M- b' w2 Z0 |5 M% L' p; k: h+ _* f+ y7 M) j! ?1 T
收藏 评论1 发布时间:2018-6-26 11:19

举报

1个回答
zero99 回答时间:2018-6-29 10:33:56
谢谢分享,楼主可以考虑用下面的工具,代码看起来更舒服0 M3 G/ m. g$ [3 M2 y7 i% h. X, J
https://www.stmcu.org.cn/module/forum/thread-612887-1-1.html
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版