|
楼主 |
发表于 2014-7-5 10:09:49
|
显示全部楼层
- #include <C8051F350.h>
- bit flag_timer3;
- unsigned char smbusdata;
- bit DATA_READY = 0;
- #define WRITE 0x00 // SMBus WRITE command
- #define READ 0x01 // SMBus READ command
- #define SLAVE_ADDR 0xF0 // Device addresses (7 bits,
- // lsb is a don't care)
- // Status vector - top 4 bits only
- #define SMB_SRADD 0x20 // (SR) slave address received
- // (also could be a lost
- // arbitration)
- #define SMB_SRSTO 0x10 // (SR) STOP detected while SR or ST,
- // or lost arbitration
- #define SMB_SRDB 0x00 // (SR) data byte received, or
- // lost arbitration
- #define SMB_STDB 0x40 // (ST) data byte transmitted
- #define SMB_STSTO 0x50 // (ST) STOP detected during a
- // transaction; bus error
- // End status vector definition
- #define SYSCLK 24500000 // System clock frequency in Hz
- #define SMB_FREQUENCY 10000
- // 16-bit SFR declarations
- sfr16 TMR3RL = 0x92; // Timer3 reload registers
- sfr16 TMR3 = 0x94; // Timer3 counter registers
- void Port_Init()
- {
- P0MDOUT = 0x00; // All P0 pins open-drain output
- XBR0 = 0x04; // Enable SMBus pins
- XBR1 = 0x40; // Enable crossbar and weak pull-ups
- P0 = 0xFF;
- }
- void Timer1_Init (void)
- {
- // Make sure the Timer can produce the appropriate frequency in 8-bit mode
- // Supported SMBus Frequencies range from 10kHz to 100kHz. The CKCON register
- // settings may need to change for frequencies outside this range.
- #if ((SYSCLK/SMB_FREQUENCY/3) < 255)
- #define SCALE 1
- CKCON |= 0x08; // Timer1 clock source = SYSCLK
- #elif ((SYSCLK/SMB_FREQUENCY/4/3) < 255)
- #define SCALE 4
- CKCON |= 0x01;
- CKCON &= ~0x0A; // Timer1 clock source = SYSCLK / 4
- #endif
- TMOD = 0x20; // Timer1 in 8-bit auto-reload mode
- // Timer1 configured to overflow at 1/3 the rate defined by SMB_FREQUENCY
- TH1 = -(SYSCLK/SMB_FREQUENCY/SCALE/3);
- TL1 = TH1; // Init Timer1
- TR1 = 1; // Timer1 enabled
- }
- void Timer3_Init (void)
- {
- TMR3CN = 0x00; // Timer3 configured for 16-bit auto-
- // reload, low-byte interrupt disabled
- CKCON &= ~0x40; // Timer3 uses SYSCLK/12
- TMR3RL = -(SYSCLK/12/40); // Timer3 configured to overflow after
- TMR3 = TMR3RL; // ~25ms (for SMBus low timeout detect):
- // 1/.025 = 40
- EIE1 |= 0x80; // Timer3 interrupt enable
- TMR3CN |= 0x04; // Start Timer3
- }
- void SMBus_Init (void)
- {
- SMB0CF = 0x1D; // Use Timer1 overflows as SMBus clock
- // source;
- // Enable slave mode;
- // Enable setup & hold time
- // extensions;
- // Enable SMBus Free timeout detect;
- // Enable SCL low timeout detect;
- SMB0CF |= 0x80; // Enable SMBus;
- }
- void main()
- {
- PCA0MD &= ~0x40; //禁止看门狗
- OSCICN |= 0x03; //时钟设置成24.5MHZ
- Port_Init();
- Timer3_Init(); //定时器3超时检测
- Timer1_Init(); //timer1配置成SCL时钟
- SMBus_Init();
- EIE1 |= 0x01;
- EA = 1; //全局中断使能
- smbusdata = 0xFD; //初始化SMBUS数据
- while(1)
- {
- if(flag_timer3==1)
- {
- flag_timer3=0;
- }
- }
- }
- void Timer3_ISR (void) interrupt 14
- {
- // TMR3 = -(SYSCLK/12/40);
- SMB0CF &= ~0x80; // Disable SMBus
- SMB0CF |= 0x80; // Re-enable SMBus
- TMR3CN &= ~0x80; // Clear Timer3 interrupt-pending flag
- flag_timer3=1;
- }
- void SMBus_ISR (void) interrupt 7
- {
- if (ARBLOST == 0)
- {
- switch (SMB0CN & 0xF0) // Decode the SMBus status vector
- {
- // Slave Receiver: Start+Address received
- case SMB_SRADD:
- STA = 0; // Clear STA bit
- if((SMB0DAT&0xFE) == (SLAVE_ADDR&0xFE)) // Decode address
- { // If the received address matches,
- ACK = 1; // ACK the received slave address
- if((SMB0DAT&0x01) == READ) // If the transfer is a master READ,
- {
- SMB0DAT = 0x41; // Prepare outgoing byte
- }
- }
- else // If received slave address does not
- { // match,
- ACK = 0; // NACK received address
- }
- break;
- // Slave Receiver: Data received
- case SMB_SRDB:
- smbusdata = SMB0DAT; // Store incoming data
- DATA_READY = 1; // Indicate new data received
- ACK = 1; // ACK received data
- break;
- // Slave Receiver: Stop received while either a Slave Receiver or
- // Slave Transmitter
- case SMB_SRSTO:
- STO = 0; // STO must be cleared by software when
- // a STOP is detected as a slave
- break;
- // Slave Transmitter: Data byte transmitted
- case SMB_STDB:
- // No action required;
- // one-byte transfers
- // only for this example
- 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.
- case SMB_STSTO:
- STO = 0; // STO must be cleared by software when
- // a STOP is detected as a slave
- break;
- // Default: all other cases undefined
- 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
- }
复制代码
终于给我研究出来了!
有几个地方我给大家提示一下哈, |
|