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

STM8L 调试硬件3线SPI 分享

[复制链接]
horsdy 发布时间:2018-6-26 11:19
这次调试SPI, 在网上查了不少资料, 特别是论坛上的, 现在硬件3线SPI已调通, 跟大家分享下.( F4 h( L) _5 @8 `0 v
由于外设是3线spi,MCU不得不也跟着使用3线SPI.
" d7 c% l4 n8 \6 p# X* M
8 s; G+ H( F* y5 NMCU: STM8L051F3$ b3 s0 [( E1 o4 _3 C
外设: A7139/ S& z' c0 x2 j4 f: A
操作寄存器方式: 官方库函数
! m5 b" Y9 p& f: _3 Y# k( zSPI: 3线 # d% e& s. @- {2 k7 p

9 K& U- X0 A  N- v& Y  ^" {: _  m主要步骤:  a2 n  S; o, P- X; T
1 初始化
0 r2 K( b/ ~: s$ x9 W/ O' `7 @% M; D
  • 主设备的时钟极性, 时钟相位一定要与从设备保持一致,即CPOL CPHA;
  • 设置单线双向;
  • 主从的速率不能相差太多;(本人的读写数据存在错误,一直以为是读写函数逻辑的问题,后来降低速率,读写变得正常了,原来是速率的问题)
    : |, Z# v* |- \& K% k1 k( u
$ o7 h5 x2 S% `0 ~# u  |
/**
. t6 e+ ~3 z; j8 b8 O: s3 U  * @brief  Initializes the SPI and CS pins.
; a/ ~. L( \8 M  |. w) U  * @param  None# p  D. R; Z# R: R& E" O
  * @retval None
: M) f# d* b( r% h$ q8 g6 W6 i  */- J3 _/ J1 w0 y6 K' d( q6 Z$ F
void SPI_LowLevel_Init(void)) W& e8 @  o+ v1 r: a  d- p! U
{  n6 p& C$ ?# D3 E$ y
  /* Enable SPI clock */
7 s' W& E; M8 n1 d* P$ h5 y( @+ @  CLK_PeripheralClockConfig(SPI_CLK, ENABLE);
: l9 }0 d8 Z2 Q" v/ y# W4 s" ^- ^1 T4 W" j+ ]
  /* Set the MOSI,MISO and SCK at high level */1 k0 E4 D2 Z8 E0 k% M
  GPIO_ExternalPullUpConfig(SPI_SCK_GPIO_PORT, SPI_MISO_PIN | SPI_MOSI_PIN | \
& a# J# f. y& o+ X! I8 l: B, D! x, q                            SPI_SCK_PIN, ENABLE);2 e/ X, @; n2 Z9 Q: |' C% J1 u
9 W" s8 V1 S/ U- ^" ~9 J* ]
  /* SPI Config */
; [* V  u1 y. p6 F# }  @  SPI_Init(SPI, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_128, SPI_Mode_Master,
7 o4 E+ }) F: Z' s/ T0 D2 V           SPI_CPOL_Low, SPI_CPHA_1Edge, SPI_Direction_1Line_Tx /*SPI_Direction_2Lines_FullDuplex*/,
# [8 a2 e5 _2 v           SPI_NSS_Soft, 0x07);
! @1 _3 i2 z5 }# E) k5 o$ ?' i/ V; b4 n0 Q5 m: n! j- x
  /* SPI enable */
9 F8 x4 F! G3 d3 a  SPI_Cmd(SPI, ENABLE);
6 m: U0 F9 V4 \1 l6 c7 x: w% q" O& S! v$ }
  /* Set MSD ChipSelect pin in Output push-pull high level */2 S% r0 s7 C: K6 R! N2 T
  GPIO_Init(CS_GPIO_PORT, CS_PIN, GPIO_Mode_Out_PP_High_Slow);
  B) |% _8 ]5 u0 `}/ m7 [- X5 F" Q7 d) o

: N+ M, _- B; }4 U1 x+ ?, K2 读写函数# k+ I0 q5 E" @0 \. o* u
  • 注意当SPI处于单线双向的RX模式时,CLOCK是一直存在的;
  • 注意在适当时候设置SPI为RX模式或TX模式, 本人的做法是要初始化设为TX, 要接收时先设置为RX,接收完再设置为TX;
  • 注意使用BUSY标志;
  • 写函数注意当数据被赋值给SPI的DR,数据没有立即发送出去,一定要等到BUSY=0;' h' U, [, @/ E- d* w

, g5 _# C! C# E: _7 Y/**: J; C" j* n3 n2 V$ H
  * @brief  Write a byte .
. {- \; T# i; K! c/ ]  * @param  Data: byte to send.
0 R$ S) p8 M9 Q7 K* m+ g  * @retval None
, n" J( h) X7 E" B, A2 j  */
. \0 u. v% y( ]0 E) Y' c" Y' T0 {1 Fuint8_t SPIx_WriteByte(uint8_t Data)
' p, s3 X7 ^- E/ o6 K{5 U0 d! B& b  z$ O0 T0 O) G; [+ C
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx); //设置单线为发送: u* n4 ?3 ^9 G; N3 i( `

0 R5 ]2 J; H" b5 i  /*!< Wait until SPI is not busy */  4 b/ _9 I9 P5 s, T# l# h
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)
8 }. X- s$ ^  {  |8 d) v  {}+ G' {% X$ d0 N: t
3 ^$ x- P# P, g1 r. w
  /*!< Send the byte */
