主要内容

与I2C总线信号设备和分析使用数字IO

与仪器和设备通信的协议层和物理层。使用I2C功能的仪器控制工具箱与TMP102温度传感器进行通信,同时分析了物理层I2C总线通信使用定时数据采集工具箱的数字输入输出特性。

数据采集工具箱和仪器控制工具箱是必需的。

硬件配置和示意图

  • 任何受支金宝app持的国家仪器™采集设备定时戴奥频道可以使用(例如,倪猫王II)

  • TotalPhase Aardvark I2C / SPI主机适配器

  • 与二线串行接口TMP102数字温度传感器

TMP102需要一个3.3 V供应。使用一个线性LDO (LP2950-33)生成3.3 V供应从采集设备的5 V补给线。

其他选项包括:

  • 使用一个外部电源。

  • 从你的数据收集设备使用一个模拟输出通道。

使用I2C主机适配器连接到TMP102传感器读取温度数据

连接传感器和验证使用I2C通信对象从仪器控制工具箱。

aa = instrhwinfo (“i2c”,“豚”);%得到I2C连接主机的信息tmp102 = i2c (“豚”0 hex2dec (48岁的));%创建一个连接到TMP102 I2C对象tmp102。PullupResistors =“两个”;%使用主机适配器上拉电阻fopen (tmp102);%打开连接data8 =从文件中读(tmp102 2“uint8”);%读2字节数据% 1 LSB等于0.0625度C温度=(双(bitshift (int16 (data8 (1)), 4)) +双(bitshift (int16 (data8 (2)), 4))) * 0.0625;%指TMP102数据表来计算温度从接收的数据流(由TMP102记录温度传感器:% s度C \ n”num2str(温度));文件关闭(tmp102);
由TMP102记录温度传感器:27.625度C

获得相应的I2C物理层信号使用采集设备

使用采样过量从倪猫王以数字频道(Dev4)获得和分析对I2C总线物理层通信。

获得SDA数据端口0,0行你的采集设备。获得sci数据端口0,1号线的采集设备。

dd =采集(“倪”);addinput (dd,“Dev4”,“port0 \ line0”,“数字”);% sdaaddinput (dd,“Dev4”,“port0 \ line1”,“数字”);% sci

生成一个时钟信号与数字子系统使用

数字子系统倪采集设备上不要有自己的时钟;他们必须共享一个时钟模拟子系统或从外部导入一个时钟子系统。生成一个50%的关税周期在1 MHz时钟使用PulseGeneration计数器输出和输入扫描速率匹配。

pgChan = addoutput (dd,“Dev4”,“ctr1”),“PulseGeneration”);dd.Rate = 1 e6;pgChan。频率= dd.Rate;

在“pgChan时钟生成。终端的针,允许与其他设备和查看时钟同步示波器。计数器的输出脉冲信号作为时钟信号是进口的。

disp (pgChan.Terminal);addclock (dd,“ScanClock”,“外部”,(“Dev4 /”pgChan.Terminal]);
PFI13

获得使用I2C信号以数字频道

获得从SDA和sci数字在后台的数据行。

  • 在后台启动DataAcquisition模式

  • I2C开始操作

  • 停止后DataAcquisition I2C操作完成

开始(dd,“连续”);fopen (tmp102);data8 =从文件中读(tmp102 2“uint8”);% 1 LSB等于0.0625度C温度=(双(bitshift (int16 (data8 (1)), 4)) +双(bitshift (int16 (data8 (2)), 4))) * 0.0625;文件关闭(tmp102);暂停(0.1);停止(dd);myData =阅读(dd,“所有”);
警告:触发器和时钟不会影响计数器输出通道。

画出原始数据获得的信号。注意,线是高闲置期间举行。下一节将展示如何找到启动/停止状态比特和使用它们来隔离I2C通信领域的兴趣。

图(“名称”,“原始数据”);次要情节(2,1,1);情节(myData (: 1));ylim ([-0.2, 1.2]);甘氨胆酸ax =;斧子。YTick = [0, 1];斧子。YTickLabel = {“低”,“高”};标题(“串行数据(SDA)”);次要情节(2,1,2);情节(myData (:, 2));ylim ([-0.2, 1.2]);甘氨胆酸ax =;斧子。YTick = [0, 1];斧子。YTickLabel = {“低”,“高”};标题(“串行时钟(sci)”);

分析了I2C总线物理层通信

提取I2C物理层信号SDA和sci线。

sda = myData (: 1)”;sci = myData (:, 2) ';

找到所有时钟上升和下降的边缘。

