上图是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。

使用STM8S i2c对TPS65987寄存器进行读写的更多相关文章

  1. MSP430的IO口模拟I2C总线对AT24C25进行读写程序

    功能: 实现MSP430口线模拟I2C总线协议与24C04通信.                                           ** 描述: 主系统工作时钟为12MHz,I2C工 ...

  2. Linux I2C总线设备驱动模型分析(ov7740)

    1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...

  3. Linux下读写芯片的I2C寄存器

    要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章<手把手教你写Linux I2C设备驱动>已经做了初 ...

  4. 第23章 I2C—读写EEPROM—零死角玩转STM32-F429系列

    第23章     I2C—读写EEPROM 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...

  5. [RK3288][Android6.0] 调试笔记 --- pmu(rk818)寄存器读写【转】

    本文转载自:http://blog.csdn.net/kris_fei/article/details/76919134 Platform: Rockchip OS: Android 6.0 Kern ...

  6. i2c总线,设备,驱动之间的关系

    ------ 总线上先添加好所有具体驱动,i2c.c遍历i2c_boardinfo链表,依次建立i2c_client, 并对每一个i2c_client与所有这个线上的驱动匹配,匹配上,就调用这个驱动的 ...

  7. Linux设备驱动模型之I2C总线

    一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,提供了与具体硬件无关的I2C读写函数. (2)I2 ...

  8. Linux+I2C总线分析(主要是probe的方式)

    Linux I2C 总线浅析 ㈠ Overview Linux的I2C体系结构分为3个组成部分: ·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法,I2C通信方法(即“algo ...

  9. IMX6 PCA9698应用层读写库

    .c #include <stdio.h> #include <string.h> #include <linux/types.h> #include <st ...

随机推荐

  1. NSArray、NSDictionary

    一.NSDictionary 1.1 使用自定义对象 key Dictionaries manage pairs of keys and values. A key-value pair within ...

  2. sql 数据库操作语句 不带select

    MySQL数据操作语句 1.总纲 DDL -数据定义语句** create/drop/alter ** create: 创建 drop:删除 alter:修改 DML -数据操作语句 ** inser ...

  3. 作为 attribute 和 property 的 value 及 Vue.js 的相关处理

    attribute 和 property 是 Web 开发中,比较容易混淆的概念,而对于 value,因其特殊性,更易困惑,本文尝试做一下梳理和例证 attribute 和 property 的概念 ...

  4. Axure RP闪退问题

    Axure RP 在mac 环境,当时安装的是8.好久没用了,最近打开,一开就闪退. 网上找了一下,显示的都是各种文件夹没权限的问题,实验了一下不管用. /Applications/develop/A ...

  5. 当阿里面试官问我:Java创建线程有几种方式?我就知道问题没那么简单

    这是最新的大厂面试系列,还原真实场景,提炼出知识点分享给大家. 点赞再看,养成习惯~ 微信搜索[武哥聊编程],关注这个 Java 菜鸟. 昨天有个小伙伴去阿里面试实习生岗位,面试官问他了一个老生常谈的 ...

  6. Vertica的这些事(十三)——Vertica备份元数据信息

    ---备份资源池 SELECT 'CREATE RESOURCE POOL ' || name || CASE WHEN memorysize IS NULL THEN ' ' ELSE ' MEMO ...

  7. 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统··········

    网上百度了下,解决方案是: 1. 以管理员身份运行PowerShell2. 执行:get-ExecutionPolicy,回复Restricted,表示状态是禁止的3.执行:set-Execution ...

  8. pinpoint配置使用

    一.下载pinpoint包 从https://github.com/naver/pinpoint/releases 下载 pinpoint-agent.tar.gz pinpoint-collecto ...

  9. Redis 练习(二)

    需求: 为购物网站实现登录状态及浏览记录的维护 进入时检查 token 是否已登录 每次进入更新 token 最新进入时间 记录用户浏览的商品信息(最多 25 个) 定时检查 token 数量,如果超 ...

  10. 尝试用tornado部署django

    import os from tornado.options import options, define from tornado import httpserver from tornado.io ...