野火32IIC串口协议
现在的我对协议的一些理解:协议分为好几层,像TCP协议分为六层,IIC分为两层。物理层,我们只能了解,不能改变。我们主要了解的是协议层,并根据协议层来实现我们想要的功能。如协议层过程中哪些寄存器的改变是要注意,并用库函数来改变这些寄存器以辅助我们编程。对底层的了解是很重要的,不然的话,编程会受到一些阻碍
IIC协议的物理层和协议层不再赘述,网上有很多资源。这篇博客的重点是在编程过程中提示犯迷糊的点。
以下是零死角玩转STM32的例程里面的一个函数
bsp_i2c_ee.c
uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
{
/* Send STRAT condition */
I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV5 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);
}
I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Send EEPROM address for write */
I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);
/* Test on EV6 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);
}
/* Send the EEPROM's internal address to write to */
I2C_SendData(EEPROM_I2Cx, WriteAddr);
I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
}
/* Send the byte to be written */
I2C_SendData(EEPROM_I2Cx, *pBuffer);
I2CTimeout = I2CT_FLAG_TIMEOUT;
/* Test on EV8 and clear it */
while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
}
/* Send STOP condition */
I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);
return 1;
}
上面的函数,对应的逻辑是以下的图,对应的事件对应的函数已在图中标出来。
可以看到里面的调用的函数基本一样,但是函数参数不一样,对应的事件也就不同。我认为这是IIC编程的关键。其他是很多是硬件的配置。
回调函数
说一下我对回调函数的理解。
举例上面是上面有六个层次,按照正常原则上层的依赖下层,下层不依赖上层。但是有时候下层会依赖上层来实现功能。这是就是回调函数。
如业务层依赖数据库来实现功能,但是有时候数据库也要依赖业务层实现功能。虽然说数据库要完成很多数据查找,但是无法覆盖的业务查询,所以此时数据库就要调用业务层的函数。这个现象叫回调,所以这种函数叫做回调函数。
本文转载布尔青年: http://blog.bools.cn/archives/624
版权声明:本文为weixin_52589726原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。