
基于stm8调试硬件I2C经验分享 网上都说STM8的硬件I2C 不好用 有BUG之类的。而我因为项目需要,用stm8硬件 I2C 中断方式 发送/接收数据,经过查阅手册和反复验证,已经完成了,话不多说,上代码。 主机主函数: I2C_MASTERMODE_Init(STANDARDSPEED); I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE); rim(); delay_ms(6000); // while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); // I2C_GenerateSTART(ENABLE); while(1) { //I2C_Write(0x40,0x50,0x64); //I2C_EEPROM_WriteOneByte(0x42,Cnt); //I2C_Write(0x40,Cnt,0x58); // Cnt++; while (I2C_GetFlagStatus(I2C_FLAG_BUSBUSY)); I2C_ITConfig(I2C_IT_ERR|I2C_IT_EVT|I2C_IT_BUF,ENABLE); I2C_AcknowledgeConfig(I2C_ACK_CURR); I2C_TXCnt=0; I2C_RXCnt=0; I2C_GenerateSTART(ENABLE); delay_ms(3000); } 主机中断部分: unsigned char Nuse; unsigned char Event; Event=I2C->SR1; //数据无错位 Nuse=I2C->SR3; if(I2C_TX) //主发送 { switch(Event) { case 0X01: //起始条件已经发送 I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_TX); //发送从机地址 break; case 0x80: //发送区空 I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; if(I2C_TXCnt>=14) { I2C_TXCnt=0; I2C_ITConfig(I2C_IT_BUF, DISABLE); } break; case 0X82: // 地址发送结束 // Nuse=I2C->SR3; I2C_TXCnt=0; I2C->DR=I2C_TXBuffer[I2C_TXCnt++]; break; case 0x84: I2C_GenerateSTOP(ENABLE); I2C_ITConfig(I2C_IT_EVT, DISABLE); //不能少 break; default: break; } } else //主接收 { switch(Event) { case 0X01: //起始条件已经发送 I2C_Send7bitAddress(SLAVE_ADDRESS, I2C_DIRECTION_RX); //发送从机地址 break; case 0x40: //接收区满 I2C_RXBuffer[I2C_RXCnt++]=I2C->DR; if(I2C_RXCnt==13) { I2C_AcknowledgeConfig(I2C_ACK_NONE); I2C_GenerateSTOP(ENABLE); } if(I2C_RXCnt>=14) { I2C_RXCnt=0; } break; case 0X42: // 地址发送结束 // Nuse=I2C->SR3; I2C_RXCnt=0; Nuse=I2C->DR; break; case 0x44: //I2C_GenerateSTOP(ENABLE); I2C_ITConfig(I2C_IT_EVT, DISABLE); //不能少 default: break; } } 从机中断: unsigned char Add; unsigned char Nuse; static unsigned char RX_Cnt=0; if(I2C->SR2&0X0F) //I2C 出现错误 { I2C->SR2&=0xf0; //I2C->CR2|=1<<7; //I2C->CR2&=~(1<<7); RX_Cnt=0; I2C_Tx_Idx=0; } 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; } if(I2C->SR1 & 0x40) { Slave_Buffer_Rx[I2C_Rx_Idx++]=I2C->DR; if(I2C_Rx_Idx>=14) { I2C_Rx_Idx=0; } } if(I2C->SR1 & 0x80) { //将发送的数据放入DR寄存器,清除TX // I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++]; // if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0; I2C->DR = Slave_Buffer_Tx[I2C_Tx_Idx++]; if(I2C_Tx_Idx>=14)I2C_Tx_Idx=0; } |
多谢分享,不过楼主发错板块了,下次注意 |
多谢分享,I2C有些难调 |
想问下楼主,I2C_TX是怎么处理的,多久去接收 |
应该是I2C_SR3的TRA位,对吧 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() ![]() |
楼主这个是8S还是8L,可否告知作为slave时的地址?是自己任意设置吗? |
STM8S103 SLAVE地址是自己在舒适化设置的 |
版主有QQ么?有问题想咨询下 |
感谢楼主分享! |
11111111111111111111111111111 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
多谢分享 还是软件模拟好用 |
谢谢分享 |