CH341StreamI2C参数解释

总体思路:

第一步:使用EEPROM写入相应的数据 

第二步:使用EEPROM读取相应的数据

第三步:使用CH341StreamI2C函数还原读取过程

每一步需要逻辑分析仪进行对比。

第一步:数据写入CH341WriteEEPROM

使用CH341WriteEEPROM写入数据,操作界面如下图:

逻辑分析仪捕获波形:

 波形分析:

第一字节0x50对应24c16的地址(7位地址)(如果是8位地址对应的应该是0xA0)

第二字节0x00写地址

第3,4,5,6字节对应需要写入的数据。

第二步:数据读取CH341ReadEEPROM

使用CH341ReadEEPROM数据读取

此处多读取了一个字节(上面写入4个字节此处读取5个字节)操作界面如下

逻辑分析仪捕获波形

 波形分析

参考上面的波形分析,只是这里先写入了地址、寄存器地址、再读取地址,之后跟着数据。

注意此顺序在后续的CH341StreamI2C函数有对应关系。

第三步:使用CH341StreamI2C读取数据

使用CH341StreamI2C读取

使用CH341StreamI2C读取地址0xA0(8位地址,实际上是7位0x50地址运算后的值),寄存器地址0x02(此处不是从第0个寄存器读取),长度2对应的是数据长度

如果是那种寄存器地址需要2个字节的则此处长度应该修改位3(要给地址+两个寄存器地址)

逻辑分析仪捕获波形:

波形分析:

第一个字节对应写入长度的第一个字节(下图中蓝色部分)

第二个字节对应下图中蓝色部分

第三个字节对应的还是地址

也就是说读取时自动发送第一个写入字节作为地址。

后面的5个字节时读取的数据字节

此处对应的实际值下图中蓝色部分

使用举例读取LM75A的温度数据

实际读取效果

为了简化此处直接使用函数每个参数直接赋值的方式进行数据读取

使用的代码如下

关键设置点代码

            m_swrdatalen = "2";// this.textBox_I2CSWRLen.Text;//写数据长度
            m_srddatalen = "2";// this.textBox_I2CSRDLen.Text;//读数据长度
            m_swrdatabuf = "9000";// this.textBox_I2CSWRDATA.Text;//写数据内容

代码解释 

m_swrdatalen = "2"; 读取温度时需要写入的两个字节(地址(i2c元器件8位表示的地址),以及寄存器地址)

m_swrdatabuf = "9000" 写入波形的前两个字节。(一个器件地址,一个寄存器地址)

m_srddatalen = "2";  读取的数据长度

完整代码

