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

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

[复制链接]
c_lass 发布时间:2016-10-23 11:42
基于stm8调试硬件I2C经验分享
: W- N% J& k: E) ]8 q' M, K0 U( v
- \' U! J3 e5 `8 o3 H
网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。
# ~8 O2 K2 T4 |% F" c) g, E/ I% p

- p% E; ]  A* U( Z  i; r   主机主函数:
% N6 i; v8 }* z& f8 p         I2C_MASTERMODE_Init(STANDARDSPEED);
+ e* l( Q# A  ^8 O; t, s5 o  I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);
" @* O% g1 S. U; _  rim();& m. e: F0 b+ U0 k0 ^
  delay_ms(6000);5 Q# h- b/ y9 ]4 ~8 M% h9 H
// while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
3 `$ g0 g! M1 _2 Z5 A# L4 A% G" ~ // I2C_GenerateSTART(ENABLE);$ G  B9 D8 X3 U' E& a! |) @; Z
  while(1)/ C5 F3 v3 ?" e- M9 {! e# M5 j
  {  E* W& S5 X+ u" `- `
    //I2C_Write(0x40,0x50,0x64);3 r+ H8 P& ?0 ]9 u
   //I2C_EEPROM_WriteOneByte(0x42,Cnt);9 o; ]% h4 |; B; K7 D  J- o
   //I2C_Write(0x40,Cnt,0x58);
, W, l, a+ G9 y( c   // Cnt++;, X. h2 Z5 k9 W. m$ s9 _# m
    while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));! g0 u7 C1 N9 k. z
    I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);1 F/ ~5 n$ f' Q
    I2C_AcknowledgeConfig(I2C_ACK_CURR);
% X1 t2 N- b$ S  l* ]1 }1 ~    I2C_TXCnt=0;
+ M" R7 n; M" }; s    I2C_RXCnt=0;
# r# m* D3 t7 I2 V    I2C_GenerateSTART(ENABLE);3 l( I% ]* z) u$ h
    delay_ms(3000); ( L: c* U5 M- @2 }; x
  }
: }5 N9 d1 z3 |& V3 U
( B( ~( o9 x) U   主机中断部分:
# l5 n& W5 f( T3 L    unsigned char Nuse;% E; ^$ ^9 G6 [1 U
  unsigned char Event;                                 % N/ N+ a; ^7 r8 z, [# x% c
  Event=I2C->SR1;                                               //数据无错位  4 d. A- A3 e: \: E# W1 n
  Nuse=I2C->SR3;
0 o% z/ l7 P* ]4 r/ M& x8 m  if(I2C_TX)                                                   //主发送
' `3 L, L. A( B- I  {4 W6 G2 `- D1 J8 X) g4 A
    switch(Event)7 w2 q5 s% z1 k0 z5 M' j% X! K! ~
    {6 C4 t9 r- x* R
      case 0X01:                                                  //起始条件已经发送( ]$ x, }- l" f1 E
          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX);   //发送从机地址5 Y( [: P) Q8 V. {" G/ c
          break;
- a, f; F, {) k# v! n4 R- w      case 0x80:                         //发送区空  
7 c- P3 f# B3 i          I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; 3 {3 ?. A* n* T  x; g
          if(I2C_TXCnt>=14)" P9 k) c- L! B- v
          {
. l! Q. p+ t; R+ K1 \            I2C_TXCnt=0;
& w1 p: L( H- p8 `6 n/ \6 h) X' [            I2C_ITConfig(I2C_IT_BUF, DISABLE);
% \/ Q+ k. Q; G          }& O$ n) C% a1 i6 G, `' S
          break;
" h2 i1 Y0 E7 I6 \+ q      case 0X82:                             // 地址发送结束   
8 w0 }3 `; C* n0 s7 k- u         // Nuse=I2C->SR3;
+ r' |" Z3 H: }* A. b          I2C_TXCnt=0;/ a- f, k, P2 [0 j) a: r& ~5 j; Q( n
          I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; - _% D# a8 K! ~" w8 A/ {$ p" V, ]
          break;) O) y+ |1 r! Y: S
      case 0x84:
' D. Y: _# d) e$ r) @          I2C_GenerateSTOP(ENABLE);. M7 R; K, F/ c" l$ m
          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少: z3 f4 \  Z* L- B/ ?3 x% s
          7 F/ Q- b% K/ z8 E  N
          break;1 I- s) N. }2 j$ T6 a/ I7 Z
      default:
- E3 b! ~, {6 _7 y          break;   
& }7 K3 x, a- R( R: V- W. [0 a    }
% s6 y- j+ e4 v. I  @  }
2 |* P3 w& C1 v! o& X  else                                                        //主接收
6 T, {# f: b% ?0 J4 ^# V* S  {: k" `" B0 a" d
    switch(Event)
$ J) u' h$ N; D0 N1 h; U4 {    {
% y/ f8 C8 A$ E7 m      case 0X01:                                                  //起始条件已经发送
, V7 w1 P# W8 I          I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX);   //发送从机地址( u2 d( }0 H3 q8 c: Z8 d& u
          break;
