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

stm8硬件I2C 主机/从机 发送/接收 完全解决测试验证通过

[复制链接]
c_lass 发布时间:2016-10-23 11:42
基于stm8调试硬件I2C经验分享
* z8 X+ ^% [# a  i7 a% o" c* y4 W' x% X" f$ X; X
! h" ^' g( T9 O2 L- T6 Q
网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。
6 L: b- x3 D7 i% j5 P, \! k, z
( H" _* n( l6 w, A: H  {7 [/ U1 P( C. V- ~! B
   主机主函数:: f& O5 N, U" e/ A1 O8 N& ~7 t. o; B
         I2C_MASTERMODE_Init(STANDARDSPEED);
4 W" F5 S9 R, d- A  I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);
  ~5 J, X  R" C) e+ j  rim();+ k3 [! H1 M: F! ~- ?; R! d
  delay_ms(6000);6 `* J( v9 X! X' c/ U0 l
// while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
; Q2 n5 N& m1 l1 W // I2C_GenerateSTART(ENABLE);% T& y0 b" Y7 s# `7 t$ E3 h
  while(1)* L' S6 }/ M$ o  l& m7 Q! D& J
  {
' ]7 z6 P3 _$ F4 `    //I2C_Write(0x40,0x50,0x64);' E& `: v. X: K7 A6 k2 r
   //I2C_EEPROM_WriteOneByte(0x42,Cnt);
, ~0 x/ }, O" L8 X- O. ^, ?5 @   //I2C_Write(0x40,Cnt,0x58);
# ?' B5 k9 ^, V, J$ P3 S# ]   // Cnt++;% ^% ^  k! ]' x
    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
; c  x& ?$ y- i* @( E1 O. A2 r    I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);$ ]4 |# C$ I' k; b& B" v
    I2C_AcknowledgeConfig(I2C_ACK_CURR);
+ ~) t% K8 D  S9 \3 Q/ r    I2C_TXCnt=0;
* f7 k2 D$ t0 {    I2C_RXCnt=0;2 }( B% h5 e, J  Z! u
    I2C_GenerateSTART(ENABLE);/ Q4 q7 ?0 J# e8 S7 ?
    delay_ms(3000);
) `- H5 N, v: ^  }
* N2 Y# ?0 K9 w2 w2 a% x) k' y
   主机中断部分:/ Y( _4 G) u( C1 z5 R! r
    unsigned char Nuse;
8 g' [' k, f/ u. m/ x! j6 p  unsigned char Event;                                 ! d$ }" `; `! u) k( M- {
  Event=I2C->SR1;                                               //数据无错位  / n0 R0 Y: j1 V+ Q, O
  Nuse=I2C->SR3;6 u+ F3 t  S1 I0 v
  if(I2C_TX)                                                   //主发送" E: `3 E+ t- d: N+ O, K3 ^/ n
  {
. M" L' G. A2 {' u    switch(Event)
* n9 u8 [6 H' M. e& z4 n( ^, q    {' C1 D& O- i, B5 C/ J5 V
      case 0X01:                                                  //起始条件已经发送4 O# }/ V, N9 E3 {# }2 e
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);   //发送从机地址
% X9 T3 }$ q7 [4 C: d- l          break;/ R8 n9 A- Q/ Y/ _( X- U
      case 0x80:                         //发送区空  
# P/ F/ f3 n2 K7 P5 \          I2C->DR=I2C_TXBuffer[I2C_TXCnt++];
  E. ]/ ?& M3 U5 r) m          if(I2C_TXCnt>=14)
# J: \/ V" O' B4 u5 t8 l          {
2 W( T% l+ P* A/ |8 g( D" y            I2C_TXCnt=0;7 k3 j% B' Q1 i0 ~, R
            I2C_ITConfig(I2C_IT_BUF, DISABLE);
9 R0 l! F6 y# Q          }+ j; T" w6 o, p. L. c3 J
          break;
9 `$ x4 d( `* u3 _0 F      case 0X82:                             // 地址发送结束   
  d) e7 N7 ?. S, S$ }  h         // Nuse=I2C->SR3;
" N4 u; _0 g( h7 A" D* c          I2C_TXCnt=0;
+ ?8 r+ J' s, A* D; ~* x& c          I2C->DR=I2C_TXBuffer[I2C_TXCnt++];
5 t; I# M2 W. N9 o: F          break;
2 t' [' q1 Z. Z( s1 B      case 0x84:
: H/ {& }# u1 Y% q( H          I2C_GenerateSTOP(ENABLE);% D' B% B4 M- f, B
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少
8 R; I2 d) H7 O( V7 y          + J4 z; V7 L& Y: I  T
          break;
7 l4 Q# Y. M/ F4 V9 b      default:( S5 G! _' B5 V+ ^8 ?% I( w
          break;   
; P( N8 G6 h  O1 P+ j    }# w. B6 R1 C* A  l( j2 G
  }
, h; V$ C9 Z& m; E- q  else                                                        //主接收( L4 [1 H& H. S. x1 W' p& I$ ]9 h
  {, A5 r/ y) u  t% A5 p- I
    switch(Event)5 _: A" M; @0 |, a
    {- }* `9 S  ^* R: N7 m/ b* y
      case 0X01:                                                  //起始条件已经发送; G# o: t3 {  f7 _4 {5 z2 y' Z
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);   //发送从机地址
6 z/ p  A% m+ t' |7 y, l& a- V          break;; l# D5 ^  m2 v7 [
      case 0x40:                                          //接收区满
) V; t+ b+ s( _) r5 y* x7 o, H          I2C_RXBuffer[I2C_RXCnt++]=I2C->DR;   
, Q/ ^+ z& N/ H& S          if(I2C_RXCnt==13)/ C% @2 J  x3 f7 ~8 l9 B
          {           
- _% [. y4 Q* N            I2C_AcknowledgeConfig(I2C_ACK_NONE);
2 F4 ~2 S6 D; f1 Y0 W4 w            I2C_GenerateSTOP(ENABLE);+ o* X5 c+ H+ b4 L3 Z
          }( \# @/ a& B* k0 Z6 e* p% {
          if(I2C_RXCnt>=14)) p; ]# F1 n, M& _1 j0 h. \
          {& ^5 Q9 N7 L* H" ?  ~2 j
            I2C_RXCnt=0;
! j2 r- _) E# M" Z1 b) }          }
' S' [) o# Y9 |( J/ {" B0 N" }          break;
. K( s$ L. ?/ A      case 0X42:                             // 地址发送结束   
3 v1 M3 P+ }7 y8 O. n( n( ?3 m         // Nuse=I2C->SR3;
9 G+ W( C& H5 h0 y9 i6 A. S          I2C_RXCnt=0;
: [1 s2 y/ v9 Y+ V+ G- L          Nuse=I2C->DR;
$ \+ l9 H, X; m* U( v0 E9 }0 I          break;1 B! }) Y5 @, _' L3 z
      case 0x44:
( {+ f; n4 y* @& q& B          //I2C_GenerateSTOP(ENABLE);+ J+ \$ `: J/ F9 Z2 L. \% I3 g, z
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少
2 s1 i$ t* ]9 P8 r# f1 l      default:
- _2 H5 \6 G2 l. ?. X6 q          break;   4 V1 L- h3 B) x- r" u5 D' b
    }0 v3 n" c1 G8 }# I/ F$ m2 n. ?4 Y
  }
