上图是TPS65987的i2c读写协议,和标准i2c协议有点出入,不过也不难理解,在读的时候i2c slave在发送数据过来之前会先发送1byte数据表示后面会有几个字节数据过来,在写的时候i2c host要先写1byte数据告诉i2c slave接下来会写几个bytes数据。

 Talk is cheap. Show me the code.

以下代码是基于STM8S。

/*******************************************************************************
**函数名称:void IIC_Read(unsigned char subaddr , unsigned char Byte_addr , unsigned char *buffer)
**功能描述:向IIC器件读数据
**入口参数:
subaddr : 从器件地址
Byte_addr : 确定从器件写地址的起始地址
*buffer : 读数据的缓冲区起始地址
**输出:无
*******************************************************************************/
void TPS65987_IIC_Read(unsigned char subaddr , unsigned char Byte_addr , unsigned char *buffer)
{
unsigned char i2csr1;
unsigned char DataLen; I2C_CR2_bit.ACK = ; //产生应答信号 I2C_CR2_bit.START = ; //发送起始信号
while(I2C_SR1_bit.SB == ); //等待起始信号产生
i2csr1 = I2C_SR1; //SR1.AF??
I2C_DR = subaddr; //发送器件地地址,并清除SB标志位
while(I2C_SR1_bit.ADDR == ); //等待器件地址发送完成
i2csr1 = I2C_SR1;
i2csr1 = I2C_SR3; //读状态寄存器1和状态寄存器3清除发送器件地址标志位
I2C_DR = Byte_addr;
while(I2C_SR1_bit.BTF == );//等待移位发送器发送完成
i2csr1 = I2C_SR1; //清除BIT标志位 //重新发送起始信号
I2C_CR2_bit.START = ;//I2C1->CR1 |= I2C_CR1_START;
while(I2C_SR1_bit.SB == );//等待起始信号产生 i2csr1 = I2C_SR1;//SR1.AF??
I2C_DR = (char)(subaddr | 0x01); //发送器件地地址,并清除SB标志位
while(I2C_SR1_bit.ADDR == ); //等待器件地址发送完成
i2csr1 = I2C_SR1;
i2csr1 = I2C_SR3; //读状态寄存器1和状态寄存器2清除发送器件地址标志位 while (I2C_SR1_bit.RXNE == ); //先读取Byte Count到DataLen
i2csr1 = I2C_SR1;
DataLen = I2C_DR; while(DataLen)
{
if(DataLen == )
{
I2C_CR2_bit.ACK = ; //最后一个字节不产生应答信号
I2C_CR2_bit.STOP = ; //发送停止信号结束数据传输
} while(I2C_SR1_bit.RXNE == );
i2csr1 = I2C_SR1; *buffer = I2C_DR;
buffer++;
DataLen--;
}
}
/*******************************************************************************
**函数名称:void IIC_Write(unsigned char subaddr , unsigned char Byte_addr , unsigned char *buffer , unsigned short num)
**功能描述:向IIC器件写数据
**入口参数:
subaddr : 从器件地址
Byte_addr : 确定器件写地址的起始地址
*buffer : 写数据的起址地址
num : 要写数据的个数
**输出:无
*******************************************************************************/
void TPS65987_IIC_Write(unsigned char subaddr , unsigned char Byte_addr , unsigned char *buffer , unsigned short num)
{
unsigned char i2csr1; //while(I2C1->SR2 & I2C_SR2_BUSY); //判断I2C模块是否忙 //发送起始信号
I2C_CR2_bit.START = ;
while(I2C_SR1_bit.SB == ); //等待起始信号产生
i2csr1 = I2C_SR1; //SR1.AF
I2C_DR = (subaddr); //发送从器件地址,并清除SB标志位
while(I2C_SR1_bit.ADDR == ); //等待器件地址发送完成
i2csr1 = I2C_SR1;
i2csr1 = I2C_SR3; //读状态寄存器1和状态寄存器3清除发送器件地址标志位 I2C_DR = Byte_addr; //发送从器件存储首地址
#if 1
while(I2C_SR1_bit.BTF == ); //等待移位发送器发送完成
i2csr1 = I2C_SR1; //清除BIT标志位
#else
while((I2C_SR1_bit.TXE) == );//数据寄存器为空,跳出循环继续运行
i2csr1 = I2C_SR1;
#endif
I2C_DR = (unsigned char)num; //把Byte Count先告诉给TPS65987
while(I2C_SR1_bit.BTF == );//等待移位发送器发送完成
i2csr1 = I2C_SR1; //清除BIT标志位
i2csr1 = I2C_DR; while(num > )
{
I2C_DR = *buffer; //发送器件存储首地址 while(I2C_SR1_bit.BTF == );//等待移位发送器发送完成
i2csr1 = I2C_SR1; //清除BIT标志位
i2csr1 = I2C_DR;
buffer++;
num--;
}
I2C_CR2_bit.STOP = ; //发送停止信号结束数据传输
}