$ K5 H, M- V, E9 Z- l# }/ x( R      case 0x40:                                          //接收区满
4 r  X5 O4 g; i" f          I2C_RXBuffer[I2C_RXCnt++]=I2C->DR;   
1 r. h) a6 O" m6 ^9 s6 S# ?; K          if(I2C_RXCnt==13)/ @+ Q$ A/ Q, t1 {" Y. E
          {           3 W" R* V; `- U, @( K7 Z% _
            I2C_AcknowledgeConfig(I2C_ACK_NONE);  ?; J4 h0 c5 Y7 {
            I2C_GenerateSTOP(ENABLE);
* Q# ]0 R9 l6 K- Y  m, \; k          }
5 S  _  @8 m1 \8 a( y7 ]          if(I2C_RXCnt>=14)
) Z* t* N# J9 C$ o8 C& m          {
& n1 c- G4 R/ g7 |4 ]            I2C_RXCnt=0;
7 |" }2 p1 S. ~          }) C# j  W9 N* [9 t. s4 ?
          break;+ t9 R- o% d4 P7 t$ F' {+ ], N
      case 0X42:                             // 地址发送结束   
! n$ K8 W. w1 s: d2 y         // Nuse=I2C->SR3;
. @% O, o" S2 p0 }4 Z9 {7 z          I2C_RXCnt=0;
% z; j, a  ~0 Z' W9 v          Nuse=I2C->DR;9 N) \  C* B5 @. F/ t8 Y
          break;
( X7 `5 n4 B' ?# Z" I6 c      case 0x44:
7 k! }" R+ l$ @          //I2C_GenerateSTOP(ENABLE);
; z9 `/ j! a& W$ q# O6 @          I2C_ITConfig(I2C_IT_EVT, DISABLE);   //不能少6 w& p5 m3 x) n8 h9 u" v
      default:
, Q1 Z5 e3 T/ i  o  s" R' p          break;   * Q7 B* U: s& h5 n# p$ N
    }0 q3 W& H- ?$ e& v5 K# H
  }% t% Y* v, O4 X1 Z1 L
   从机中断:8 k! \# j0 ?1 f9 }0 A+ D0 ~% S" S
unsigned char Add;( ~; _* M& U+ Q
  unsigned char Nuse;
, c; F3 Z  {2 t* Z  static unsigned char RX_Cnt=0;) }0 O# @3 r  \% w* E& M7 G
  
! K1 t% h0 {" o, j2 F1 K% ?- {! W( K  if(I2C->SR2&0X0F)           //I2C 出现错误! v- D5 e* x- i
  {
1 ]! {: K8 c: O4 H) B! o$ H+ D    I2C->SR2&=0xf0;
: b7 t' Y3 ~+ V' O9 ?( s4 `9 r( \    //I2C->CR2|=1<<7;5 ~: K$ p, x! m2 r8 h
    //I2C->CR2&=~(1<<7);
; F4 H4 l, {& z* o* v; `4 o/ [    RX_Cnt=0;# I) G1 r! p) E  o/ b
    I2C_Tx_Idx=0;
) u$ w* N7 f. S' g  }
9 H) }0 F% x, G, F/ U$ t! w7 ^  / ^- u& w' h; W$ A7 j# f
   if(I2C->SR1&0X02)      //地址匹配
: w+ [$ l9 V/ g, Q  {
3 F& A( ?$ x7 Q& d    (void)(I2C->SR3);  //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR
8 ?/ A; Q' H& d* T     // I2C->DR = 0X00;
: O  T7 J8 I9 s! p6 p+ g2 ?    I2C_Tx_Idx=0;
  ]* ?" q5 K+ ]8 r  b9 T  b9 s    I2C_Rx_Idx=0;
) Z* l- ^* M" L9 _    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];
1 S+ c; E3 }+ G3 D  }
1 v' F" m& T0 s0 v& ^0 n; R  if(I2C->SR1&0X10)         //停止条件
% e* N8 `1 Y* ^7 W6 U- [  {
+ I% m/ ]# c1 ~1 X  I# R    Nuse = I2C->CR2;
. u! V5 D& u* o; |/ l" P    nop();
5 F% N; _6 z+ R    I2C->CR2 = Nuse;
9 J/ V' x4 ]* M8 x7 N  }
6 h1 }. M+ r4 q. f: F  if(I2C->SR1&0X04)
0 F" p) a) F: X  {
; x/ A& b$ k; ]. d2 S, o, \    Nuse=I2C->DR;
0 p/ A" m: R5 h! c! P: k   // I2C->DR=Nuse;0 h0 B7 V! X/ \: m! s6 }6 i
  }
' x) C- h( y- ?% T% R  P' P   if(I2C->SR1 & 0x40): p5 }% b6 w! M  @
   {9 b7 x3 B, I; p7 {+ Y
      Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR;/ z" T. w' b, \7 v0 D" p/ Y+ l+ R6 A
      if(I2C_Rx_Idx>=14)3 [, K* E6 F3 P9 l( D/ \
      {
6 z' R5 q/ O- ~9 Q; t2 a        I2C_Rx_Idx=0;
( w, L$ ?- T! `5 R$ g' b      }   
# r7 N+ i: G6 ^8 ^+ k3 U   }
8 q, S0 w1 T. M: z* q  if(I2C->SR1 & 0x80)
/ i4 A0 R6 `1 s) l  {
; T+ o) D3 a3 x9 u$ Q" s! `3 s    //将发送的数据放入DR寄存器,清除TX& q8 s  K. n9 Z3 p2 l
    //   I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];! M4 H" G1 c$ L' H2 k9 z& p4 Y, G# E
     //  if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;! K+ G1 B$ q. A* X, n7 P+ ^7 h
    1 h8 m" Z  P+ K; Y  B# S* U
    I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];( ^6 R. k1 C/ E2 p
    if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;
0 L1 \+ N% b5 }& N5 Y# `2 w7 n  }
5 y; x2 ~0 O* H2 H; E. w
" X- p/ s# z2 I4 v$ S( y+ @1 r" B3 q' V
  k+ F8 a$ |) |( O" E
7 w3 \0 U' D0 u

, B' O- M# H( C" W

评分

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