完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大家好,期待一个紧急的解决方案。我目前正与PIC24FJ256GB406微控制器的I2C-2外围设备一起工作,因为我试图与RTCC芯片PC8563I接口,但无法工作。我试图调试,发现在第一次写入后“TBF”位没有清除。到TRN寄存器。我可以理解传输缓冲区已满,并且仍然没有通过传输寄存器完全发送数据。但它是一个“HSC”位,必须由硬件清除,并且由于它没有被清除,我不能继续进一步传输。在写TRN寄存器之后,传输是否有可能没有被启动????可能是什么问题????请帮助……我也附上了我的源代码和这个论坛。
以上来自于百度翻译 以下为原文 Hi everyone, Expecting a solution for this urgently. I am currently working with the I2C-2 peripheral of PIC24FJ256GB406 microcontroller since I am trying to interface with a RTCC Chip PC8563 I couldn't make it work I tried debugging and found that the 'TBF' bit is not getting cleared after the 1st write to the TRN register. I could understand that the transmission buffer is full and still data is not fully sent out through the transmission register. But its an 'HSC' bit which must be cleared by the hardware, and since its not cleared, I couldn't proceed with further transmission. Is there any chance that the transmission is not initiated even after writing the TRN register ??? What might be the problem??? Please help..... I had also attached my source code along with this forum void i2c_configurations() { I2C2BRG = 0x9D; // 100KHz operation with 16MHz clock I2C2CONLbits.I2CEN = 0; // Disable I2C Mode I2C2CONLbits.DISSLW = 1; // Disable slew rate control IFS3bits.MI2C2IF = 0; // Clear Interrupt I2C2CONLbits.I2CEN = 1; // Enable I2C Mode temp = I2C2RCV; // read buffer to clear buffer full reset_i2c_bus(); // set bus to idle temp = I2C2RCV; // Reading Receive buffer to clear Buffer Full i2c_reset_bus(); temp = 0; halMcuWaitMs(1000); } //--------------------------------------------------------------------------------------------------------------------------- void i2c_start() { I2C2STATbits.ACKSTAT = 0; // Clearing the previous ACK received from the slave to avoid false ACK for current trasmission I2C2CONLbits.SEN = 1; Nop(); while(I2C2CONLbits.SEN) { halMcuWaitMs(10); temp++; if(temp>10) { // start_bit_not_clearing = start_bit_not_clearing + 1; break; } } halMcuWaitMs(1); temp = 0; } //--------------------------------------------------------------------------------------------------------------------------- void i2c_stop() { I2C2CONLbits.PEN = 1; while(I2C2CONLbits.PEN) { halMcuWaitMs(10); temp++; if(temp>10) { //stop_bit_not_clearing = stop_bit_not_clearing + 1; break; } } temp = 0; } //--------------------------------------------------------------------------------------------------------------------------- void i2c_restart() { I2C2CONLbits.RSEN; Nop(); while(I2C2CONLbits.RSEN) { halMcuWaitMs(10); temp++; if(temp>10) { //restart_bit_not_clearing = restart_bit_not_clearing + 1; break; } } temp = 0; } //--------------------------------------------------------------------------------------------------------------------------- void send_ack() { I2C2CONLbits.ACKDT = 0; // This ACKDT bit will be transmitted to the slave when Enabling the ACKEN bit I2C2CONLbits.ACKEN = 1; // ACKDT is transmitted at this point and thus ACK is made, after this the slave receives ACK and auto increments its Register address while(I2C2CONLbits.ACKEN); // ACKEN is a Hardware clearable bit } //--------------------------------------------------------------------------------------------------------------------------- void send_nack() { I2C2CONLbits.ACKDT = 1; // This ACKDT bit will be transmitted to the slave when Enabling the ACKEN bit indicating No ACK I2C2CONLbits.ACKEN = 1; // ACKDT is transmitted at this point and thus ACK is made, after this the slave receives No ACK while(I2C2CONLbits.ACKEN); // ACKEN is a Hardware clearable bit } //--------------------------------------------------------------------------------------------------------------------------- unsigned short int ack_received() { if(I2C2STATbits.ACKSTAT == 0) return 1; else return 0; } //--------------------------------------------------------------------------------------------------------------------------- void i2c_transmit_data(unsigned char data) { TRISFbits.TRISF4 = 0; // Data pin configured as output //while((I2C2STATbits.TBF)); // Waits until the TRANSMISSION BUFFER IS EMPTY //halMcuWaitMs(100); IFS3bits.MI2C2IF = 0; I2C2TRN = (data & 0xFF); // Data transmission is initiated here while((I2C2STATbits.TRSTAT)) { halMcuWaitMs(1); temp++; if(temp>20) { master_long_transmission_time = master_long_transmission_time + 1; break; } } temp = 0; // // if(I2C2STATbits.ACKSTAT == 1) // { // i2c_reset_bus(); // } //I2C2STATbits.IWCOL = 0; // Clearing the write collision bit, Its an Hardware settable but not clearable } //--------------------------------------------------------------------------------------------------------------------------- unsigned char i2c_receive_data(void) { TRISFbits.TRISF4 = 1; // Data pin configured as input unsigned char data; I2C_RECEIVE_ENABLE(); // Automatically cleared by hardware at the end of the 8-bit reception while(!(I2C2STATbits.RBF)) // Waits until the receiver buffer is full indicating one complete reception is completed { halMcuWaitMs(1); temp++; if(temp>20) { //master_long_reception_time = master_long_reception_time + 1; break; } } data = (I2C2RCV & 0xFF); temp = 0; return data; } //--------------------------------------------------------------------------------------------------------------------------- void i2c_reset_bus() { I2C2CONLbits.PEN = 1; while(I2C2CONLbits.PEN) { halMcuWaitMs(10); temp++; if(temp>10) { //stop_bit_not_clearing = stop_bit_not_clearing + 1; break; } } temp = 0; I2C2CONLbits.RCEN = 0; IFS3bits.MI2C2IF = 0; // Clearing Master I2C2 interrupt //I2C1CONHbits.PCIE = 0; // Disabling stop condition interrupt //I2C1CONHbits.SCIE = 0; // Disabling Start condition interrupt I2C2STATbits.IWCOL = 0; // Software clearing of write collision I2C2STATbits.BCL = 0; // Software clearing of Bus Collision detect halMcuWaitMs(10); } //--------------------------------------------------------------------------------------------------------------------------- |
|
相关推荐
9个回答
|
|
非常感谢您的回复……实际上我意识到一旦启用了I2C外围设备,那么I/O端口引脚就不起作用了,但是经过多次尝试,我终于知道至少可以解决我的问题。代码不工作。你问我有关调用代码的问题。我从我的主例程调用这些函数…我没有包括整个代码,因为我甚至在第二次写到TXN寄存器时遇到问题…你的建议很有价值。
以上来自于百度翻译 以下为原文 Thank u very much for ur kind reply... Actually I was aware that once I2C peripherals are enabled then the I/O port pins has no effect, but defined that after numerous tries expecting atleast that will solve my issue... So wat im coming to say is, without that data direction registers being defined also the code is not working. U asked me regarding the calling code.... I call these functions from my main routine... I haven't enclosed the whole code, since Im even getting problem in the second write to the TXN register... Ur suggestions are valuable int main(void) { Configure_MCU(); // It configures Oscillator clock, Peripheral Port pins halMcuWaitMs(500); i2c_configurations(); i2c_start(); // The following set of routines will write the initial values for the Slave Registers i2c_transmit_data(0xA2); // Slave is ordered by Master to write its Registers //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(0x00); //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(0x00); // Here the oscillator of the RTC Chip is stopped so that we can write its registers //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(0x00); // Data to be fired into the Control Register 1 i2c_transmit_data(dec_to_bcd(SECOND_INITIAL_VALUE)); // Data to be fired into the Seconds Register 1 //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(dec_to_bcd(MINUTE_INITIAL_VALUE)); // Data to be fired into the Minutes Register 1 //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(dec_to_bcd(HOUR_INITIAL_VALUE)); // Data to be fired into the Hours Register 1 //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(dec_to_bcd(DAY_INITIAL_VALUE)); // Data to be fired into the Day Register 1 //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(dec_to_bcd(1)); // Data to be fired into the Control Register 1 //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(dec_to_bcd(MONTH_INITIAL_VALUE)); // Data to be fired into the Control Register 1 //halMcuWaitMs(500); //while(!(ack_received())); i2c_transmit_data(dec_to_bcd(YEAR_INITIAL_VALUE)); // Data to be fired into the Control Register 1 i2c_stop(); return 0; } |
|
|
|
嗨,如果TBF位在合理的时间内没有返回到零,通常是因为在传输完成之前传输被拒绝或***扰。或者是因为传输是在I2C硬件仍然忙于先前传输时启动的,或者是检测到总线冲突情况。ROBLIM发生,检查BCL位,I2CXSTAT寄存器中的IWCOL位。问候,Mysil
以上来自于百度翻译 以下为原文 Hi, If the TBF bit do not return to zero in reasonable time, it is usually because transmission was refused or disturbed before transmission was completed. Either because transmission was started while I2C hardware was still busy with previous transfer, or a Bus Collision condition was detected. When problem occur, check BCL bit, and IWCOL bit in I2CxSTAT register. Regards, Mysil |
|
|
|
在i2c_start()函数中,您正在寻找SEN返回到零的超时,但是您不返回任何状态来指示它发生了,或者在返回之后执行任何其他检查。同样,您已经注释掉了ACKSTAT的所有检查,并且在注释掉的代码中还犯了等待ACKSTAT的非常常见的错误。您不必等待。在传输完成后,您检查它,ONCE。如果它是高的(==NAK),那么事务失败,并且您应该中止。当时它是高的,无论您再等待多久,它永远不会变低(==ACK)。
以上来自于百度翻译 以下为原文 You are looking for a timeout on SEN returning to zero in your i2c_start() function, but you don't return any status to indicate it happened, or do any other checks after you return. You should also be checking the "bus collision" flag, which will tell you if something was already driving SDA or SCL low. Equally, you have commented out all the checks for ACKSTAT, and you have also made the very common mistake of WAITING for ACKSTAT in that commented out code. You do not wait for it. You check it, ONCE, after the transmission is complete. If it is high (== NAK), then the transaction failed, and you should abort. It it was high then, it will never go low (== ACK) no matter how much longer you wait. |
|
|
|
什么是“IT”?我希望IWCOL可以在TBF仍然被设置的时候写到TXN上,这是BCL在这里更重要。它被设定了吗?我想你刚才跟我说的一样,但是BCL标志已经被设置,还是在第二次写入TXN之后?所有定时都由主机控制。当TrSTAT标志变低时,ACK位的时钟脉冲已经切换,读取的值在ACKSTAT位中。您可以等到母牛回家,在该时间点之后不会改变。添加等待是错误的。
以上来自于百度翻译 以下为原文 What is "it"? I would expect IWCOL to get set if you wrote to TXN while TBF was still set. It's BCL that is more important here. Does it ever get set? I think you've just said the same as me above. But was the BCL flag already set, or only after the second write to TXN? All timing is controlled by the Master. When the TRSTAT flag goes low, the clock pulse for the ACK bit has already toggled, and the value that was read is in the ACKSTAT bit. You can wait until the cows come home, IT WILL NOT CHANGE after that point in time. Adding a wait there is wrong. |
|
|
|
嗨,在消息#6中,您报告检查IWCOL位和BCL位,您必须知道哪些被设置。如果硬件已经设置了IWCOL位=1,那么这是由于驱动程序代码中的错误,代码试图启动新操作,而之前的传输没有完成。E到I2CXTRN,代码应该检查TrSTAT位是否清晰,并且其他先前的操作已经完成。当上一次传输完成时,可以等待TRSTAT位变为0。如果BCL位已经设置为ben set=1,则硬件上是因为信号线电平检查检测到不匹配。如果发生这种情况,I2C硬件将放弃并释放总线。正确的动作是清除BCL位,并通过发送开始条件信号从一开始就重试。迈西尔
以上来自于百度翻译 以下为原文 Hi, In message #6 you report checking IWCOL and BCL bits, you have to tell which of those get set. If IWCOL bit have been set = 1 by the hardware, then it is because of error in your driver code, code have tried to start a new operation, while previous transfer was not completed. Before starting a write to I2CxTRN, code should check that TRSTAT bit is clear, and that other previous operations have been completed. It is possible to wait for TRSTAT bit to become 0 when previous transfer is completed. If BCL bit have ben set = 1, by the hardware, it is because signal line level checking have detected a mismatch. If this happen, I2C hardware will give up and release the bus. The correct action is to Clear the BCL bit, and retry from the beginning by sending Start condition signal. Mysil |
|
|
|
谢谢你们两个,我现在有一些清晰…我的SDA和SCL线显示0.5V,即使在连接上拉电阻总是在IM开始时,BCL标志变高…我检查了上拉电路分开,这是好的,但一旦我连接我的Mimon控制器的SDA。SCL引脚下降到0.5维有任何初始配置,可以改变总线(SDA和放大器,SCL)????
以上来自于百度翻译 以下为原文 Thank u both of u, i now have some clarity.... My SDA & SCL lines shows just 0.5V even after connecting the pull-up resistors Hence always when Im writing the Start bit, BCL flag goes high.... I checked the pull-up circuitry separately, and it was good But once I connected my microncontroller's SDA & SCL pins it drops down to 0.5V Is there any initial configurations that could make changes in the BUS lines (SDA & SCL) ??? |
|
|
|
嗨,“有没有任何初始配置可以改变公交线路(SDA和SCL)???”简短的回答是肯定的。但是为了确定一个实际的原因,你必须完全显示你的代码。我们可以猜测,但是我们不能知道你实际上在做什么。在MPLAB,有一个设施来收集重建项目所需的所有文件:指向项目P中的项目结构的根目录。ALEL(左上角),点击右键,在菜单中选择“包”。它将在项目目录中创建一个ZIPFILE。希望你是论坛的一个成员,被允许与MasaGeEGARDS,Mysil联系。
以上来自于百度翻译 以下为原文 Hi, "Is there any initial configurations that could make changes in the BUS lines (SDA & SCL) ???" Short answer is Yes. But in order to identify an actual cause, you will have to show absolutely all your code. We can guess, but we cannot know what you are actually doing. In MPLAB there is a facility to collect all files needed to recreate the project: Point to root of project structure in Projects panel (upper left), click right button, and select 'package' in menu. It will create a zipfile in the project directory. Hopefully, you have been a member of the forum to be allowed to make an attachment to a message Regards, Mysil. |
|
|
|
数据表中的设备的PIN功能图对这两个引脚有说明:因此SEG10和RP10函数具有比SDA2更高的优先级,并且SEG11和RP17比SCL2具有更高的优先级。LCD是激活的,还是PPS触摸这两个引脚?PMA9和PMA8功能应该是较低的优先级,但我记得一些设备有ErrATA说激活并行主端口(PMP)可以抓住所有的PM引脚。
以上来自于百度翻译 以下为原文 The pin function diagram for your device in the data sheet has this to say about those two pins: 31 SEG10/RP10/SDA2/PMA9/RF4 32 SEG11/RP17/SCL2/PMA8/RF5 So the SEG10 and RP10 functions have higher priority than SDA2, and SEG11 and RP17 functions higher priority than SCL2. Is the LCD active, or PPS touching those two pins? The PMA9 and PMA8 functions should be lower priority, but I recall some devices having errata saying that activating the Parallel Master Port (PMP) can grab all the PM pins. |
|
|
|
嗨,已经把一些缺失的片段连同代码在我的PX24FJ256GB110中的代码1和第3工作。在这个芯片上,SDA2是引脚RA3,SCL2与引脚RA2共享。对于ADXL345的I2C地址,存在用于地址和数据传输的AC.。当寻址一个不可用的设备时,存在NACK,并且代码被改变以终止传输并发送停止条件信号。关于MysIL
以上来自于百度翻译 以下为原文 Hi, Have put in some of the missing pieces together with the code in message #1 and #3 Works for me, on PIC24 FJ256GB110. On this chip SDA2 is pin RA3, SCL2 is shared with pin RA2. With the I2C address of ADXL345, there is ACKnowledge for both address and data transfer. When addressing a device that is not available, there is NACK, and code is changed to terminate the transfer and send Stop condition signal. Regards, Mysil Attachment(s) I2C_problem.zip (14.43 KB) - downloaded 63 times |
|
|
|
只有小组成员才能发言,加入小组>>
5189 浏览 9 评论
2009 浏览 8 评论
1933 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3181 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2232 浏览 5 评论
746浏览 1评论
632浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
517浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
644浏览 0评论
544浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-30 20:02 , Processed in 1.464703 second(s), Total 93, Slave 77 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号