! x& h# v! d# x  c  J7 ^5 N( w   从机中断:+ r- l) m+ `: U7 T0 N: Z9 a2 v7 {8 J
unsigned char Add;
  z: s3 v+ y; W: [+ l% D( t  unsigned char Nuse;
4 d) Q& {4 C3 e' g; G  static unsigned char RX_Cnt=0;
# p1 p  n* q/ ]$ k3 e5 @- w  
) o* ?( v, V$ X6 S, T  if(I2C->SR2&0X0F)           //I2C 出现错误
' A. ?# E  M! V  b  {2 j: `3 J' B) k; U; Y
    I2C->SR2&=0xf0;
3 Q6 F4 c$ a- q% ~9 F    //I2C->CR2|=1<<7;
  i6 x& U3 p: J7 ^; K; B8 t    //I2C->CR2&=~(1<<7);
9 ], T7 Y. k3 m1 k1 D    RX_Cnt=0;1 ^; |. d2 o! n9 |" h, _3 ~5 m
    I2C_Tx_Idx=0;
! i; m$ z5 h. B  }
$ j; Z' P) E: N  k' ?" X$ {: s  ) v) C2 Y. L( K& g" z7 _" v
   if(I2C->SR1&0X02)      //地址匹配
9 `( C/ n+ c6 L  g5 ]  {
6 S7 J$ D9 X9 o! R8 G    (void)(I2C->SR3);  //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR9 F1 s8 Y( s. i5 P; D
     // I2C->DR = 0X00;+ E' j% r' f, J3 Y3 o' B1 Z; c9 T8 M$ j
    I2C_Tx_Idx=0;: w! ?0 T' [3 w% R- v9 b# W
    I2C_Rx_Idx=0;
0 K# [$ w" ]9 b$ ~! v1 O6 Z" w    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
1 u7 s  s# {+ x9 I. ~& l& E  }
( J: S( W; U3 f  if(I2C->SR1&0X10)         //停止条件
" Y! L1 W- d$ S2 \* K  {
) C7 H" o- r. i& o, r3 q  f; i    Nuse = I2C->CR2;" ~  _6 i! Z$ E  I4 Y
    nop();3 x7 e( J* X  T* ~
    I2C->CR2 = Nuse;& [+ Q2 V& O* U8 u  `" f* |
  }' S5 ]! [/ h; a; H+ a* ]6 u
  if(I2C->SR1&0X04)$ G* |/ T6 \* Q/ ?5 Q: ~
  {9 g! Y, g' r6 `9 y# J" E- {
    Nuse=I2C->DR;
$ {. D/ r  L7 S, V0 p+ u9 ~9 R, R- I   // I2C->DR=Nuse;/ g6 T3 [' Y0 r& j- r1 W
  }
' P1 a" H+ ^: }) Q6 \   if(I2C->SR1 & 0x40)
+ K& t  g/ d* x6 R  H% x   {) M" D1 G* E' g- G8 z5 T$ d: B5 H
      Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR;' T1 ?% \( |; r4 _0 I
      if(I2C_Rx_Idx>=14)$ r+ F' R" |: ]- U: @4 \2 L
      {
% G! \# F) K! x( Z. X3 X. q        I2C_Rx_Idx=0;) C  K% Q4 s' x6 a) z
      }   
3 v$ y$ z$ _: _   }
) @$ K! F# p6 [$ z) _4 k  if(I2C->SR1 & 0x80)! {, `5 ^5 U! r+ g: O  H0 m
  {4 J0 ~9 e! a' k1 Z& V2 C2 O9 V
    //将发送的数据放入DR寄存器,清除TX+ x7 I" H* Y7 z) R+ \# [$ _: p; N
    //   I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
9 `$ j# Q4 ~, ]0 d: a8 M     //  if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;7 \) Z/ U& I# p" ^
   
6 R7 s" s. K1 T4 p  O0 C    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];& _: j8 _, B2 ^3 J5 ?. g6 m6 W
    if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;
' \3 {( \6 u6 c% M8 F3 n; _' M  }1 o' x6 ^* J& t4 p! k9 `+ f; Y0 J

) O- O. h: M& i- E3 A1 F1 ?5 m: s. n' s8 S0 r/ I5 B
) _8 R! K2 z  ?( z
& Y- m7 ]4 S0 b* k, d2 Y

