基于stm8调试硬件I2C经验分享 8 q' M, K0 U( v - \' U! J3 e5 `8 o3 H 网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。 " c) g, E/ I% p 主机主函数: I2C_MASTERMODE_Init(STANDARDSPEED); I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE); 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)); // 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); // 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); I2C_TXCnt=0; I2C_RXCnt=0; I2C_GenerateSTART(ENABLE);3 l( I% ]* z) u$ h delay_ms(3000); ( L: c* U5 M- @2 }; x } 主机中断部分: 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; if(I2C_TX) //主发送 {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; case 0x80: //发送区空 I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; 3 {3 ?. A* n* T x; g if(I2C_TXCnt>=14)" P9 k) c- L! B- v { I2C_TXCnt=0; I2C_ITConfig(I2C_IT_BUF, DISABLE); }& O$ n) C% a1 i6 G, `' S break; case 0X82: // 地址发送结束 // Nuse=I2C->SR3; 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: 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: break; } } else //主接收 {: k" `" B0 a" d switch(Event) { case 0X01: //起始条件已经发送 I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX); //发送从机地址( u2 d( }0 H3 q8 c: Z8 d& u break; case 0x40: //接收区满 I2C_RXBuffer[I2C_RXCnt++]=I2C->DR; 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); } if(I2C_RXCnt>=14) { I2C_RXCnt=0; }) C# j W9 N* [9 t. s4 ? break;+ t9 R- o% d4 P7 t$ F' {+ ], N case 0X42: // 地址发送结束 // Nuse=I2C->SR3; I2C_RXCnt=0; Nuse=I2C->DR;9 N) \ C* B5 @. F/ t8 Y break; case 0x44: //I2C_GenerateSTOP(ENABLE); I2C_ITConfig(I2C_IT_EVT, DISABLE); //不能少6 w& p5 m3 x) n8 h9 u" v default: 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; static unsigned char RX_Cnt=0;) }0 O# @3 r \% w* E& M7 G if(I2C->SR2&0X0F) //I2C 出现错误! v- D5 e* x- i { I2C->SR2&=0xf0; //I2C->CR2|=1<<7;5 ~: K$ p, x! m2 r8 h //I2C->CR2&=~(1<<7); RX_Cnt=0;# I) G1 r! p) E o/ b I2C_Tx_Idx=0; } / ^- u& w' h; W$ A7 j# f if(I2C->SR1&0X02) //地址匹配 { (void)(I2C->SR3); //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR // I2C->DR = 0X00; I2C_Tx_Idx=0; I2C_Rx_Idx=0; I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++]; } if(I2C->SR1&0X10) //停止条件 { Nuse = I2C->CR2; nop(); I2C->CR2 = Nuse; } if(I2C->SR1&0X04) { Nuse=I2C->DR; // I2C->DR=Nuse;0 h0 B7 V! X/ \: m! s6 }6 i } 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/ \ { I2C_Rx_Idx=0; } } if(I2C->SR1 & 0x80) { //将发送的数据放入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; } + @1 r" B3 q' V k+ F8 a$ |) |( O" E 7 w3 \0 U' D0 u |
多谢分享,不过楼主发错板块了,下次注意 |
多谢分享,I2C有些难调 |
想问下楼主,I2C_TX是怎么处理的,多久去接收 |
应该是I2C_SR3的TRA位,对吧 |
楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗? |
STM8S103 SLAVE地址是自己在舒适化设置的 |
版主有QQ么?有问题想咨询下 |
感谢楼主分享! |
11111111111111111111111111111 |
多谢分享 还是软件模拟好用 |
谢谢分享 |