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

STM8L 调试硬件3线SPI 分享

[复制链接]
horsdy 发布时间:2018-6-26 11:19
这次调试SPI, 在网上查了不少资料, 特别是论坛上的, 现在硬件3线SPI已调通, 跟大家分享下.
* i2 P) D3 S( g; T* {/ |* o由于外设是3线spi,MCU不得不也跟着使用3线SPI.0 P% j* \3 W7 y( d; o: T0 w8 O
7 Y# I6 e# s$ u  f0 ~
MCU: STM8L051F3+ q: P! q6 l- z( d& O3 Z
外设: A7139
* Y. L% N( B8 j5 l! j$ @1 P/ r& y操作寄存器方式: 官方库函数: t4 ^8 F9 w' |6 S5 s
SPI: 3线 , l* M! a2 F' s& p+ z( w% x& V1 O) p
2 x. s) c5 f! P$ h" {$ C) C
主要步骤:, s# D) @! S# k' B& t1 c3 M; ^
1 初始化, u6 h* d3 C9 l+ a
  • 主设备的时钟极性, 时钟相位一定要与从设备保持一致,即CPOL CPHA;
  • 设置单线双向;
  • 主从的速率不能相差太多;(本人的读写数据存在错误,一直以为是读写函数逻辑的问题,后来降低速率,读写变得正常了,原来是速率的问题)
    2 {8 J2 ^9 g; Y* |3 A! `

. ?' @5 v# \$ v6 R) ^; X/**& ?7 [  [2 h, C" v$ B
  * @brief  Initializes the SPI and CS pins.% C- r8 Z" n( s2 t: w
  * @param  None/ n9 u' \1 o# }, C# o
  * @retval None# {" C5 _! R6 B5 O0 d6 F. u
  */. F2 m7 d  p6 l1 p1 b. Y4 ]% F
void SPI_LowLevel_Init(void)# n$ O4 w5 ^4 c
{
: z- b% g2 t9 @  z  /* Enable SPI clock */. u# }+ j0 n7 u7 }- u
  CLK_PeripheralClockConfig(SPI_CLK, ENABLE);
7 Z/ T% q6 y1 n
0 B9 {5 n* ~' n' K/ Z+ j3 s# R1 ~  /* Set the MOSI,MISO and SCK at high level */. z+ s$ ]; ~& [$ h9 f4 |
  GPIO_ExternalPullUpConfig(SPI_SCK_GPIO_PORT, SPI_MISO_PIN | SPI_MOSI_PIN | \( z$ ?& c; V/ r
                            SPI_SCK_PIN, ENABLE);
+ r5 |9 J/ U* O" U- L/ x: E
; [  s! |9 v4 t; s  /* SPI Config */- z9 l% s; K* _( o
  SPI_Init(SPI, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,9 Z2 g7 X3 ?& g8 _
           SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_1Line_Tx /*SPI_Direction_2Lines_FullDuplex*/,+ {4 N9 s- c1 B! @
           SPI_NSS_Soft, 0x07);
5 _* i/ ^1 l: x4 g8 E( u/ a) |, h5 a% r9 \+ o
  /* SPI enable */7 F& s7 u$ y* x1 H, r9 O  x
  SPI_Cmd(SPI, ENABLE);
; K0 j. G2 B5 U1 u, Z" J) l) j% g+ _; R. ?- b5 M
  /* Set MSD ChipSelect pin in Output push-pull high level */9 @  u: h: O6 ]. n# a4 k" F+ ~1 q
  GPIO_Init(CS_GPIO_PORT, CS_PIN, GPIO_Mode_Out_PP_High_Slow);' [! X; j) a5 D3 e( z& \
}$ [% I* P/ w9 ^2 S+ g7 X
7 J0 T/ o* M9 F3 `* W( X
2 读写函数8 u* L* \$ f( a* k3 U* S) o
  • 注意当SPI处于单线双向的RX模式时,CLOCK是一直存在的;
  • 注意在适当时候设置SPI为RX模式或TX模式, 本人的做法是要初始化设为TX, 要接收时先设置为RX,接收完再设置为TX;
  • 注意使用BUSY标志;
  • 写函数注意当数据被赋值给SPI的DR,数据没有立即发送出去,一定要等到BUSY=0;  B1 j. E+ ~7 ^; f- R6 M' E7 O

+ `% }4 o0 O. X4 W7 I. X/**( f7 N4 n. B) M. |- X3 F
  * @brief  Write a byte .
. m4 G1 X& w% [  * @param  Data: byte to send.- U, ?; O! [$ D7 o7 b
  * @retval None
$ E( p2 m5 d+ _6 P  */" ?4 @, S* z  M0 |6 R# x( `
uint8_t SPIx_WriteByte(uint8_t Data)
& b5 S1 B& m0 q! r) M+ X  J$ p" x{+ W7 k1 N5 s$ F4 L% B- [& o" A
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx); //设置单线为发送
5 }  O3 j; i/ j4 _7 n! X
- l# B  j& u6 o3 ~: Z8 b; \( O  /*!< Wait until SPI is not busy */  7 n& d9 F1 b6 u
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)
% m1 q; j6 ]" E$ S8 V+ t  {}
8 m+ l# f3 [) c  W) v5 K, Q" ]9 |7 g2 l0 t8 t2 ]  Z% I( P
  /*!< Send the byte */
0 Q! B: U# s. ?' a: E! l% S  SPI_SendData(SPI, Data);  O  ?: v5 z7 {+ g$ v! }  \

9 `0 T& H* \# {; U  /*!< Wait until SPI is not busy */, Z' }- @& Q3 k: }& y- q
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)! q) e& ?( o8 h3 Q
  {}0 d0 }: ~, v) @
. j! n3 H+ G' i' B
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收3 o" f  K) V+ @* u( X% D
  return 1;( J9 _. R3 d1 _- f3 G
}% d" V& R" T  s/ G# l
8 z4 a; k& \. f- W+ D
/**3 w. x! ^1 N8 N( Z1 Z5 ^5 ~
  * @brief  Read a byte .
7 H# u* Z* }# }  * @param  None
6 x. {4 {) J5 N  * @retval The received byte.' ~' j: A( h, z/ N# O4 V
  */
  m$ F5 q9 N4 {6 P% x8 ^9 Huint8_t SPIx_ReadByte(void)4 u! O8 ?2 F8 G2 c+ Y4 E2 x1 u
{# ]8 J! K: a) D
  uint8_t Data = 0;
; J% D  j$ X+ G& I1 Y% o0 U  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收/ }9 v# Y) {; `  }4 f- j( \  ]
  //SPI_Cmd(SPI, ENABLE);# Y6 K0 I3 z; n' l/ S" [1 T

