完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,大家好,
我正在使用CY8C5267Lti-LP039芯片上的I2C,并且我已经实现了一种解决方案,该解决方案与管理设备中的电池的奴隶进行对话。 我的代码在下面。 简短的故事是,我写一个单一的命令字节,读取返回日期(2或4字节),然后存储要发送到USB上的数据,然后重复下一个命令字节。 空隙内部是BATII2C(空隙)/这个函数被称为主环中的其他东西。 { E,0x11,0x17,0x01,0x03.0x030x0b,0x0C,0x0f,0x3c,0x3c,0x3e,0x3e,0x3f,0x140x150.0x180x190x1a,0x1a,0x60,0x61,0x62.0x55,0x56,0x50,0x51,0x52.0x53.0x54;静态uTInIAGILASGAGOGEGY地址[40 ]={0x00,0x08/0x090.0x0a,0x0d,0x0. 静态UIT8内部I2CI命令[1 ];//I2C写指针 静态UTIN内部BATII2CY步骤=1;//内部BAT I2C步骤 静态UTI8I2CYNILALL BATY-CMDYSEQ=0;/ /用于递增I2C地址 静态UTInIn BATYI2C2Read BythyType计数; 静态UTIN内部BATI2I2CX写入字节数; 静态UIT8内部I2Cl缓冲器〔5〕;//I2C读缓冲指针 如果(IntualBATIII2CYSTEP=1)/I将I2C事务拆分为步骤,以便固件的其他部分可以在其解析时运行。 { I2CyInAutoLaBATMistCurraseStUbSUs(); BiTuxBi2Ic2CyErthyByTeTyCube计数=1;//写入单字节到I2C -燃气表的命令字节 内部I2CI命令[0 ]=Innall Gasth-GugGeAdv[I2cInIalalthBATY-CMDYSEQ ];//= 0x20; I2CXInAuthBaTyMrdRead Buf(0x0b,(Unt8*)IntualI2Icx命令,InnalBuiI2C2WrdErthyByTeTyEnter计数,I2CyInalalBATHOMDEDENOYSTOP); IntualBATIII2CY步骤=2;//写完成,然后继续读下一步循环。 } //如果写完成,那么 如果((i2cInInAdBaTimeStasuSues)和;(=0U)和(和);(IntualBATIII2CYSTEP==2)和(和(I2CYNILALBATBATMARSTATESUSER)和;= 0U) { I2CyInAutoLaBATMistCurraseStUbSUs(); In(InIall I2C~命令[0 ]=0x50π(内部I2CII命令[0 ]=0x51)〉(内部Al2Ci命令[0 ]=0x52)*(内部Al2Ci命令[0 ]=0x53) OMMand〔0〕=0x54〕(InIall I2Cl命令[0 ]=0x60)(InIall I2Cl命令[0 ]=0x61)(InIall I2Cl命令[0 ]=0x62)*(内部Al2Ci命令[0 ]=0x55)*(内部I2CII命令(0)=0x56)){ 内部的BATYI2C2Read BythyTyCo计数=5; } 其他的 { 内部的BATYI2C2Read BythyTyCo计数=2; } I2CXInAuthalBATYMASTRADEBUF(0x0B,(UTI8*)内部I2Cl缓冲,内部BATAI I2C2Read BytheTyTo计数,(I2CyBialthBATOMDEMeExcel,XFER,I2CYNILALL BATA MODEDEA重复启动); 内部BATIII2CY步骤=3; } //如果读取完成,则存储要发送到USB的数据。 如果((i2cInInAdBaTimeStasuSues)和;(=0U)和(和);(IntualBATIII2CYSTEP==3)和(和(I2CYNILALBATBATMARSTATESUSER)和;= 0U) { In(InnalBATIII2C*Read ObjyTytCo==2) { InnalAsGas-GueGeDATAYB0 [I2CYNIALALBATBYCMDYSEQ ] =内部I2Cl缓冲器〔0〕; InnalAsGas-GueGeDATAYB1[I2CY-InAlalthBATY-CMDYSEQ ] =内部I2Cl缓冲器〔1〕; } In(InnalBATIII2C*Read ObjyTytCo==5) { InnalAsGas-GueGeDATAYB0 [I2CYNIALALBATBYCMDYSEQ ] =内部I2Cl缓冲器〔1〕; InnalAsGas-GueGeDATAYB1[I2CY-InAlalthBATY-CMDYSEQ ] =内部I2Cl缓冲器〔2〕; IntualasGas-GueGeDATAYB2 [I2CY-InAlalthBATY-CMDYSEQ ] =内部I2Cl缓冲器〔3〕; IntualasGas-GueGeDATAYB3 [I2CY-InAlalthBATY-CMDYSEQ ] =内部I2Cl缓冲器〔4〕; } //此代码段选择要发送的下一个命令字节。我们只是遍历整个列表 计数器/1x启动();//使用计数器在每个命令之间增加20MSEC延迟-启动计数器 如果(counter_1_readcounter() <;= 59980)/ /等待20msec以上(测量~与没有USB连接USB连接和~ 40ms延迟80ms范围) { 计数器1-停止();/停止计数器 counter_1_writecounter(6);//计数器重置回其原始 如果(i2c_internal_bat_cmd_seq = = 39)/ /如果我们已经到了最后一个命令然后重置为第一 { 反2x启动(); 如果(counter_2_readcounter() <;= 59000)/ /等待至少2sec再次阅读同一命令之前 { 计数器2x停止();/停止计数器 Audio2x书写器(60000); I2Cl内部的BATY-CMDYSEQ=0; 内部BATIII2CY步骤=1; } } 其他的 { +I2Cl内部的BATY-CMDYSEQ; 内部BATIII2CY步骤=1; } } } } 我遇到的问题是,尽管给i2c_masterwritebuf()只有一个字节会随机发送一个额外的2字节。我的I2C总线锁并不会恢复到系统权限。同时,I2C总线锁我注意到USB数据发送到窗口从柏树也消失,在设备管理器中显示为一个未知的设备,所以我认为芯片本身也可能被锁定。 下面是用I2C嗅探器捕获故障的方法。 有人对此发表评论吗?我不知道为什么我的代码会导致或允许额外的字节被发送。我也无法解释USB与I2C连接失败的关系。 干杯 凯文 以上来自于百度翻译 以下为原文 Hi all, I'm using the I2C on a CY8C5267LTI-LP089 chip and I've implemented a solution that talks to a slave that manages a battery in my device. My code is below. The short story of it is that I write a single command byte, read the return date (either 2 or 4 bytes), then store that data to be sent out on USB, then repeat for the next command byte. void Internal_BAT_I2C(void) //This function is called in the main loop amongst other things{ static uint8 Internal_Gas_Gauge_Address[40] = {0x00,0x08,0x09,0x0A,0x0D,0x0E,0x11,0x12,0x13,0x16,0x17,0x4F,0x01,0x02,0x03,0x0B,0x0C,0x0F,0x10,0x1B,0x3C,0x3D,0x3E,0x3F,0x14,0x15,0x18,0x19,0x1A,0x1C,0x60,0x61,0x62,0x55,0x56,0x50,0x51,0x52,0x53,0x54}; static uint8 Internal_I2C_Command[1]; // i2C write pointer static uint8 Internal_BAT_I2C_Step = 1 ; //internal bat i2c step static uint8 I2C_Internal_BAT_CMD_SEQ = 0; //used for incrementing the I2C address static uint8 Internal_BAT_I2C_READ_BYTE_COUNT; static uint8 Internal_BAT_I2C_WRITE_BYTE_COUNT; static uint8 Internal_I2C_buffer[5]; //I2c read buffer pointer if (Internal_BAT_I2C_Step == 1) // I split the I2C transaction into steps so that other parts of the firmware can run while it resolves. { I2C_INTERNAL_BAT_MasterClearStatus(); Internal_BAT_I2C_WRITE_BYTE_COUNT = 1; // Write single byte to I2C -command byte of gas gauge Internal_I2C_Command[0]= Internal_Gas_Gauge_Address[I2C_Internal_BAT_CMD_SEQ]; // = 0x20; I2C_INTERNAL_BAT_MasterWriteBuf(0x0B, (uint8*)Internal_I2C_Command, Internal_BAT_I2C_WRITE_BYTE_COUNT, I2C_INTERNAL_BAT_MODE_NO_STOP); Internal_BAT_I2C_Step = 2; //Write is done so proceed to read step on next loop } // If the write is finished then if (((I2C_INTERNAL_BAT_MasterStatus() & I2C_INTERNAL_BAT_MSTAT_WR_CMPLT)!=0u) && (Internal_BAT_I2C_Step == 2) && ((I2C_INTERNAL_BAT_MasterStatus() & I2C_INTERNAL_BAT_MSTAT_ERR_XFER) != 0u)) { I2C_INTERNAL_BAT_MasterClearStatus(); if (Internal_I2C_Command[0] == 0x50 || (Internal_I2C_Command[0] == 0x51) ||(Internal_I2C_Command[0] == 0x52) ||(Internal_I2C_Command[0] == 0x53) || (Internal_I2C_Command[0] == 0x54) ||(Internal_I2C_Command[0] == 0x60) || (Internal_I2C_Command[0] == 0x61) ||(Internal_I2C_Command[0] == 0x62) ||(Internal_I2C_Command[0] == 0x55) || (Internal_I2C_Command[0] == 0x56) ) { Internal_BAT_I2C_READ_BYTE_COUNT = 5; } else { Internal_BAT_I2C_READ_BYTE_COUNT = 2; } I2C_INTERNAL_BAT_MasterReadBuf(0x0B, (uint8*)Internal_I2C_buffer, Internal_BAT_I2C_READ_BYTE_COUNT, (I2C_INTERNAL_BAT_MODE_COMPLETE_XFER|I2C_INTERNAL_BAT_MODE_REPEAT_START)); Internal_BAT_I2C_Step = 3; }// if the read is finished then store data to be sent to USB if (((I2C_INTERNAL_BAT_MasterStatus() & I2C_INTERNAL_BAT_MSTAT_RD_CMPLT)!=0u) && (Internal_BAT_I2C_Step == 3) && ((I2C_INTERNAL_BAT_MasterStatus() & I2C_INTERNAL_BAT_MSTAT_ERR_XFER) != 0u) ) { if (Internal_BAT_I2C_READ_BYTE_COUNT == 2) { Internal_Gas_Gauge_Data_B0[I2C_Internal_BAT_CMD_SEQ]=Internal_I2C_buffer[0]; Internal_Gas_Gauge_Data_B1[I2C_Internal_BAT_CMD_SEQ]=Internal_I2C_buffer[1]; } if (Internal_BAT_I2C_READ_BYTE_COUNT == 5) { Internal_Gas_Gauge_Data_B0[I2C_Internal_BAT_CMD_SEQ]=Internal_I2C_buffer[1]; Internal_Gas_Gauge_Data_B1[I2C_Internal_BAT_CMD_SEQ]=Internal_I2C_buffer[2]; Internal_Gas_Gauge_Data_B2[I2C_Internal_BAT_CMD_SEQ]= Internal_I2C_buffer[3]; Internal_Gas_Gauge_Data_B3[I2C_Internal_BAT_CMD_SEQ]= Internal_I2C_buffer[4]; } //This section of code selects the next command byte to be sent. We just iterate through the entire list Counter_1_Start(); //using counter to add 20msec delay between each commands - start the counter if (Counter_1_ReadCounter() <= 59980) //wait for 20msec or more (Scope measured ~80ms delay with USB connection and ~40ms with no USB connection) { Counter_1_Stop(); //stop the counter Counter_1_WriteCounter(60000); //reset the counter back to its orginal if (I2C_Internal_BAT_CMD_SEQ == 39)//if we've reached the last command then reset to the first { Counter_2_Start(); if (Counter_2_ReadCounter() <= 59000) //wait for at least 2sec before reading the same command again { Counter_2_Stop(); //stop the counter Counter_2_WriteCounter(60000); I2C_Internal_BAT_CMD_SEQ = 0; Internal_BAT_I2C_Step = 1; } } else { ++I2C_Internal_BAT_CMD_SEQ; Internal_BAT_I2C_Step = 1; } } }} The problem I'm running into is that despite giving I2C_MasterWriteBuf() only a single byte it will randomly send an extra 2 bytes. My I2C bus locks up and won't recover until the the system is power cycled. At the same time the I2C bus locks up I've noticed that the USB sending data to Windows from Cypress also disappears and shows as an unknown device in Device Manager so I think the chip itself may also be locking up. Here's a capture of the failure with my I2C sniffer. Can someone comment on this? I can't see a reason why my code would cause or allow extra bytes to be sent. I also can't explain the relation between the USB failing in conjunction with the I2C. Cheers Kevin |
|
相关推荐
3个回答
|
|
调试你的项目并检查I2CyInAdLaBATMigWrrestBuffe()计数!= 1。可以相应地设置断点条件。
鲍勃 以上来自于百度翻译 以下为原文 Debug your project and check at I2C_INTERNAL_BAT_MasterWriteBuf() for count != 1. You may set the breakpoint condition accordingly. Bob |
|
|
|
嘿,鲍伯,谢谢你的回复。 我不知道如何检查计数——据我所知,MistWrrestBuffe()不为它发送的字节数返回一个计数。在MrimeWrreBuffE()中使用的IntualBaTII2C*WrueByTeTyCurt被硬设置为1并且从不更改。 我也很抱歉如果这是一个愚蠢的问题…断点如何帮助我在嵌入式系统中调试这个?我对开发嵌入式芯片不是很有经验,但从我的理解,我仍然无法读取任何数据,对吗? 以上来自于百度翻译 以下为原文 Hey Bob, thanks for the response. I'm not sure how to check the count - as far as I know MasterWriteBuf() doesn't return a count for the number of bytes it sends. The Internal_BAT_I2C_WRITE_BYTE_COUNT I use in the MasterWriteBuf() is hard set to 1 and never changes. Also I apologize if this is a silly question.. How would the breakpoints help me debug this in an embedded system? I'm not very experienced with developing for embedded chips - but from my understanding I'd still be unable to read any of the data right? |
|
|
|
Jaionm 发表于 2018-10-1 18:50 I2CyInAutoLaBaTigMrdRead BuffE()是一个函数,您可以在其中实现(右击名称,选择定义)。在第一个可执行语句中,可以设置断点。左键点击BP符号并设置所需条件(计数!=1)。当执行停止时,您可以选择查看调用堆栈来查看错误数据来自何处。当然,在调试时,您可以检查变量(甚至设置)变量。检查堆栈溢出、错误指针等。 鲍勃 以上来自于百度翻译 以下为原文 I2C_INTERNAL_BAT_MasterWriteBuf() is a function which implementation you can find (right click on the name, select definition). At the first executable statement you can set a breakpoint. Left click on the BP symbol and set the required condition (count != 1). When the execution stops you have the choice to see the call stack to see where the wrong data come from. Of course you may inspect (and even set) variables when debugging. Check for stack overflow, bad pointers etc. Bob |
|
|
|
只有小组成员才能发言,加入小组>>
754个成员聚集在这个小组
加入小组2103 浏览 1 评论
1849 浏览 1 评论
3667 浏览 1 评论
请问可以直接使用来自FX2LP固件的端点向主机FIFO写入数据吗?
1784 浏览 6 评论
1534 浏览 1 评论
CY8C4025LQI在程序中调用函数,通过示波器观察SCL引脚波形,无法将pin0.4(SCL)下拉是什么原因导致?
566浏览 2评论
CYUSB3065焊接到USB3.0 TYPE-B口的焊接触点就无法使用是什么原因导致的?
420浏览 2评论
CX3连接Camera修改分辨率之后,播放器无法播出camera的画面怎么解决?
435浏览 2评论
381浏览 2评论
使用stm32+cyw43438 wifi驱动whd,WHD驱动固件加载失败的原因?
913浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 21:38 , Processed in 0.957504 second(s), Total 81, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号