sujieww 发表于 2014-11-12 11:09:09

有人使用过C8051F300的SMBUS模拟I2C从机么?

{:sweat:} LZ现在模拟I2C从机,现在写入数据的时候,第2位到第8位的数据不能正常写入,其他位都是正常。

dzymushi 发表于 2014-11-16 11:14:55

可的啊,你是不是地址没配对?

sujieww 发表于 2014-11-16 14:12:23

dzymushi 发表于 2014-11-16 11:14
可的啊,你是不是地址没配对?

没明白,地址没配对是什么错误。
是指在写入数据的时候对应的地址写错了么?
可是这八位在写的时候数据完全没有写进去。应该不是这个吧。

dzymushi 发表于 2014-11-16 16:43:07

void Timer3_ISR (void) interrupt 14
{
   SMB0CF &= ~0x80;                  // Disable SMBus
   SMB0CF |= 0x80;                     // Re-enable SMBus
   TMR3CN &= ~0x80;                  // Clear Timer3 interrupt-pending flag
}

void PORT_Init (void)
{
   P0MDOUT = 0x00;                     // All P0 pins open-drain output
   XBR0 = XBR0|0x04;                        // Enable SMBus pins
   XBR1 = XBR0|0x40;                        // Enable crossbar and weak pull-ups

   P0 = 0xFF;
}
void smbusInit (void)
{
   PCA0MD &= ~0x40;                  // WDTE = 0 (Disable watchdog
                                       // timer)
   OSCICN = 0x83;           //选择内部时钟,分频系数是1
   OSCICN |= 0x03;                     // Set internal oscillator to highest
                                       // setting of 24500000

   PORT_Init();                        // Initialize Crossbar and GPIO
   //Timer1_Init();                      // Configure Timer1 for use
                                       // with SMBus baud rate

   //Timer3_Init ();                     // Configure Timer3 for use with
                                       // SCL low timeout detect

   SMBus_Init ();                      // Configure and enable SMBus

   EIE1 |= 0x01;                     // Enable the SMBus interrupt
   EA = 1;                           // Global interrupt enable
}
void SMBus_ISR (void) interrupt 7
{

   if (ARBLOST == 0)
   {
      switch (SMB0CN & 0xF0)         // Decode the SMBus status vector
      {
         // Slave Receiver: Start+Address received,收到起始信号和从机地址
         caseSMB_SRADD:
            STA = 0;                   // Clear STA bit
            if((SMB0DAT&0xFE) == (SLAVE_ADDR&0xFE)) // 地址过滤
                    {                        // If the received address matches,
                       ACK = 1;                // ACK the received slave address
                       if((SMB0DAT&0x01) == READ) // If the transfer is a master READ,
                               {
                        //smbDataRead(smbData,smbData);
                                                SMB0DAT = smbRecData;
                                                LED_SMB = ~LED_SMB;
                                                //smbIndex=0;
                               }
                    }
            else                     // If received slave address does not
                    {                        // match,
                       ACK = 0;                // NACK received address
                    }
            break;
         // Slave Receiver: Data received,从机接收到数据
         caseSMB_SRDB:
                           smbData=SMB0DAT;
                           smbIndex++;
               if(smbIndex>=NUM_BYTES_RD)//3位收全了
                             {
                                  //LED_SMB1 = ~LED_SMB1;
                                  smbIndex =0;
                                  smbReady=1;
                                  sendMsgRequest =1;
                                  //smbRecData = smbRecData|0x01;                                
                               }
                           ACK = 1;                // ACK received data
                                                             
                        //        if(1==smbDataWrite(smbData,smbData))
                        //           SMB0DAT = smbRecData;

            break;
         // Slave Receiver: Stop received while either a Slave Receiver or
         // Slave Transmitter,从机复位或者结束通信
         caseSMB_SRSTO:
            STO = 0;                   // STO must be cleared by software when a STOP is detected as a slave
            break;
         caseSMB_STDB: //从机发送完一个字节               
            if (ACK == 1)            // If Master ACK's, send the next byte
            {
             SMB0DAT = 0xaa;

            }
            break;
         // Slave Transmitter: Arbitration lost, Stop detected
         // This state will only be entered on a bus error condition.
         // In normal operation, the slave is no longer sending data or has
         // data pending when a STOP is received from the master, so the TXMODE
         // bit is cleared and the slave goes to the SRSTO state.
         caseSMB_STSTO://丢失,直接复位

            STO = 0;                   // STO must be cleared by software when a STOP is detected as a slave
            break;
         default: //其他情况直接复位

            SMB0CF &= ~0x80;         // Reset communication
            SMB0CF |= 0x80;
            STA = 0;
            STO = 0;
            ACK = 0;
            break;
      }
   }
   // ARBLOST = 1, Abort failed transfer
   else
   {
      STA = 0;
      STO = 0;
      ACK = 0;
   }

   SI = 0;                           // Clear SMBus interrupt flag
   
}

chwe1112 发表于 2016-8-24 00:15:08

喔,我现在用C8051F340,smbus寄存器跟C8051F300一样,没有地址寄存器SMB0ADR。我也想实现两片C8051F340的SMBUS的主从通信,不知道楼主是否已经调通。

yjamdfhqjs 发表于 2021-7-17 10:34:47

楼主现在调的怎么样了?

ANHOME 发表于 2021-7-17 11:41:28

yjamdfhqjs 发表于 2021-7-17 10:34
楼主现在调的怎么样了?

用硬件I2C做slave 从机,不更香吗?
如果非得要软件做,也是可以滴,只是比较麻烦一些。

yjamdfhqjs 发表于 2021-7-17 12:48:40

ANHOME 发表于 2021-7-17 11:41
用硬件I2C做slave 从机,不更香吗?
如果非得要软件做,也是可以滴,只是比较麻烦一些。 ...

你弄过吗 我两个都没做过

ANHOME 发表于 2021-7-17 13:18:16

yjamdfhqjs 发表于 2021-7-17 12:48
你弄过吗 我两个都没做过

是的,都做过。
页: [1]
查看完整版本: 有人使用过C8051F300的SMBUS模拟I2C从机么?