|
基于stm8调试硬件I2C经验分享 网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。% S* H" Z) X6 I% j* h 7 A2 N/ |+ V* {5 a4 I9 S) P1 ^$ E 主机主函数: 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(); delay_ms(6000); // while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); // I2C_GenerateSTART(ENABLE); 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++; while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE); 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); } % k/ P% H7 H' ~3 j5 H7 v ( n& ~- d/ K) c {$ Q% z- v9 n, O, T 主机中断部分: unsigned char Nuse; 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 { 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; case 0x80: //发送区空 I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; ( I5 I9 d# b" o if(I2C_TXCnt>=14) { I2C_TXCnt=0;' @3 t4 R. h# w) [# h8 q I2C_ITConfig(I2C_IT_BUF, DISABLE); }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; I2C_TXCnt=0;, {7 J( ?/ M6 s7 {: F0 Q) X I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; break; 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); //不能少 2 _3 b& y& |1 V7 v break;( L9 R' o0 w7 n( Q N' S default: break; 2 s0 ^- u( t# | } }9 s3 _' Z& ?/ x$ D+ X else //主接收 { switch(Event) {5 n3 s2 ^4 A9 w/ B1 V4 T" m/ @ F case 0X01: //起始条件已经发送 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: //接收区满 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 } 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: // 地址发送结束 // Nuse=I2C->SR3;9 T6 Q" R+ p& C5 }/ ` I2C_RXCnt=0;! | D* k7 u7 R! s Nuse=I2C->DR; break;: {+ J2 Z. @: B9 Z8 l& @5 J case 0x44: //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: break; } }5 u7 |2 F+ P! y' \9 l7 x 从机中断:0 z9 G H" A# h unsigned char Add; unsigned char Nuse;. E0 F. n$ ]3 Y' {! R static unsigned char RX_Cnt=0; C# P2 i# p& _1 S if(I2C->SR2&0X0F) //I2C 出现错误 { 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; I2C_Tx_Idx=0; } u( y& I1 ?% W, F( N : J' ?/ \$ G0 T. i8 r if(I2C->SR1&0X02) //地址匹配 { (void)(I2C->SR3); //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR // I2C->DR = 0X00;! D0 S# P6 f5 i! y I2C_Tx_Idx=0; I2C_Rx_Idx=0; I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++]; } 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(); I2C->CR2 = Nuse; }" T- G% r r- m o9 D9 [' b if(I2C->SR1&0X04) {! 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) { Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR; 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; } } if(I2C->SR1 & 0x80) {/ s E5 Z2 j% C* W* g, ~7 c //将发送的数据放入DR寄存器,清除TX // 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++]; if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0; } 7 O% g- C/ j Y3 N9 p) Y4 a: u& z % @1 L# A, I+ b2 M $ d9 u! q: b1 z |
| 多谢分享,不过楼主发错板块了,下次注意 |
| 多谢分享,I2C有些难调 |
| 想问下楼主,I2C_TX是怎么处理的,多久去接收 |
| 应该是I2C_SR3的TRA位,对吧 |
![]() ![]() ![]() ![]() ![]() ![]() |
|
| 楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗? |
| STM8S103 SLAVE地址是自己在舒适化设置的 |
| 版主有QQ么?有问题想咨询下 |
| 感谢楼主分享! |
| 11111111111111111111111111111 |
![]() ![]() ![]() ![]() ![]() ![]() |
| 多谢分享 还是软件模拟好用 |
| 谢谢分享 |
微信公众号
手机版