" P' c+ D! Q$ K. q. R

评分

参与人数 1 ST金币 +10 收起 理由
zero99 + 10

查看全部评分

赞 收藏 7 评论14 发布时间:2016-10-23 11:42

举报

14个回答
zero99 回答时间:2016-11-3 09:58:07
多谢分享,不过楼主发错板块了,下次注意
peter001 回答时间:2016-11-5 20:34:55
多谢分享,I2C有些难调
诗歌 回答时间:2016-11-11 11:30:37
想问下楼主,I2C_TX是怎么处理的,多久去接收
诗歌 回答时间:2016-11-11 11:43:08
应该是I2C_SR3的TRA位,对吧
assssdz 回答时间:2016-11-11 12:20:03
wdshuang09 回答时间:2016-11-16 12:16:04
        
fengurl 回答时间:2017-6-6 18:10:54
楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗?
c_lass 回答时间:2017-6-22 15:14:34
STM8S103 SLAVE地址是自己在舒适化设置的
秦皇岛老王 回答时间:2017-7-1 14:55:08
版主有QQ么?有问题想咨询下
蓝色天使211 回答时间:2018-1-23 12:38:06
感谢楼主分享!
ycaaa 回答时间:2018-1-28 17:02:13
11111111111111111111111111111
Johnson Cao 回答时间:2018-1-30 10:18:13
小镇夏天的风声 回答时间:2018-10-10 17:59:17
多谢分享 还是软件模拟好用
sincomaster 回答时间:2018-10-12 08:51:40
谢谢分享

所属标签

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