發新話題
打印

F380 SMbus1使用問題

F380 SMbus1使用問題

各位先進您好
小弟初次使用F380的SMBus1的功能, 先前都是使用F32X/34X的SMBus0做開發.

現在發現SMBus1在搭配Timer2使用上有無法產生中斷的問題, 不知道哪邊設定有問題???
若改用SMBUS0就可以動作, 有點奇怪.

我的設定如下:

1. 設定  XBR2 |= 0x02;        //enable SMBus I/O
2. 設定  Timer2   
3. Init SMBus1 為Slave device
   SMB1CF = 0x1F;
   SMB1CF |= 0x80;   // Enable SMBus
   EIE2 |= 0x08;    //Enable SMBus0 interrupt

4. Enable Timer2
5. void SMBus1_ISR (void) interrupt 18
{       
        SMBus_slaveIsrHook();       
}

void SMBus_slaveIsrHook(void)
{

        PrjBtnStatus.bits.SMBus1Test =1 ;
        if (ARBLOST1 == 0)
        {
                switch(SMB1CN & 0xF0)
                {          
        //*********************************************************************************
        //****** SMBus HOST is slave
                        case STDB:
                               
                       
                                if(ACK1 == 1)
                            {                               
                                        if(send_cnt < new_send_byte)  // transmitter next byte
                                        {                               
                                                SMB1DAT = KerSMBusslave.smb_data_out[send_cnt];                                                                                                                                          
                                                send_cnt++;
                                        }                                       
                            }               
                        break;               
       
                        case STSTO:        // detect an illegal stop or bus error               
                                STO1 = 0; // clear STO
                                send_cnt = 0;       
                        break;
                                       
                        case SRADD:        // Slave Receiver: Start+Address received                         
                                STA1 = 0;
                                KerSMBusslave.smb_data_in[0] = SMB1DAT;

                                if((KerSMBusslave.smb_data_in[0] & 0xFE) == 0x42)
                                {                                               
                                        ACK1 = 1;

                                        if(KerSMBusslave.smb_data_in[0] & 0x01 == 0x01)  // 0x73         // receive word start
                                        {                                                       
                                                ODM_SMBusSlaveService(KerSMBusslave.smb_data_in[1],KerSMBusslave.smb_data_in[2]);
                                                                                                                                                               
                                                SMB1DAT =  KerSMBusslave.smb_data_out[send_cnt]; // transmitter first byte
                                                send_cnt++;

                                        }                                                                                                                                       
                                }
                                else
                                {
                                        ACK1 = 0;
                                }                                                       
                                       
                        break;
               
                        case SRSTO:
                                STO1 = 0;
                                STA1 = 0;
                                ACK1 = 1;
                                for(i=0;i<send_byte;i++)
                                        KerSMBusslave.smb_data_out = 0;  // reset out data register
                                rec_cnt = 0;                   // reset receive counter
                                send_cnt=0;            // reset send counter                          
                        break;
               
                        case SRDB: // receive 1 2  byte
                               
                                if(rec_cnt < (receive_byte-1))
                                {                               

                                        KerSMBusslave.smb_data_in[rec_cnt+1] = SMB1DAT;       
                                                               
                                        rec_cnt++;                               
                                        ACK1 = 1;       


                                        if(KerSMBusslave.smb_data_in[2] == 0xE0)
                                                ODM_SMBusSlaveService(KerSMBusslave.smb_data_in[1],KerSMBusslave.smb_data_in[2]);                                               

                                }
                                                                                                                                                                       
                        break;
               
                        default:       
                                SMBusSlave.bits.fail = 1;  // failed       

                        break;               
                }
        }
        else  // ARBLOST = 1
        {
                SMBusSlave.bits.fail = 1;       
        }
    // After fail, reset SMBus         
        if(SMBusSlave.bits.fail)
        {
                SMB1CF &= ~0x80;  // Reset communication
            SMB1CF |= 0x80;          // Enable SMBus

                STA1 = 0; //start register
                STO1 = 0; //stop register
                ACK1 = 0; //        acknowledge

                SMBusSlave.bits.fail = 0; // clean 0
        }

        SI1 = 0;
}

TOP

Root cause在這...

14. Special Function Registers
The direct-access data memory locations from 0x80 to 0xFF constitute the special function registers
(SFRs). The SFRs provide control and data exchange with the C8051F380/1/2/3/4/5/6/7's resources and
peripherals. The CIP-51 controller core duplicates the SFRs found in a typical 8051 implementation as well
as implementing additional SFRs used to configure and access the sub-systems unique to the
C8051F380/1/2/3/4/5/6/7. This allows the addition of new functionality while retaining compatibility with the
MCS-51™ instruction set. Table 14.1 lists the SFRs implemented in the C8051F380/1/2/3/4/5/6/7 device
family.
The SFR registers are accessed anytime the direct addressing mode is used to access memory locations
from 0x80 to 0xFF. SFRs with addresses ending in 0x0 or 0x8 (e.g. P0, TCON, SCON0, IE, etc.) are bitaddressable
as well as byte-addressable. All other SFRs are byte-addressable only. Unoccupied
addresses in the SFR space are reserved for future use. Accessing these areas will have an indeterminate
effect and should be avoided. Refer to the corresponding pages of the data sheet, as indicated in
Table 14.2, for a detailed description of each register.
14.1. 13.1. SFR Paging
The CIP-51 features SFR paging, allowing the device to map many SFRs into the 0x80 to 0xFF memory
address space. The SFR memory space has 256 pages. In this way, each memory location from 0x80 to
0xFF can access up to 256 SFRs. The C8051F380/1/2/3/4/5/6/7 devices utilize two SFR pages: 0x0, and
0xF. Most SFRs are available on both pages. SFR pages are selected using the Special Function Register
Page Selection register, SFRPAGE. The procedure for reading and writing an SFR is as follows:
1. Select the appropriate SFR page number using the SFRPAGE register.
2. Use direct accessing mode to read or write the special function register (MOV instruction).

TOP

發新話題