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

STM8L 调试硬件3线SPI 分享

[复制链接]
horsdy 发布时间:2018-6-26 11:19
这次调试SPI, 在网上查了不少资料, 特别是论坛上的, 现在硬件3线SPI已调通, 跟大家分享下.( m: b# ]+ S7 @# P& f- `2 _
由于外设是3线spi,MCU不得不也跟着使用3线SPI.
$ K6 f) I& J; s; V+ E7 N  p* Y- t. u/ U3 Z7 \
MCU: STM8L051F3
  z" e$ s4 V* D5 e5 Y- G外设: A7139
$ Z0 l% ^, J% w" s4 n操作寄存器方式: 官方库函数
2 d  L. I" c* F2 Q" \SPI: 3线 4 a7 X. Z+ }- H0 q! }
6 W" u  a4 U+ {8 ]6 @+ K% {
主要步骤:
! C+ T* q1 F2 Z1 初始化; U3 n4 h0 i2 r# t2 L
  • 主设备的时钟极性, 时钟相位一定要与从设备保持一致,即CPOL CPHA;
  • 设置单线双向;
  • 主从的速率不能相差太多;(本人的读写数据存在错误,一直以为是读写函数逻辑的问题,后来降低速率,读写变得正常了,原来是速率的问题)2 U) l  W, W% D# f9 ?/ u0 N

7 p9 t! L+ u# Z# L/**
' Y7 h. Z5 Z& M1 K2 m; f0 A' \8 B2 e2 r  * @brief  Initializes the SPI and CS pins.
' g! A+ K7 L1 h2 C1 n% W( N  * @param  None: ]. q2 W2 [: a$ z! d+ D
  * @retval None7 E) W1 T0 Y! S
  */
