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

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

[复制链接]
c_lass 发布时间:2016-10-23 11:42
基于stm8调试硬件I2C经验分享
' o% K6 Q2 ~4 a: V" V" w  z' N( S
) ~. r- r6 a' a* ?3 e4 T
. J6 |4 q4 A' k- r. @网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。% S* H" Z) X6 I% j* h

8 C; o/ _8 }! E4 m: \( E: L( e7 A2 N/ |+ V* {5 a4 I9 S) P1 ^$ E
   主机主函数:
5 f- q% W; ]$ s2 w. d         I2C_MASTERMODE_Init(STANDARDSPEED);4 _. C- O) Z4 p
  I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);: B% i  Y7 O, U. W
  rim();
% q% u$ w6 d5 h+ A" y) A" r. A7 d  delay_ms(6000);
- u+ q/ b/ X! ?. N2 E( X // while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
! P5 Y! I4 k% @- K. i2 A% ` // I2C_GenerateSTART(ENABLE);
& m/ A9 u7 s1 N  while(1)5 P; d0 @0 p6 `4 ~  [& f- x
  {/ B" ?) p9 y* Y# s
    //I2C_Write(0x40,0x50,0x64);2 l3 F$ V+ ~% |. Q  l
   //I2C_EEPROM_WriteOneByte(0x42,Cnt);' Z; f" j/ X5 E; P8 p1 `5 o
   //I2C_Write(0x40,Cnt,0x58);# K* T8 w" H' z' ]4 @1 [* @8 ?
   // Cnt++;
- d' `, Y* H7 T5 ^% r& O- ^9 i    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
/ y) c% B5 Y. u1 L; }" l+ ]    I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);
9 E( |/ e+ ]. a% p! x/ k3 |) |    I2C_AcknowledgeConfig(I2C_ACK_CURR);; P- `5 T5 G- ?: K! _) W$ M+ l# V
    I2C_TXCnt=0;0 e5 C! V. ^9 \; l5 U- R
    I2C_RXCnt=0;! o" h" F' H3 p' h1 u
    I2C_GenerateSTART(ENABLE);% m5 ~5 B- K+ f# j. b6 p
    delay_ms(3000);
9 W- h# O" a& {6 V+ f# U  } % k/ P% H7 H' ~3 j5 H7 v
( n& ~- d/ K) c  {$ Q% z- v9 n, O, T
   主机中断部分:
$ V: K; c# @- D& M7 L3 g    unsigned char Nuse;
9 P0 E3 J6 u2 p' R; S. M- z/ X/ m4 y  unsigned char Event;                                 0 D% @0 p; \" b, i
  Event=I2C->SR1;                                               //数据无错位  . q- I/ m/ @+ X2 S. z
  Nuse=I2C->SR3;1 u' O, \) D+ p$ J4 E+ y
  if(I2C_TX)                                                   //主发送& Y# p5 d2 D( d" r+ \5 N8 r
  {
7 e* T0 l# i. u; ~    switch(Event)1 R& `9 X! w! E- I4 p3 i! _' }2 j
    {* b6 P$ I1 p$ V0 e* u  @
      case 0X01:                                                  //起始条件已经发送* L) z# W! L! X0 i
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);   //发送从机地址, ], E! F3 e! W! V) X
          break;
1 g3 N5 R0 x& i      case 0x80:                         //发送区空  
& W% Z/ x4 l+ G* m          I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; ( I5 I9 d# b" o
          if(I2C_TXCnt>=14)
, w; G1 U* E- Q          {
! G: Y, f6 U7 A6 }            I2C_TXCnt=0;' @3 t4 R. h# w) [# h8 q
            I2C_ITConfig(I2C_IT_BUF, DISABLE);
% p  ^- b7 g5 y          }7 a0 ~6 ~) f9 v/ T& ?. D
          break;$ f) G* C) o9 I- K
      case 0X82:                             // 地址发送结束    4 @+ k) a, N4 o: }. A: v; j$ |6 l
         // Nuse=I2C->SR3;
. E. D' k4 h% v; f5 b          I2C_TXCnt=0;, {7 J( ?/ M6 s7 {: F0 Q) X
          I2C->DR=I2C_TXBuffer[I2C_TXCnt++];