: S  J$ Q1 l7 l  /* Wait untils SPI is working */
8 D& h- T, P/ {7 I; v* F; B7 _  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) == SET);$ P- F) o! {8 |/ I, O1 }0 e4 P

5 J1 ^9 G& T& m  /*!< Wait until a data is received */
- f7 }/ ]/ j. @1 a! W; @2 _  while (SPI_GetFlagStatus(SPI, SPI_FLAG_RXNE) == RESET)9 P3 H/ B, X, r
  {}
0 Y$ I$ t7 s; v6 B4 L  /*!< Get the received data *// b* V  @7 G4 c
  Data = SPI_ReceiveData(SPI);3 i$ B4 x- v4 v* i& ?

- V8 g& m1 Y4 G5 T  //SPI_Cmd(SPI, DISABLE);
1 z7 n: Z- l2 c, e, x  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);1 J+ _' x) u5 b* B( g
  /*!< Return the shifted data */! G) a8 L# W5 N2 ?
  return Data;! t& O7 G! _/ E0 H6 ]8 O' b
}: N4 Y/ H" D- W
8 b1 G  r* P! r, X8 |" G* {
void A7139_SetCID(Uint32 id)
( w+ o, H6 ~9 A{
( \2 t: f8 ~* u$ o$ e" |        SPI_CS_LOW(); //SCS=0;
/ {6 t% B' y) f3 t# h        SPIx_WriteByte(CMD_CID_W);+ G" P1 ^* n+ t% r
        SPIx_WriteByte((Uint8)(id>>24));1 r. z8 w% ?7 V# ^5 L% D5 J. m7 C
        SPIx_WriteByte((Uint8)(id>>16));! g( \  J( r. M& X
        SPIx_WriteByte((Uint8)(id>>8));
+ K2 X$ T! z+ g% k3 W: {        SPIx_WriteByte((Uint8)id);
1 l$ ]" z1 T* J5 J' R& ^        SPI_CS_HIGH(); //SCS=1;) U+ D" I) A4 h0 p( T' D' F" K% M2 Q
}
9 s+ o+ N. l1 G
2 m" {" i4 Y. d5 J  k" {" oUint32 A7139_ReadCID(void)6 h  o, q0 o* ~  Q% C- a7 x! S& `8 E
{
8 X6 F  ~2 M8 j; G2 Y2 `        Uint32 data = 0;
! @2 [( `8 V/ G) }3 m% [+ ~        Uint8 i = 0;! g$ R+ A- N, F$ |& `
        Uint32 byte[4] = {0};7 Y- \, x/ a/ D0 l1 l8 V  l, j7 Y

9 b; `. r# A- U        SPI_CS_LOW();% l; ?8 b" e: p& ]0 j, Q$ L6 o
        SPIx_WriteByte(CMD_CID_R);
/ m, s  X, L+ P9 c4 v6 ^3 K8 S        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收5 V2 e5 P4 K9 G' s1 v3 ?7 @
//        for (i = 0; i < 4; i++)5 k* L9 [5 H2 G1 [% G* m5 [) k$ I
//        {) n" ~% i+ f$ f" N1 `
//                data = data << 8;* T/ d, f0 S6 ]; a/ c
//                data |= SPIx_ReadByte();* c$ |) h" E0 R+ j
//        }
2 E: T9 o; l. z) {        byte[0] = SPIx_ReadByte();+ L* z. V' X- o5 t7 S& g
        byte[1] = SPIx_ReadByte();
1 J5 A) A+ r) w  U" l        byte[2] = SPIx_ReadByte();
3 W) i: n. e1 T4 }$ B9 \' @+ z        byte[3] = SPIx_ReadByte();
) O8 o7 R7 h) q6 i; s% w& M. ]* {. z' N# \3 r
        data = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];8 i' _  u) w( \9 Z# c( q' w( [
        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);+ w0 u  `# _1 M: _9 }
        SPI_CS_HIGH(); ) N5 O5 \5 @: F9 q1 E+ W3 t

2 G4 Z) P- I* _4 j        return data;/ j( R6 ^- l+ R  r+ Q* h
}
# r% L; E4 [" A8 N6 |. |0 w9 X
+ w  |) p! j* {8 X, A1 ?7 {4 Z* ]0 q& t$ W9 u9 w
收藏 评论1 发布时间:2018-6-26 11:19

举报

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