完整代码如下:(此处只是对LM75的读取处理,对于设备初始化等信息,参考官方完整代码,此处只是对CH341StreamI2C函数的参数进行解释)


        private void button_ReadLM75A_Click(object sender, EventArgs e)
        {
            ReadLM75A();
        }

        public void ReadLM75A()
        {
            UInt32 mwlen = 0, mrlen = 0;
            UInt32 k = 0;
            UInt32 i = 0;
            byte[] wrdatabuf;
            byte[] mwBuf = new byte[CH341DLL.mMAX_BUFFER_LENGTH * 2];
            byte[] wbuffer = new byte[CH341DLL.mMAX_BUFFER_LENGTH];
            byte[] rbuffer = new byte[CH341DLL.mMAX_BUFFER_LENGTH];
            string m_swrdatalen, m_srddatalen, m_swrdatabuf, m_srddatabuf;

            m_swrdatalen = "2";// this.textBox_I2CSWRLen.Text;//写数据长度
            m_srddatalen = "2";// this.textBox_I2CSRDLen.Text;//读数据长度
            m_swrdatabuf = "9000";// this.textBox_I2CSWRDATA.Text;//写数据内容
            m_srddatabuf = "";//待读取的数据
            mwlen = mStrToBcd(m_swrdatalen); //写入数据长度
            mrlen = mStrToBcd(m_srddatalen); //读取数据长度
            if (mwlen == 0 && mrlen == 0)
            {
                MessageBox.Show("请输入长度", "CH341");
                return;
            }
            else if ((m_swrdatabuf.Length) == 0 && (mwlen > 0))
            {
                MessageBox.Show("请输入要写入的数据", "CH341");
                return;
            }
            else if (mrlen < 0)
            {
                MessageBox.Show("请输入读数据的长度", "CH341");
                return;
            }
            if (mwlen >= 0x400 || mrlen >= 0x400)
            {
                MessageBox.Show("请输入小于0x400的长度", "CH341");
                return;
            }
            if (mwlen > (m_swrdatabuf.Length) / 2)
                mwlen = Convert.ToUInt32((m_swrdatabuf.Length) / 2);//在输入长度和数据长度中取小值
            wrdatabuf = Encoding.Default.GetBytes(m_swrdatabuf);
            mem_cpy(mwBuf, 0, wrdatabuf, 0, mwlen * 2);
            mem_cpy(wbuffer, 0, mStrtoVal(mwBuf, mwlen * 2), 0, mwlen);
            if (m_open)
            {
                try
                {
                    if (!CH341DLL.CH341StreamI2C(mIndex, mwlen, wbuffer, mrlen, rbuffer))
                    {
                        this.textBox_I2CSWRLen.Text = k.ToString("x");
                        this.textBox_I2CSRDLen.Text = k.ToString("x");     //返回已读写的数据个数
                        MessageBox.Show("流模式读写数据失败!", "CH341");
                    }
                    else   //发送成功
                    {
                        //this.textBox_I2CSWRLen.Text = mwlen.ToString("x");
                        //this.textBox_I2CSRDLen.Text = mrlen.ToString("x");     //返回已读写的数据个数

                        log(" 读取成功 ");
                        log("写入数据长度 " + mwlen.ToString("x"));
                        log("读取数据长度 " + mrlen.ToString("x"));


                        for (i = 0; i < mrlen; i++)
                        {
                            m_srddatabuf += rbuffer[i].ToString("x2").ToUpper() + " ";//两位十六进制数加一个空格
                        }
                        //this.richTextBox_LM75A.Text = m_srddatabuf;
                        log(" 读取的16进制数据 "+m_srddatabuf);
                        log(" 读取的温度数据   "+(LM75A(rbuffer[0] * 256 + rbuffer[1])).ToString("f3")+ "℃");
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                    return;
                }
            }
            else
            {
                MessageBox.Show("设备未打开!");
            }
        }

        private void log(string msg)
        {
            this.richTextBox_LM75A.AppendText("\r\n" + DateTime.Now.ToString("HH:mm:ss:fff") + " -> " +  msg);
        }

        private float LM75A(int zhi)
        {
            return (float)zhi / 32 * 5 / 4/10;

        }

LM75A读取波形

 一次读取的数据(蓝色部分)

本次读取对应的波形

总结:

对于CH341StreamI2C函数的数据读取时写入的字节也是需要设置的(对应设置元器件地址,以及寄存器地址)

 特此记录

anlog

2024年1月4日

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/290679.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

性能测试之Mysql数据库调优

一、前言 性能调优前提&#xff1a;无监控不调优&#xff0c;对于mysql性能的监控前几天有文章提到过&#xff0c;有兴趣的朋友可以去看一下 二、Mysql性能指标及问题分析和定位 1、我们在监控图表中关注的性能指标大概有这么几个&#xff1a;CPU、内存、连接数、io读写时间…

【网络安全】【密码学】常见数据加(解)密算法及Python实现(一)

一、Base64编码 1、算法简介 Base64是一种常见的编&#xff08;解&#xff09;码方法&#xff0c;用于传输少量二进制数据。该编码方式较为简短&#xff0c;并不具有可读性&#xff0c;对敏感数据可以起到较好的保护作用。 2、Python实现&#xff08;调库&#xff09; &…

每日一道算法题day-one(备战蓝桥杯)

从今天开始博主会每天做一道算法题备战蓝桥杯&#xff0c;并分享博主做题的思路&#xff0c;有兴趣就加入我把&#xff01; 算法题目&#xff1a; 有一个长度为 N 的字符串 S &#xff0c;其中的每个字符要么是 B&#xff0c;要么是 E。 我们规定 S 的价值等于其中包含的子…

C++模板(泛型)

1. 模板 1.1 知识点 模板&#xff1a;template 泛型编程&#xff1a; 是指数据的类型是广泛&#xff0c;任意的数据类型 模板&#xff1a;可以将一个函数或类描述成一个模板&#xff0c;例如&#xff1a;画画&#xff0c;给一个人物模型上色彩&#xff0c;根据用户上的色彩是什…

Bean如何诞生与消亡:生命周期探秘【beans 二】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Bean如何诞生与消亡&#xff1a;生命周期探秘【beans 二】 前言bean的创建过程bean的初始化阶段1. 实现InitializingBean接口&#xff1a;2. 使用PostConstruct注解&#xff1a; bean的属性注入1. Set…

视频倒放软件,看视频如何演绎“逆袭”之旅

你是否厌倦了日复一日的平淡生活&#xff0c;渴望时光倒流&#xff0c;重温那些逝去的精彩瞬间&#xff1f;在数字技术的世界里&#xff0c;这样的愿望或许不再遥不可及。视频倒放仿佛让时光倒流&#xff0c;给我们的视觉带来了全新的冲击&#xff0c;今天&#xff0c;让我们一…

新手第一次在linux上用git上传代码到仓库全过程

目录 背景&#xff1a; 过程&#xff1a; -1.去github.com自己的账号先建个仓库repository 0.命令行输入 git version 看下有无安装git 1.git init 初始化了一个Git仓库&#xff0c;你可以 ls -a 看见这个隐藏的目录 3.git add . 添加要上传的文件到Git的暂存区&#xff0…

windows对微信及小程序抓包:Burp+Fiddler+Proxifier

本文由掌控安全学院 - zbs 投稿 话不多说&#xff0c;直接先上个效果图&#xff1a; 新新的版本哈&#xff1b; 好好的抓包哈&#xff1b; 然后直接说我如何配置的&#xff1a; 准备好三个工具&#xff1a;bp、fiddler、proxifier【也可以用其他的进行代理】 bp、proxifie…

ELement UI时间控件el-date-picker误差8小时解决办法

一、问题描述&#xff1a; 在项目中引用了elementui中的date-picker组件&#xff0c;选中的时间跟实际相差八小时&#xff0c;且格式不是自己想要的格式 <el-date-pickertype"date"placeholder"选择日期"format"yyyy/M/d"v-model"form…

R304S 指纹识别模块的硬件接口说明

一.外部接口尺寸图 二.串行通讯 R304S 指纹模块通讯接口定义&#xff1a; 引脚号名称定义描述15V电源输入电源正输入端 DC 4.2--6V2GND电源和信号地电源和信号地3TXD数据发送串行数据输出&#xff0c;TTL 逻辑电平4RXD数据接收串行数据输入&#xff0c;TTL 逻辑电平 三.USB通…

EtherCAT的COE报文

本文主要用于记录工作中需要学习的内容&#xff0c;如有冒犯请私信&#xff01; COE协议 下面我们介绍以下CANOpen在EtherCAT中的应用。 COE的对象字典 COE协议是完全遵循CANopen协议的&#xff0c;但针对EtherCAT通信做了一些扩展&#xff0c;索引为0x1c00~0x1c4f&#xff0…

Java中关键词strictfp有什么作用?

在Java中&#xff0c;关键词strictfp用于声明一个方法、类或接口是严格遵守浮点数计算规范的。 具体作用包括&#xff1a; 保证浮点数计算的结果在不同平台上是一致的&#xff0c;避免由于浮点数计算的不精确性导致的结果不确定性。 指定了严格的浮点数计算规则&#xff0c;禁…

LeetCode刷题---矩阵置零

解题思路&#xff1a; 本题要求原地置换元素 对矩阵进行第一轮遍历&#xff0c;使用第一行第一列来充当该行该列是否要置换为0的标记位&#xff0c;如果第一行或第一列本身就含有零元素&#xff0c;我们使用colZero和rowZero变量来对其标记。如果第i行第j列的那个元素为0&#…

产品经理如何选择城市?

年底&#xff0c;全国性的人口大迁徙即将开始。选择城市&#xff0c;堪称年轻人的“二次投胎”&#xff0c;族望留原籍&#xff0c;家贫走他乡。 古人在选择城市时&#xff0c;主要的考量因素是家族势力&#xff0c;这一点放在当代&#xff0c;大致也成立&#xff0c;如果在老…

Cell 文章图复现

多组差异火山图复现 参考文章: A Spatiotemporal Organ-Wide Gene Expression and Cell Atlas of the Developing Human Heart Figure 2. H 图里主要是单细胞数据不同cluster之间的差异火山图, 所以说白了就是散点图和柱状图的结合, 散点图用差异基因绘制, 柱状图利用logFC最…

关于MIPS上手应知应会-如何把C语言改写为MIPS!

文章目录 寄存器指令使用技巧翻译C/Cif/else语句switch语句for循环while 循环do...while循环一维数组定义与使用二维数组定义与使用例 &#xff1a;哈密顿回路 注意立即数被符号位扩展 参考链接 寄存器 NameReg. NumUsage z e r o zero zero0constant value 0(恒为0) a t at a…

TypeScript Array(数组)

目录 1、数组初始化 2、Array 对象 3、数组迭代 4、数组在函数中的使用 4.1、作为参数传递给函数 4.2、作为函数的返回值 5、数组方法 数组对象是使用单独的变量名来存储一系列的值。数组非常常用。假如你有一组数据&#xff08;例如&#xff1a;网站名字&#xff09;…

Java中的IO与NIO篇----第三篇

系列文章目录 文章目录 系列文章目录前言一、信号驱动 IO 模型二、异步 IO 模型三、JAVA NIO四、NIO 的缓冲区前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 一、…

P1423 小玉在游泳python

s float(input()) sum 0 step 0 meter 2.0 while sum < s:sum metermeter 0.98 * meterstep 1 print(step)

三、C语言中的分支与循环—switch语句(4)分支结构 完

本章分支结构的学习内容如下&#xff1a; 三、C语言中的分支与循环—if语句 (1) 三、C语言中的分支与循环—关系操作符 (2) 三、C语言中的分支与循环—条件操作符 与逻辑操作符(3) 三、C语言中的分支与循环—switch语句&#xff08;4&#xff09;分支结构 完 本章循环结构的…
最新文章