; H( a4 W. l8 ~3 F8 |& c9 {- |          break;
. @0 R& w3 J& W" h      case 0x84:! {9 M6 C% o$ g2 I: E: c
          I2C_GenerateSTOP(ENABLE);5 X5 [* }/ v6 Z1 }. M$ i
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少
! f, W, I, {0 C; t          2 _3 b& y& |1 V7 v
          break;( L9 R' o0 w7 n( Q  N' S
      default:
( ^: B: Q3 s" T          break;   2 s0 ^- u( t# |
    }
( M' l, _" Q& x) b1 s9 [/ p6 q1 d2 D+ l  }9 s3 _' Z& ?/ x$ D+ X
  else                                                        //主接收
4 F; H( B9 h+ v5 [7 H  {
+ l, T# k( ^: G6 r4 I    switch(Event)
! M. z! f* P' w    {5 n3 s2 ^4 A9 w/ B1 V4 T" m/ @  F
      case 0X01:                                                  //起始条件已经发送
2 [+ S7 E% c) P6 g3 d          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);   //发送从机地址& L: A! s/ T/ e& G7 m9 K) D% f- e- u
          break;% r' e9 m  j3 M0 F5 R: ?
      case 0x40:                                          //接收区满
; g9 X: Q0 q# ~: x, i  p          I2C_RXBuffer[I2C_RXCnt++]=I2C->DR;   # b# i2 b+ ^  a
          if(I2C_RXCnt==13); ?" C6 V' Z! Y/ l* V
          {           : [5 A3 Q: Q* S) G/ H
            I2C_AcknowledgeConfig(I2C_ACK_NONE);) x/ f5 D+ ], w! _2 N6 H  V4 a
            I2C_GenerateSTOP(ENABLE);" ]! h: S, K7 h2 w
          }
) f7 d3 K% G7 U) t) y1 P0 o          if(I2C_RXCnt>=14)0 `, ]( `+ V! a. p
          {1 J; {) H3 f  x/ j$ j+ g" r
            I2C_RXCnt=0;" C4 Y( k5 ~3 }9 h% O, i" Q
          }2 b" i; G# c- b$ V4 r" U
          break;1 R3 W& [3 X5 g+ A: D& ?
      case 0X42:                             // 地址发送结束   
+ a6 |0 j5 k3 T4 l" P: ]( P' l4 o# F         // Nuse=I2C->SR3;9 T6 Q" R+ p& C5 }/ `
          I2C_RXCnt=0;! |  D* k7 u7 R! s
          Nuse=I2C->DR;
: {! f+ ~& M. X; S+ I6 f          break;: {+ J2 Z. @: B9 Z8 l& @5 J
      case 0x44:
4 Z0 d$ q' W& q& v; H8 o' {, b          //I2C_GenerateSTOP(ENABLE);$ ~% y" \+ ?! F8 s. C/ b! D+ S
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少( z: u0 [- q1 S7 f$ m' S9 T
      default:
! j+ }& I; Y+ C' f6 j, q          break;   
9 H% H* P; o4 L- E: b2 C! ]    }
4 N0 j5 O. c6 A- b: s" L, h  }5 u7 |2 F+ P! y' \9 l7 x
   从机中断:0 z9 G  H" A# h
unsigned char Add;
) X3 ^# P! U. G! u/ ^  unsigned char Nuse;. E0 F. n$ ]3 Y' {! R
  static unsigned char RX_Cnt=0;
3 p5 b3 y; r! x/ h6 M7 c2 E1 d( q    C# P2 i# p& _1 S
  if(I2C->SR2&0X0F)           //I2C 出现错误
1 r' t6 o' x: {) o; A  u7 }0 B  {
  E" U% b/ r6 ^5 ^- T. j8 D' I9 O9 ^    I2C->SR2&=0xf0;& q$ K, t) L+ }$ r: O8 b' k. O
    //I2C->CR2|=1<<7;! q; N  j1 b) _
    //I2C->CR2&=~(1<<7);# L7 H7 Q9 v9 K6 U( Y1 @) `9 k( b
    RX_Cnt=0;
$ b8 e7 Q4 p: U& [* p    I2C_Tx_Idx=0;
4 X3 J+ s4 x% ?: }. Q! p( E# F  }  u( y& I1 ?% W, F( N
  : J' ?/ \$ G0 T. i8 r
   if(I2C->SR1&0X02)      //地址匹配
& p% x, F! S/ g, M  {
0 `+ }0 P7 @2 c% q3 Z1 [7 F3 k7 X    (void)(I2C->SR3);  //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR
  {- P3 V% n* _/ W. k     // I2C->DR = 0X00;! D0 S# P6 f5 i! y
    I2C_Tx_Idx=0;
8 o( ^3 I. a$ q+ Q' A    I2C_Rx_Idx=0;
( c( _4 Y" I9 W$ W    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
5 B% q/ C+ b# k  }
, p$ n' o2 m; Q" ?1 p) h+ g  if(I2C->SR1&0X10)         //停止条件+ E* e9 N7 Q& _- [
  {- w2 m2 N: Y, o! d
    Nuse = I2C->CR2;' n% x2 l" ~. y. L$ C1 ]1 Q6 J9 J3 [
    nop();
" f3 k/ \4 J0 W% J    I2C->CR2 = Nuse;
5 t+ j, [/ h9 G7 D7 t0 A" H  q  b  }" T- G% r  r- m  o9 D9 [' b
  if(I2C->SR1&0X04)
2 e6 ~% }' _# H- M. g9 g  {! U+ q. I6 k9 g# S0 n
    Nuse=I2C->DR;& H$ z$ [$ \8 p/ N8 T
   // I2C->DR=Nuse;* @, `3 b. L) U0 b% M
  } 6 y8 ^# A6 P9 j
   if(I2C->SR1 & 0x40)
  o- u$ K7 {. b+ w5 V   {
* l9 a& O' X% Y0 F* f      Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR;
8 B% B: \% R0 T1 A) P3 m      if(I2C_Rx_Idx>=14)% ^, G# @0 m7 j8 F' r' N& h6 H
      {4 u$ T$ n- y: h# Z
        I2C_Rx_Idx=0;
+ [8 t: r+ }( N- ?6 I      }   
# c" b9 ]6 ]2 w8 O  E' F4 x   }
+ {& ]( _2 G# r( {  if(I2C->SR1 & 0x80)
: u/ T4 ~7 P8 }8 d6 }( H  {/ s  E5 Z2 j% C* W* g, ~7 c
    //将发送的数据放入DR寄存器,清除TX
% C9 g* ~1 e; f) A; C+ O, J    //   I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];3 J0 j# ~8 _' ]
     //  if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;# _# z. ^1 @. S8 O4 B7 I3 ?  I
    9 `, f. k8 Y) q% p$ y* `- e
    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
8 h# Y' x) B  c9 V    if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;
: U3 i  X9 S. k4 C, I) r  }
6 M8 B8 ]. i* x4 b
, e  @1 p0 `% ]  }0 \; `$ A6 O7 L7 O% g- C/ j  Y3 N9 p) Y4 a: u& z
% @1 L# A, I+ b2 M

0 ]5 ]3 m' e$ o3 s% i3 _$ X% u$ d9 u! q: b1 z

评分

参与人数 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 手机版