这样就可以对TPS65987进行读写了。

上面的i2c读写函数没有加上timeout功能,如果不想在i2c通信不成功时一直阻塞的话,可以在while循环里面加上,例如:

unsigned int count = ;

while(I2C_SR1_bit.ADDR == )    //等待器件地址发送完成
{
if (++count > ) { //count大于6000立即返回
I2C_CR2_bit.STOP = ;
return;
}
}

注意:

从Windows下上位机工具也可以进行TPS65987的register读写,TPS65981_2_6_7_8 Application Customization 6.1.1上显示的i2c1地址为0x20, i2c2的地址为0x38;注意0x20/0x38是七位地址位的值,进行i2c读写时的地址要左移一位,即0x20/0x38 << 1等于0x40/0x70。

如果直接用地址0x20/0x38进行读写会怎么样呢,结果就是地址发过去没收到ACK。下图是用0x38地址去读寄存器值的时候示波器抓到的波形(黄色波形是SCL,粉红色波形是SDA)。

从波形上看0x38地址发过去是没有ACK的,所以slave地址0x38肯定是错误的了。

后面用示波器量了一下TPS65981_2_6_7_8 Application Customization 6.1.1上位机软件和TPS65987 EVM进行i2c读写时的波形,发现i2c2的地址发过去的确实是0x70。

最新文章

  1. Android图片处理
  2. wamp下多域名配置
  3. JavaScript表单编程
  4. Vim 中截取部分内容保存到其他文件
  5. 下雪了-js下雪效果
  6. VLD(Visual LeakDetector)内存泄露库的使用
  7. 关于cocos2d这个东西
  8. 解决secureCRT数据库里没有找到防火墙 &#39;无&#39;问题,转自:http://jingyan.baidu.com/article/9989c74601274bf649ecfe74.html
  9. Opencv探索之路(二十):制作一个简易手动图像配准工具
  10. 打开redis和solr
  11. LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】
  12. 关于spring aop Advisor排序问题
  13. 支持“xxxContext”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库
  14. IndentationError: expected an indented block 在继承中出现的问题:未完
  15. Charles 使用教程
  16. 【做题】spoj4060 A game with probability——dp
  17. C语言Win32 Application 的标题栏图标,任务栏图标,exe文件图标问题
  18. PAT甲题题解-1078. Hashing (25)-hash散列
  19. AIX用裸设备给表空间添加数据文件
  20. Java中final与 static final 修饰的常量的区别

热门文章

  1. Windows系统向Ubuntu传输文件
  2. MATLAB——nctoolbox安装及使用
  3. 原来rollup这么简单之 tree shaking篇
  4. 从火车站车次公示栏来学Java读写锁
  5. Python——五分钟理解函数式编程与闭包
  6. 看完这篇Exception 和 Error,和面试官扯皮就没问题了
  7. 浅谈Java接口(Interface)
  8. postman 参数传递
  9. 【PHP】流程控制
  10. flask-include、set、with、模板继承