之前集成外设需要用到STM8的IIC,从网上找例程,以及参考STM32的代码,用了IO口模拟IIC,代码调通了,功能也实现了,正在被测试爸爸们疯狂“虐待”,但仔细研究了STM8的功能发现他的硬件IIC好像比32的靠谱些,本着刻苦钻研不信邪的精神(实际是没事找事)又用STM8的硬件IIC写了程序,功能也是可以实现的,自己初步测试没发现啥问题和bug,也许是因为测试时间太短,bug还没有发现,准备自己测试一段时间再交给测试爸爸们去“虐待”,本人能力有限,就简单说下调试过程抛砖引玉,有错误和不足的地方也欢迎大家指正。
库函数和参考手册官网都能找到。
首先,IIC一定要加上拉电阻,IIC的管脚是纯开漏引脚,纯开漏引脚输出0时为低,输出1为高阻态,而非高电平,因此不加上拉电阻硬件IIC是肯定调不通的,另外也需要注意上拉电压,如果电压不够,也会出问题。
另外STM8通过SR1和SR3寄存器的状态判断I2C的情况,因此有时候IIC卡住调不通很可能就是因为寄存器状态不对。硬件IIC的ack应答是自动发送,不需要像模拟IIC那样每次都发。详细代码如下:
void I2C_WriteOneByte(u8 WriteAddr)
{
I2C_GenerateSTART(ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(MS561101BA_SlaveAddress, I2C_DIRECTION_TX);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_SendData(WriteAddr);
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(ENABLE);
}
void I2C_ReadBuffer(u8* pBuffer,u8 ReadAddr,u8 NumByteToRead)
{
while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));
I2C_GenerateSTART(ENABLE);
while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(MS561101BA_SlaveAddress , I2C_DIRECTION_TX);
while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
I2C_SendData(ReadAddr);
while (!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(ENABLE);
while (!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(MS561101BA_SlaveAddress, I2C_DIRECTION_RX);
while (!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED);
while(NumByteToRead)
{
if(NumByteToRead == 1)
{
I2C_AcknowledgeConfig(I2C_ACK_NONE);
I2C_GenerateSTOP(ENABLE);
}
if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
{
*pBuffer = I2C_ReceiveData();
pBuffer++;
NumByteToRead--;
}
}
I2C->CR2 |= 0x04;
}
|