: k2 b$ G) A: ?! t1 Q2 T8 b6 n  SPI_SendData(SPI, Data);
/ E& ]2 C: u; h/ N& K6 y- Y
( R, m2 {# w5 Y0 D8 i  /*!< Wait until SPI is not busy */
1 j/ G4 S6 p! f, S  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) != RESET)& S- F/ |6 [8 k# _: g
  {}
. P- t$ a2 u4 |
; r; R4 u% D" O6 h) S# ]4 n  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收4 }+ |% x! W  K+ Q
  return 1;
; l% W5 L  B3 c, t: s/ Y}" B& J. [$ v. C9 G' E! G

, n3 Y4 p! W5 }& |$ C! i: D, I/**. S  E$ c% u" k2 X4 D
  * @brief  Read a byte .# I8 v5 T1 @0 C+ t$ b$ T
  * @param  None6 o, T# V! O3 {" H
  * @retval The received byte.2 ~  J  V6 U& A! c  V  j: ~
  */
2 I1 b  }, a! p1 Juint8_t SPIx_ReadByte(void)! [- Y9 h& S* M* U# A
{
+ m0 ?2 u/ @# y& q  uint8_t Data = 0;  r2 b  F# W* `* `5 T: o2 z5 G
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
" @5 E3 K' Z  i5 }  //SPI_Cmd(SPI, ENABLE);9 U% u3 C4 s( G( _' o9 Z

0 X, [' H' ]  `- v$ m* z# I, X  n  /* Wait untils SPI is working */- _' g. Y0 {% c1 M( Q/ z
  while (SPI_GetFlagStatus(SPI, SPI_FLAG_BSY) == SET);
( F; }7 e; D- K, R" s8 i3 B+ r# W
  /*!< Wait until a data is received */
" S; X2 f  C( ?; w5 @5 |; |  while (SPI_GetFlagStatus(SPI, SPI_FLAG_RXNE) == RESET)
1 O  y9 X9 j5 A0 \/ A7 l/ v1 S  {}
6 W) Q" I/ b$ z% {  /*!< Get the received data */" G. ]: w& a+ K
  Data = SPI_ReceiveData(SPI);% ]) |2 \! \' T* N

/ S" P1 X2 \/ M  //SPI_Cmd(SPI, DISABLE);; E# {; g: b. G: _
  //SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);% [# s8 B( \2 u# A3 w0 n+ C0 a5 g- J) p
  /*!< Return the shifted data */2 C: _4 J+ z. h# D4 ?
  return Data;8 z  ^7 P) a5 H* q8 E% a
}
, o4 l3 ?  I, N% {" [4 s3 F5 W
7 x: f, @; `5 s! J) A. j+ O& X* y2 b+ Xvoid A7139_SetCID(Uint32 id). C, P1 y7 k5 F8 H
{
& o5 ^1 m7 C3 D        SPI_CS_LOW(); //SCS=0;+ m; @2 v$ G: Z0 H7 j
        SPIx_WriteByte(CMD_CID_W);/ D/ I% R; ?2 ~6 ?4 S2 n
        SPIx_WriteByte((Uint8)(id>>24));' I- I" L0 l: p* s
        SPIx_WriteByte((Uint8)(id>>16));% B# ~5 N1 N' W% I+ I/ L) u
        SPIx_WriteByte((Uint8)(id>>8));) ~4 s4 X" N3 \6 b
        SPIx_WriteByte((Uint8)id);
& b" \& a1 |8 ?* k/ b! a        SPI_CS_HIGH(); //SCS=1;
- w) f: v1 }+ t* c$ Y5 Z}' W& u7 d5 t! Q7 x- w% u

7 s2 L3 s( f- v8 W# ]Uint32 A7139_ReadCID(void): p5 m. P2 h$ e: h. J, ?
{
' _# Y% E5 U. _! v) S- |        Uint32 data = 0;
% F5 q" V5 v: E# X6 f, v        Uint8 i = 0;4 x( e( D: U  [9 B+ u- D
        Uint32 byte[4] = {0};! w! P% P( t0 i5 N* L

! V9 {/ @( v9 \  w        SPI_CS_LOW();& H& d1 x  d' U
        SPIx_WriteByte(CMD_CID_R);/ H4 G! O) R5 l7 g4 l
        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Rx); //设置单线为接收
; F0 f* p: l" k( u//        for (i = 0; i < 4; i++)
- `  D  J$ ?  d/ c//        {, A4 o1 p9 O" l
//                data = data << 8;2 i4 U% A( s" v- {
//                data |= SPIx_ReadByte();
) h" c% W* M5 A1 ]' E//        }
$ L9 d$ ?8 R& e, P        byte[0] = SPIx_ReadByte();6 h: L0 e+ v4 a; a. y
        byte[1] = SPIx_ReadByte();
# J  Z& @; l2 m  W        byte[2] = SPIx_ReadByte();
6 h: a$ j. L: q, p        byte[3] = SPIx_ReadByte();
+ g2 @. W7 q/ ~. g/ n2 }3 `  {3 ^) J6 a. S0 C  f9 A) c' _
        data = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3];
& y8 \* f4 _. H1 n5 B2 f+ p        SPI_BiDirectionalLineConfig(SPI, SPI_Direction_Tx);
4 W0 z" |" U) E        SPI_CS_HIGH();
2 R8 \2 I3 I7 D9 N0 c0 J, Y3 t2 f4 J8 g$ v3 p
        return data;
) q. ~( h6 v! n7 d7 r}
# q0 I, _; V1 U( N2 I: X; I% E3 \% L( z

$ y3 _: U# K' ]' @. ?
赞 收藏 评论1 发布时间:2018-6-26 11:19

举报

1个回答
zero99 回答时间:2018-6-29 10:33:56
谢谢分享,楼主可以考虑用下面的工具,代码看起来更舒服& q  ~( Y( Y) G& E/ [) J
https://www.stmcu.org.cn/module/forum/thread-612887-1-1.html

所属标签

相似技术帖

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