% h5 Q& V# E* _$ L, M: dvoid SPI_LowLevel_Init(void)
  ^  \2 S- d8 |, D& \{
: W  E& X: a) r$ @6 \4 {  /* Enable SPI clock */
& R4 u8 C0 n' y# A5 E( m  CLK_PeripheralClockConfig(SPI_CLK, ENABLE);
' i2 d* R4 b' o" G
- I: V9 C0 g  F5 \2 z2 k' s4 j  /* Set the MOSI,MISO and SCK at high level */
% X$ g/ ?( f: c0 y0 o& x- y$ E  GPIO_ExternalPullUpConfig(SPI_SCK_GPIO_PORT, SPI_MISO_PIN | SPI_MOSI_PIN | \
6 w, ]% p( L* B; Z! ~0 d# d                            SPI_SCK_PIN, ENABLE);
2 u& S7 |$ h9 G6 @+ Y$ |/ W' @
% g: i6 S4 U2 P" K  r  /* SPI Config */
  o. V9 o1 [& K$ a  SPI_Init(SPI, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,1 c* {% P% Z2 s5 r" q8 x9 q
           SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_1Line_Tx /*SPI_Direction_2Lines_FullDuplex*/,
% |5 }' O' C$ h/ m3 S           SPI_NSS_Soft, 0x07);! Y3 @8 m  K! P5 G& x  W

/ c7 g7 v$ S7 N( N! J! y  /* SPI enable */6 l( U0 v9 |7 i) X' Z3 H5 ~* t
  SPI_Cmd(SPI, ENABLE);1 b- t: I. Y/ f7 L7 V' U3 ?3 x

6 y' I2 N% E9 G# H+ t/ D- V  /* Set MSD ChipSelect pin in Output push-pull high level */+ v0 I# h5 x( a1 S  o. S2 i: i/ V
  GPIO_Init(CS_GPIO_PORT, CS_PIN, GPIO_Mode_Out_PP_High_Slow);
# r. Q, Q; L5 ^- }2 p}
0 N' r5 p3 x6 l9 n4 K6 `1 U2 z0 l' W1 e
2 读写函数
- N  s8 }6 s. b) _  `+ Q4 o
  • 注意当SPI处于单线双向的RX模式时,CLOCK是一直存在的;
  • 注意在适当时候设置SPI为RX模式或TX模式, 本人的做法是要初始化设为TX, 要接收时先设置为RX,接收完再设置为TX;
  • 注意使用BUSY标志;
  • 写函数注意当数据被赋值给SPI的DR,数据没有立即发送出去,一定要等到BUSY=0;$ j9 @; e% X' w

/ c; ?9 l+ m. f1 a/**
0 j( X7 k' P8 z  * @brief  Write a byte .
5 D% k% x, ~  [0 C" X  * @param  Data: byte to send.- n6 r' v5 w  F, y0 E* |
  * @retval None3 O. b  W6 |8 a  N
  */
) o  g% I  s  d' ]  y+ o% k: C3 xuint8_t SPIx_WriteByte(uint8_t Data)
% @+ s, ^- T: E/ r+ O% y{  ?: Y: I5 l3 ?" y, w
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx); //设置单线为发送
0 {( H, t  X, f' s
( F0 y1 x7 v0 H( g9 C5 j- |6 }3 Q+ C  /*!< Wait until SPI is not busy */  
- M: H% I  w7 P1 ]. }  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)( x8 S& J0 A: m% ?# a7 M  I  T
  {}0 z- x) F  Q* x# u+ Q
" }  y! Q- Y+ {# j7 ^" K" i
  /*!< Send the byte */
& o% |( q! }+ u% i* T# y1 h  SPI_SendData(SPI, Data);' S# A1 j6 H2 }& f. R" |9 _+ {$ G
, Z) X: K# [% ]
  /*!< Wait until SPI is not busy */9 ?( Y  d+ w8 ?/ \, t
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)
/ t" ^- ?# ]  ]8 G4 U  {}; P+ \+ W5 ?( n$ r4 I/ _) ~+ b! E

7 T8 J  O3 G8 \" f' g3 V" z$ E$ J  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
& o! z1 i: H% H* r0 x  return 1;
% M1 o: D$ ~7 _/ q}
4 W8 w' C" D% f6 s# x- g- D2 @
) i) v0 G% [2 o, I* {1 e/**
  m) |! ^- k: }5 N  * @brief  Read a byte ./ R5 q' @% ~- O" x" V
  * @param  None
  a& c% f5 U; Z" Y6 ]7 W2 z  * @retval The received byte.& @1 S. k( w8 P+ `- n
  */+ `- H* h8 p8 e3 k# `
uint8_t SPIx_ReadByte(void)
! e, Z1 X9 Y  J{
  A, f7 C; d/ Q4 L4 ^' L  uint8_t Data = 0;
7 [% h5 J" P+ }  _3 m8 k  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
: L  @; b' P- S5 t  D  //SPI_Cmd(SPI, ENABLE);4 S- K% T* N* Q: [# ?( [! Y
3 g7 X& i9 m. U( z1 d; G
  /* Wait untils SPI is working */0 w9 d# F8 E: \' N6 U) U* c2 u6 O
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) == SET);
) e- `$ l& z6 G
. p0 M* V" n6 H' X: b$ R7 y$ B  /*!< Wait until a data is received */
2 D# y, d: G4 Z9 i* F# X  while (SPI_GetFlagStatus(SPI, SPI_FLAG_RXNE) == RESET)0 i- c# S1 m% b
  {}# M2 q0 v4 m1 r& T; H8 m3 P& F7 a! \
  /*!< Get the received data */
# H$ ?# m  C6 V1 n  Data = SPI_ReceiveData(SPI);! Q" M: w, b6 t

) l* h' |% k: K) @  //SPI_Cmd(SPI, DISABLE);
& [. m. T$ |0 u, e  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);; s/ ]8 |" I" x  s0 K
  /*!< Return the shifted data */7 }# S6 r8 S9 p# y! M
  return Data;
% x8 A, w( S' {& X8 i7 Q" a}% `! {* I4 K+ E3 e  l$ R

, M  n6 E) Q! b. tvoid A7139_SetCID(Uint32 id)
8 C/ W2 M1 w0 {  e- {3 U{, _$ j$ |0 x) @1 I5 o# }
        SPI_CS_LOW(); //SCS=0;* ]" M, j- W7 [% b" f0 I
        SPIx_WriteByte(CMD_CID_W);
& w- E0 s: a" ]2 E1 O: a8 ~+ c        SPIx_WriteByte((Uint8)(id>>24));
0 v/ W0 J1 ^0 z2 m" r7 v2 y) W3 z        SPIx_WriteByte((Uint8)(id>>16));
7 L0 X# ]7 q; p  Z- s        SPIx_WriteByte((Uint8)(id>>8));
& k/ Y6 d4 d6 K! p        SPIx_WriteByte((Uint8)id);( ?* i/ D4 f' l6 V( ~2 f: g
        SPI_CS_HIGH(); //SCS=1;
2 Q4 Q1 f5 X# I0 t}( c( C' |4 Q6 \4 P9 N# ]- c
6 \; u. o) q# D% T& K. l
Uint32 A7139_ReadCID(void)" y6 C5 a! f& ]- V$ {5 }3 r) s
{8 e4 \$ A  o# g# v9 m
        Uint32 data = 0;
) }/ H" O6 I+ z$ [2 |        Uint8 i = 0;
  S2 E, ?- p& l. @/ R        Uint32 byte[4] = {0};
; A! A; P% f, N0 O( |% l; o+ L: ]1 {5 \
        SPI_CS_LOW();
6 E  ]- b( A; Y) P        SPIx_WriteByte(CMD_CID_R);9 P3 ]  b/ z, `& `* P0 v
        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收; G; M6 Z: r0 W9 F$ J
//        for (i = 0; i < 4; i++)
( a: a  J( ^3 ?) @9 d- c3 M//        {
; x+ c1 v' G" T//                data = data << 8;
; G+ ?$ f3 V2 X2 x  M( V//                data |= SPIx_ReadByte();; o/ i' h% o" N9 j) ^) j4 f; H
//        }
/ p, h7 U( Q+ q$ C; s        byte[0] = SPIx_ReadByte();" N* g: k+ `1 n1 e8 L* M
        byte[1] = SPIx_ReadByte();
4 F& k2 L' a% @( P: D% e" V  K        byte[2] = SPIx_ReadByte();+ f4 |' D; N4 b# A+ E' N2 f3 M/ j; p
        byte[3] = SPIx_ReadByte();% x( Z5 i. W2 e7 |3 [

" \! c* Q0 a# O2 B6 n8 P1 t4 R        data = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
0 O/ P2 L4 L" S        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);
5 n8 }8 }: j9 v" D! y        SPI_CS_HIGH(); & G4 u3 \1 y2 b: \2 J( W
/ V4 u) {6 g+ |/ @+ N
        return data;8 ~) e, F* ^. N$ w  S8 f! l
}
3 ]9 u: I; E! n, R! H6 z- O9 a8 l: _6 _! Z' R
9 e* a# F6 j/ N5 ?
收藏 评论1 发布时间:2018-6-26 11:19

举报

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