sclFlips = xor (sci (1: end-1), sci(2:结束);sclFlips = [1 sclFlips 1];sclFlipIndexes =找到(sclFlips = = 1);

计算时钟的时钟周期指数

sclFlipPeriods = sclFlipIndexes(1:结束)- [1 sclFlipIndexes (1: end-1)];

通过检查,观察到空闲时间sci高超过100美元。自扫描率= 1 ms / s,每个样本代表1人。idlePeriodIndices表明在I2C通信周期时间的活动。

idlePeriodIndices =找到(sclFlipPeriods > 100);

放大的第一期活动的I2C总线。为了便于查看,包括30个样本的空闲活动前和结束时,每一个情节。

range1 = sclFlipIndexes (idlePeriodIndices (1)) - 30: sclFlipIndexes (idlePeriodIndices (2) - 1) + 30;图(“名称”,“I2C通信数据”);次要情节(2,1,1);情节(sda (range1));ylim ([-0.2, 1.2]);甘氨胆酸ax =;斧子。YTick = [0, 1];斧子。YTickLabel = {“低”,“高”};标题(“串行数据(SDA)”);次要情节(2,1,2);情节(sci (range1));ylim ([-0.2, 1.2]);甘氨胆酸ax =;斧子。YTick = [0, 1];斧子。YTickLabel = {“低”,“高”};标题(“串行时钟(sci)”);

分析汽车性能指标

作为一个简单的例子分析指标、启动和停止条件和I2C比特率计算。

  • 开始状态持续时间被定义为时间sci后去低SDA低。

  • 停止条件持续时间被定义为时间SDA高sci后走高。

  • 比特率计算通过之间的时间的倒数2时钟上升边缘。

启动条件:首先SDA低,然后sci低

sclLowIndex = sclFlipIndexes (idlePeriodIndices (1));sdaLowIndex =找到(sda (1: sclLowIndex) = = 1, 1,“最后一次”)+ 1;% + 1,去年高抛后下一个值startConditionDuration = (sclLowIndex - sdaLowIndex) * 1 / s.Rate;流(“sda: % s \ n”sprintf (' % d 'sda (sdaLowIndex-1: sclLowIndex)));%索引指向下一个改变,因此sclLowIndex包括低抛流(“sci: % s \ n”sprintf (' % d 'sci (sdaLowIndex-1: sclLowIndex)));%减去1 sdaLowIndex翻转之前看到sda价值流(“启动条件持续时间:% d秒。\ n \ n”,startConditionDuration);%计算5个脉冲,5。
sda: 1 0 0 0 0 0 0 sci: 1 1 1 1 1 1 0开始条件持续时间:5.000000 e-06秒。

停止条件:首先sci高,然后SDA高

%翻转之前进入空闲状态是我们想要的sclHighIndex = sclFlipIndexes (idlePeriodIndices (2) 1);sdaHighIndex =找到(sda (sclHighIndex:结束)= = 1,1,“第一”)+ sclHighIndex - 1;stopConditionDuration = (sdaHighIndex - sclHighIndex) * 1 / s.Rate;流(“sda: % s \ n”sprintf (' % d 'sda (sclHighIndex-1: sdaHighIndex)));流(“sci: % s \ n”sprintf (' % d 'sci (sclHighIndex-1: sdaHighIndex)));流(“停止条件持续时间:% d秒。\ n \ n”,stopConditionDuration);
sda: 0 0 0 0 0 0 1 sci: 0 1 1 1 1 1 1停止条件持续时间:5.000000 e-06秒。

比特率:逆之间的间隔时间2在sci边缘线

startConditionIndex = idlePeriodIndices (1);firstRisingClockIndex = startConditionIndex + 2;secondRisingClockIndex = firstRisingClockIndex + 2;clockPeriodInSamples = sclFlipIndexes (secondRisingClockIndex)——sclFlipIndexes (firstRisingClockIndex);clockPeriodInSeconds = clockPeriodInSamples * 1 / s.Rate;比特率= 1 / clockPeriodInSeconds;流(的采集计算比特率= % d;实际的I2C对象比特率= % dKHz \ n ',比特率,tmp102.BitRate);
采集计算比特率= 1.000000 e + 05;实际的I2C对象比特率= 100千赫

上找到的位流抽样上升的边缘

sclFlipIndexes向量是使用XOR创建,因此既包含上升和下降的边缘。与崛起的边缘开始,用两步跳过下降的边缘。

% idlePeriodIndices时钟上升沿(1)+ 1是先上升后开始条件。%使用两步跳过边缘,只看上升下降的边缘。% idlePeriodIndices(2) 1是该指数上升边的停止条件。% idlePeriodIndices(2) 3是最后一个时钟上升边缘位流%解码。比特流= sda (sclFlipIndexes (idlePeriodIndices (1) + 1:2: idlePeriodIndices (2) 3));流(“原始比特流中提取的I2C物理层信号:% s \ n \ n”sprintf (' % d '比特流));
原始比特流中提取的I2C物理层信号:1 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 0 1 0 1 0 0 0 0 0 1

解码获得的位流

ADR_RW = {' W ',“R”};ACK_NACK = {“消”,“纳”};地址=比特流(1:7);% 7位地址流(“\ nDecoded地址:% d % d % d % d % d % d % d (0 x % s) % d (% s) % d (% s) \ n ',地址,binaryVectorToHex(地址),比特流(8),ADR_RW{比特流(8)+ 1},比特流(9),ACK_NACK{比特流(9)+ 1});iData = 0:1 startBit = 10 + iData * 9;endBit = startBit + 7;ackBit = endBit + 1;data =比特流(startBit: endBit);流(“解码数据% d: % s (0 x % s) % d (% s) \ n ',iData + 1,sprintf (' % d '数据),binaryVectorToHex(数据),比特流(ackBit),ACK_NACK{比特流(ackBit) + 1});结束
解码地址:1001000 (0 x48) 1 (R) 0 (ACK)解码Data1: 00011011 (0 x1b) 0 (ACK)解码Data2: 10100000 (0 xa0) 1(纳)

验证解码使用ICT数据使用数据收集与数据读取

两个uint8字节是阅读、使用从文件中读,从I2C总线到变量data8。十六进制转换这些值应与上面所示的总线解码的结果。

流(从I2C获得的数据对象:0 x % s \ n”dec2hex (data8) ');流(“温度:f % 2.2度C。\ n \ n”、温度);
数据从I2C获得对象:0 x1ba0温度:27.63度C