基于stm8调试硬件I2C经验分享 5 m6 L0 [/ m$ q/ l. |/ y 网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。 . D& J* J- C8 [% j 主机主函数:) r p3 C( Q/ l* j6 s3 n, |* e7 V I2C_MASTERMODE_Init(STANDARDSPEED); 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); while(1) { //I2C_Write(0x40,0x50,0x64); //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)); 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; I2C_RXCnt=0;' }1 n k4 ~- @' k) Z I2C_GenerateSTART(ENABLE); 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; 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! @ { switch(Event) {: ^5 @" N- q( w case 0X01: //起始条件已经发送 I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX); //发送从机地址 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 { I2C_TXCnt=0;% o7 l+ R5 l; {) i5 j I2C_ITConfig(I2C_IT_BUF, DISABLE); }, M" P4 N! D* { break; case 0X82: // 地址发送结束 5 n( R' I; S" g8 ]& n' [4 \2 ~" f // Nuse=I2C->SR3; I2C_TXCnt=0; I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; 6 L. Z( J' U0 b; ~/ m2 [8 ^ break; case 0x84: I2C_GenerateSTOP(ENABLE);% ~( P) J8 Q& a, u0 e$ T I2C_ITConfig(I2C_IT_EVT, DISABLE); //不能少 9 D5 |' T5 p6 H break;, V7 g S/ N/ i% ]* i" i3 I: B% \ default: break; . O4 n* I, b% H) w }3 l$ n$ y% B7 s( D( y } else //主接收 {$ t0 V8 }+ U) J5 C4 c! u$ |! c) ^ switch(Event) {: 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: //接收区满 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); I2C_GenerateSTOP(ENABLE); f0 I* C' [/ p/ v7 ?0 V) O6 A* @ } if(I2C_RXCnt>=14) {% 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; 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; break; 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 } 从机中断: unsigned 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 出现错误 { I2C->SR2&=0xf0;3 G c+ u4 o* v4 F; ?! {7 @- r //I2C->CR2|=1<<7; //I2C->CR2&=~(1<<7); RX_Cnt=0; I2C_Tx_Idx=0; }- 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 { (void)(I2C->SR3); //先读I2C_SR1,再读I2C_SR3,就可以清除ADDR // I2C->DR = 0X00;2 x9 Y c% Q4 p& O. r I2C_Tx_Idx=0; I2C_Rx_Idx=0; I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++]; } if(I2C->SR1&0X10) //停止条件4 H* I8 d; z' i% T% W6 } { Nuse = I2C->CR2; 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) {/ r9 Q' d5 u+ c) T: L Nuse=I2C->DR; // I2C->DR=Nuse;7 p( F; P" k" \. p L/ P } 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; if(I2C_Rx_Idx>=14) { I2C_Rx_Idx=0; } }2 @; u" l" D) w8 }0 b1 e if(I2C->SR1 & 0x80) {- 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++]; // if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0;2 b" |7 k l K8 Z7 i: H. ~3 ~4 I; Y 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 U) ?7 c* n ; S( ]% i; Q1 x" F+ e; F |
多谢分享,不过楼主发错板块了,下次注意 |
多谢分享,I2C有些难调 |
想问下楼主,I2C_TX是怎么处理的,多久去接收 |
应该是I2C_SR3的TRA位,对吧 |
楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗? |
STM8S103 SLAVE地址是自己在舒适化设置的 |
版主有QQ么?有问题想咨询下 |
感谢楼主分享! |
11111111111111111111111111111 |
多谢分享 还是软件模拟好用 |
谢谢分享 |