使用STM8S i2c对TPS65987寄存器进行读写

上图是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寄存器进行读写的更多相关文章
- MSP430的IO口模拟I2C总线对AT24C25进行读写程序
功能: 实现MSP430口线模拟I2C总线协议与24C04通信. ** 描述: 主系统工作时钟为12MHz,I2C工 ...
- Linux I2C总线设备驱动模型分析(ov7740)
1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...
- Linux下读写芯片的I2C寄存器
要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章<手把手教你写Linux I2C设备驱动>已经做了初 ...
- 第23章 I2C—读写EEPROM—零死角玩转STM32-F429系列
第23章 I2C—读写EEPROM 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/f ...
- [RK3288][Android6.0] 调试笔记 --- pmu(rk818)寄存器读写【转】
本文转载自:http://blog.csdn.net/kris_fei/article/details/76919134 Platform: Rockchip OS: Android 6.0 Kern ...
- i2c总线,设备,驱动之间的关系
------ 总线上先添加好所有具体驱动,i2c.c遍历i2c_boardinfo链表,依次建立i2c_client, 并对每一个i2c_client与所有这个线上的驱动匹配,匹配上,就调用这个驱动的 ...
- Linux设备驱动模型之I2C总线
一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,提供了与具体硬件无关的I2C读写函数. (2)I2 ...
- Linux+I2C总线分析(主要是probe的方式)
Linux I2C 总线浅析 ㈠ Overview Linux的I2C体系结构分为3个组成部分: ·I2C核心: I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法,I2C通信方法(即“algo ...
- IMX6 PCA9698应用层读写库
.c #include <stdio.h> #include <string.h> #include <linux/types.h> #include <st ...
随机推荐
- 【强烈推荐】适合Flutter初学者的完整项目
简介 Flutter Fly是什么?Flutter Fly是一款开源的Flutter 项目,非常适合初学者进行学习.App内集成了160+Flutter基础控件的详细介绍及用法,内容来源于:http: ...
- 数据源管理 | 基于JDBC模式,适配和管理动态数据源
本文源码:GitHub·点这里 || GitEE·点这里 一.关系型数据源 1.动态数据源 动态管理数据源的基本功能:数据源加载,容器维护,持久化管理. 2.关系型数据库 不同厂商的关系型数据库,提供 ...
- 用python写项目之图书管理系统
1.功能介绍: (1).添加新书:输入要添加的书名.存放的书架号.价格. (2).修改书架:输入要书名,然后对其修改书架号.价格 (3).删除书架:输入书名,然后对应删除书名.书架号.价格 (4).查 ...
- markdown中锚链接实现目录跳转以及注意事项
当文章有分类,需要快速阅读,通常会先在文首部写一个目录,点击可以跳转. 为文章写目录,特别在文章较长的时候,有助于对内容的整体把握,能提高阅读效率. 以下,将写一个基本的锚目录demo,然后特别说明需 ...
- 关于AUI框架自学心得
2018年8月25日今天星期六,这段时间接触到移动端布局框架AUI,借着早上一个小时时间大致看了一下开发文档(后面统称文档),对AUI一点认识. 目前2.0版本为最新版,这个版本和1.0比较升级很多. ...
- django禁用csrf
django禁用csrf 函数试图 from django.views.decorators.csrf import csrf_exempt @csrf_exempt def your_func_vi ...
- flask入门 之 Python Shell (三)
1.代码: #encoding:utf-8 from flask_sqlalchemy import SQLAlchemy from flask_script import Manager,Shell ...
- 盘点一下Github上开源的编程面试/学习相关的仓库
转载自:JavaGuide 最近浏览 Github ,收藏了一些还算不错的 Java面试/学习相关的仓库,分享给大家,希望对你有帮助.我暂且按照目前的 Star 数量来排序. 本文由 SnailCli ...
- 34.3 转换流 InputStreamReader OutStreamReader
转换流: 把字节输出流转换成字符输出流 标准输入输出流:传输的对象是字节流 System.in . System.out 标准输入输出流 public static final InputStream ...
- C# 发布时出现:在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误
在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接. (provider: SQL ...