|
基于stm8调试硬件I2C经验分享 4 W' x% X" f$ X; X ! h" ^' g( T9 O2 L- T6 Q 网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。 : H {7 [/ U1 P( C. V- ~! B 主机主函数:: f& O5 N, U" e/ A1 O8 N& ~7 t. o; B I2C_MASTERMODE_Init(STANDARDSPEED); I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE); rim();+ k3 [! H1 M: F! ~- ?; R! d delay_ms(6000);6 `* J( v9 X! X' c/ U0 l // while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); // I2C_GenerateSTART(ENABLE);% T& y0 b" Y7 s# `7 t$ E3 h while(1)* L' S6 }/ M$ o l& m7 Q! D& J { //I2C_Write(0x40,0x50,0x64);' E& `: v. X: K7 A6 k2 r //I2C_EEPROM_WriteOneByte(0x42,Cnt); //I2C_Write(0x40,Cnt,0x58); // Cnt++;% ^% ^ k! ]' x while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE);$ ]4 |# C$ I' k; b& B" v I2C_AcknowledgeConfig(I2C_ACK_CURR); I2C_TXCnt=0; I2C_RXCnt=0;2 }( B% h5 e, J Z! u I2C_GenerateSTART(ENABLE);/ Q4 q7 ?0 J# e8 S7 ? delay_ms(3000); } 2 w2 a% x) k' y 主机中断部分:/ Y( _4 G) u( C1 z5 R! r unsigned char Nuse; 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 { switch(Event) {' C1 D& O- i, B5 C/ J5 V case 0X01: //起始条件已经发送4 O# }/ V, N9 E3 {# }2 e I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX); //发送从机地址 break;/ R8 n9 A- Q/ Y/ _( X- U case 0x80: //发送区空 I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; if(I2C_TXCnt>=14) { I2C_TXCnt=0;7 k3 j% B' Q1 i0 ~, R I2C_ITConfig(I2C_IT_BUF, DISABLE); }+ j; T" w6 o, p. L. c3 J break; case 0X82: // 地址发送结束 // Nuse=I2C->SR3; I2C_TXCnt=0; I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; break; case 0x84: I2C_GenerateSTOP(ENABLE);% D' B% B4 M- f, B I2C_ITConfig(I2C_IT_EVT, DISABLE); //不能少 + J4 z; V7 L& Y: I T break; default:( S5 G! _' B5 V+ ^8 ?% I( w break; }# w. B6 R1 C* A l( j2 G } 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); //发送从机地址 break;; l# D5 ^ m2 v7 [ case 0x40: //接收区满 I2C_RXBuffer[I2C_RXCnt++]=I2C->DR; if(I2C_RXCnt==13)/ C% @2 J x3 f7 ~8 l9 B { I2C_AcknowledgeConfig(I2C_ACK_NONE); 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; } break; case 0X42: // 地址发送结束 // Nuse=I2C->SR3; I2C_RXCnt=0; Nuse=I2C->DR; break;1 B! }) Y5 @, _' L3 z case 0x44: //I2C_GenerateSTOP(ENABLE);+ J+ \$ `: J/ F9 Z2 L. \% I3 g, z I2C_ITConfig(I2C_IT_EVT, DISABLE); //不能少 default: break; 4 V1 L- h3 B) x- r" u5 D' b }0 v3 n" c1 G8 }# I/ F$ m2 n. ?4 Y } 从机中断:+ r- l) m+ `: U7 T0 N: Z9 a2 v7 {8 J unsigned char Add; unsigned char Nuse; static unsigned char RX_Cnt=0; if(I2C->SR2&0X0F) //I2C 出现错误 {2 j: `3 J' B) k; U; Y I2C->SR2&=0xf0; //I2C->CR2|=1<<7; //I2C->CR2&=~(1<<7); RX_Cnt=0;1 ^; |. d2 o! n9 |" h, _3 ~5 m I2C_Tx_Idx=0; } ) v) C2 Y. L( K& g" z7 _" v if(I2C->SR1&0X02) //地址匹配 { (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; I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++]; } if(I2C->SR1&0X10) //停止条件 { 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; // I2C->DR=Nuse;/ g6 T3 [' Y0 r& j- r1 W } if(I2C->SR1 & 0x40) {) 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 { I2C_Rx_Idx=0;) C K% Q4 s' x6 a) z } } 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++]; // if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;7 \) Z/ U& I# p" ^ I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++];& _: j8 _, B2 ^3 J5 ?. g6 m6 W if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0; }1 o' x6 ^* J& t4 p! k9 `+ f; Y0 J 5 m: s. n' s8 S0 r/ I5 B ) _8 R! K2 z ?( z & Y- m7 ]4 S0 b* k, d2 Y |
| 多谢分享,不过楼主发错板块了,下次注意 |
| 多谢分享,I2C有些难调 |
| 想问下楼主,I2C_TX是怎么处理的,多久去接收 |
| 应该是I2C_SR3的TRA位,对吧 |
![]() ![]() ![]() ![]() ![]() ![]() |
|
| 楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗? |
| STM8S103 SLAVE地址是自己在舒适化设置的 |
| 版主有QQ么?有问题想咨询下 |
| 感谢楼主分享! |
| 11111111111111111111111111111 |
![]() ![]() ![]() ![]() ![]() ![]() |
| 多谢分享 还是软件模拟好用 |
| 谢谢分享 |
微信公众号
手机版