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

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

[复制链接]
c_lass 发布时间:2016-10-23 11:42
基于stm8调试硬件I2C经验分享
+ O3 }! G, |. _5 G0 E) |$ l
; ^+ z* F9 r) Z" J$ b; J3 d1 b5 m6 L0 [/ m$ q/ l. |/ y
网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。
% B% S4 T( ]6 Q  {; a9 L% E' o2 E8 r
. o/ \; d& Q6 ]! c; h7 ~8 e4 c) f. D& J* J- C8 [% j
   主机主函数:) r  p3 C( Q/ l* j6 s3 n, |* e7 V
         I2C_MASTERMODE_Init(STANDARDSPEED);
$ E; K, Y/ |6 Q" {  Q' A  I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);% D: t8 }! V7 y- I4 i
  rim();, d5 w( t1 K6 r0 h. h) v" B
  delay_ms(6000);" e: N) ], f3 _4 J. p, r( A
// while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));0 C% i. u1 _$ U% M& n5 x
// I2C_GenerateSTART(ENABLE);
. _& E' T& D/ l# l1 p8 V0 i  while(1)
( d. I, ]& I/ d( E4 j  {
% H) b5 z; h6 Z; U- d' |$ B    //I2C_Write(0x40,0x50,0x64);
8 R; }3 j, B# ^  n( w$ R1 s: D. T# d   //I2C_EEPROM_WriteOneByte(0x42,Cnt);; J! e7 w5 O/ y9 q8 m
   //I2C_Write(0x40,Cnt,0x58);9 q/ n4 Y9 O9 G* s: Q
   // Cnt++;2 g9 Q* N5 j! L3 }' a. ^8 d
    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
  l3 b7 k0 H9 S' B9 m. X    I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);5 I0 ^2 y7 U+ i8 s! v
    I2C_AcknowledgeConfig(I2C_ACK_CURR);# d5 ]0 `5 X" m( m5 Y
    I2C_TXCnt=0;
. p! ?3 Z1 P4 i3 S7 R- k! D" ]    I2C_RXCnt=0;' }1 n  k4 ~- @' k) Z
    I2C_GenerateSTART(ENABLE);
7 D/ Q4 C$ T7 Z" `# e1 P- B    delay_ms(3000); , K7 F# N1 D2 u1 N8 H
  } , G, g$ r9 V+ t! G* J- v
% W, o$ {' X8 t+ U7 R
   主机中断部分:7 k* F  X0 L- W$ L3 j; m
    unsigned char Nuse;/ q* L- m; c$ L' `/ W+ {/ v3 Q8 x
  unsigned char Event;                                 
6 I: r7 B* ?4 E' X  Event=I2C->SR1;                                               //数据无错位  4 Y4 S0 g1 |6 g1 }1 [/ W9 v. m0 V
  Nuse=I2C->SR3;; z0 j& F5 A" C3 a% b# Q
  if(I2C_TX)                                                   //主发送7 p+ f4 z& `5 v! @
  {
1 N2 u( n+ P: E: [, C0 R    switch(Event)
1 i: m# ?) b+ }6 N* L' n    {: ^5 @" N- q( w
      case 0X01:                                                  //起始条件已经发送
# F# F  x4 W) ^( [          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);   //发送从机地址
/ r- c% M! R" T9 |          break;9 q$ R% Q: w5 |4 e, q+ a
      case 0x80:                         //发送区空  5 ~4 p/ r4 x, ]& A7 i
          I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; 7 u: i$ ^9 G: J/ T8 ~
          if(I2C_TXCnt>=14)! o' H+ O* P7 V& ^  \  t
          {
. d4 x% v5 E. z2 \            I2C_TXCnt=0;% o7 l+ R5 l; {) i5 j
            I2C_ITConfig(I2C_IT_BUF, DISABLE);
' k: V! t, G; X# \  Y* F+ o          }, M" P4 N! D* {
          break;
) [# j* T7 e" I      case 0X82:                             // 地址发送结束    5 n( R' I; S" g8 ]& n' [4 \2 ~" f
         // Nuse=I2C->SR3;
# v2 L/ I  L. {& u- s. o6 x5 L          I2C_TXCnt=0;
1 r, l$ U6 `9 z; a  e& g/ V          I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; 6 L. Z( J' U0 b; ~/ m2 [8 ^
          break;
4 }( s8 G/ S9 c% R6 J" L0 g      case 0x84:
% D( Y" t3 i3 X( z5 ?          I2C_GenerateSTOP(ENABLE);% ~( P) J8 Q& a, u0 e$ T
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少
2 @3 e3 i9 o1 ~# J! k          9 D5 |' T5 p6 H
          break;, V7 g  S/ N/ i% ]* i" i3 I: B% \
      default:
& G$ M. F6 {0 l          break;   . O4 n* I, b% H) w
    }3 l$ n$ y% B7 s( D( y
  }
: {. u2 e6 F" Z) h" G5 Z. F$ G% f5 G  else                                                        //主接收
( X" ^9 o+ }3 l  L( q; t0 C  {$ t0 V8 }+ U) J5 C4 c! u$ |! c) ^
    switch(Event)
. p/ I% d# E/ Y& q; H    {: J; U8 X9 i' O
      case 0X01:                                                  //起始条件已经发送: _2 E+ o* _. A8 w2 C8 `
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);   //发送从机地址3 o) {+ K( V: ~9 t, o
          break;& |, S, E! f' W, Q" l6 m5 z
      case 0x40:                                          //接收区满
, O2 g, z* F- c% Q- c1 S          I2C_RXBuffer[I2C_RXCnt++]=I2C->DR;   ' Q$ U+ L0 `% ]+ M+ X
          if(I2C_RXCnt==13)9 m5 j- b* c# ]  \* ^
          {           6 e. G1 g4 \& s6 G
            I2C_AcknowledgeConfig(I2C_ACK_NONE);
8 }7 `' s6 {: u# c            I2C_GenerateSTOP(ENABLE);  f0 I* C' [/ p/ v7 ?0 V) O6 A* @
          }
; x4 v9 @  u  G" I          if(I2C_RXCnt>=14)
' q' t4 p1 t: f* Z6 e& u2 `0 J* F8 D          {% y7 _! q6 G  H* b+ i0 S1 s# C
            I2C_RXCnt=0;( y  V' \" N1 W6 P) w5 e) @7 E
          }' Q, G3 p' U0 d- z
          break;
% {; q; a6 n+ x: j1 {& R3 F      case 0X42:                             // 地址发送结束    3 y5 H& F2 I; z' K& T" w
         // Nuse=I2C->SR3;- H9 G; N, u# o. j: h) \* n
          I2C_RXCnt=0;: r: z: @: ]& o( X
          Nuse=I2C->DR;
0 e+ ?; a: c5 K  t; j1 I' `          break;
. c, B4 f  E9 B' ~  d      case 0x44:* ^% F/ M* V/ J0 H& a
          //I2C_GenerateSTOP(ENABLE);. x6 o3 n  f2 }/ q
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少, M4 B7 {0 [2 X. H1 k
      default:4 K# H9 y8 B; k6 Q- R4 r1 q
          break;   * p; {6 P2 A, d% p6 q
    }2 u9 a0 n$ L! O/ o2 F5 x, P
  }
6 U4 [: P/ A% t% ]: p   从机中断:
9 M% f3 S: ^5 H9 k* ~$ munsigned char Add;: v/ P9 q0 _7 {* w" n
  unsigned char Nuse;6 R* X5 _5 L7 r
  static unsigned char RX_Cnt=0;" z. z. |+ I, d1 m; o
  - n, z/ T8 C+ h  q! W+ J) p
  if(I2C->SR2&0X0F)           //I2C 出现错误
' E, s& j8 t, t5 W- Q+ m  {
* x+ u8 O' K1 H1 o" ~    I2C->SR2&=0xf0;3 G  c+ u4 o* v4 F; ?! {7 @- r
    //I2C->CR2|=1<<7;
9 `4 m, C, Z  {0 k& E+ n4 w    //I2C->CR2&=~(1<<7);
  J: a3 U( f7 R# [/ b% ?    RX_Cnt=0;
2 o4 \; H9 s* l$ q; l9 N    I2C_Tx_Idx=0;
1 h# T( C1 D6 h  P# h  }- K4 N% k  Y2 U4 B, B
  8 E* R' K- k6 x# h" R/ n: ?. |
   if(I2C->SR1&0X02)      //地址匹配6 l1 p. Z* a9 ^$ L7 g
  {
: U3 `. E: F0 Y. S; |$ |! l    (void)(I2C->SR3);  //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR
4 |! ~5 q( w  H  Q     // I2C->DR = 0X00;2 x9 Y  c% Q4 p& O. r
    I2C_Tx_Idx=0;
6 l- J" t! Q8 D2 c; q: \    I2C_Rx_Idx=0;
- Q8 W* f0 N" f4 t    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
5 }. n7 m% a- D/ i  }
. s. m, N( l. n7 v" K: M  if(I2C->SR1&0X10)         //停止条件4 H* I8 d; z' i% T% W6 }
  {
' N# }# I& o9 k- a9 N    Nuse = I2C->CR2;
; K, n/ Z& D7 ]+ }; W0 a    nop();" v3 h( {5 \3 @
    I2C->CR2 = Nuse;" ?" s* T: l* }1 s2 O$ I% }# G& h
  }! I, H. C( R; o' }
  if(I2C->SR1&0X04)
* t1 D5 S2 W4 z. K5 A; O) x! M8 m. e  {/ r9 Q' d5 u+ c) T: L
    Nuse=I2C->DR;
3 l1 e; V& ^7 T   // I2C->DR=Nuse;7 p( F; P" k" \. p  L/ P
  }
% W: `- w3 D9 [  p, H   if(I2C->SR1 & 0x40)  {, V$ S6 n) Z6 s, B  ?9 _( B
   {( N& {9 I) c6 D: X
      Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR;
8 D5 Z6 {3 ~/ r1 @$ i: }; g; I* U      if(I2C_Rx_Idx>=14)
, C' G3 ~4 ~1 r+ q+ y) ?      {
9 u$ j. q, `2 ^" A5 [        I2C_Rx_Idx=0;
! t7 S- S# j2 `( E; g/ W' o/ U      }   
! N5 l; i7 _+ O3 ]) r   }2 @; u" l" D) w8 }0 b1 e
  if(I2C->SR1 & 0x80)
: w/ u7 p! f& \3 [  {- k$ _: K& X! |7 k. L  `- Z5 d. Q1 M( @
    //将发送的数据放入DR寄存器,清除TX0 L6 M6 x2 l4 |! j: Z- Q- y
    //   I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
: {/ _. U* F9 U. x! b# L# m     //  if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;2 b" |7 k  l  K8 Z7 i: H. ~3 ~4 I; Y
   
9 `' [0 j% b7 @3 K8 j9 c. w1 u    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];4 Y+ S! V9 f2 a5 [$ r2 a
    if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;
9 A3 {/ m6 C2 g3 B% ?' }. j  }
8 J5 |7 e4 j, b* \* ~
  M, e. f+ F7 n4 T: }) ]& _' `9 U) ?7 c* n
; S( ]% i; Q1 x" F+ e; F

- u  D( R  k( p) c5 s' Z
* y1 ^4 O6 F% [5 w* n  B5 s- ]

评分

参与人数 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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版