“C8051F I2C(SMBus)程序”的版本间的差异

来自丢石头百科
(/********************************************************************************************************** File : ws_iic_port.h* Hardware Environment:* Build Environment : Silicon LABs 3.42.00 / uVis ...)
 
(文本替换 - 替换“www.waveshare.net”为“{{SERVERNAME}}”)
第11行: 第11行:
 
*
 
*
 
*                                                          (c) Copyright 2005-2010, WaveShare
 
*                                                          (c) Copyright 2005-2010, WaveShare
*                                                                     <a class="Blue_2_12px_" href="http://www.waveshare.net/" style="color: rgb(7, 66, 184);" target="_blank">http://www.waveshare.net
+
*                                                                     <a class="Blue_2_12px_" href="http://{{SERVERNAME}}/" style="color: rgb(7, 66, 184);" target="_blank">http://{{SERVERNAME}}
  
 
*                                                                         All Rights Reserved
 
*                                                                         All Rights Reserved
第101行: 第101行:
 
*
 
*
 
*                                                          (c) Copyright 2005-2010, WaveShare
 
*                                                          (c) Copyright 2005-2010, WaveShare
*                                                                     <a class="Blue_2_12px_" href="http://www.waveshare.net/" style="color: rgb(7, 66, 184);" target="_blank">http://www.waveshare.net
+
*                                                                     <a class="Blue_2_12px_" href="http://{{SERVERNAME}}/" style="color: rgb(7, 66, 184);" target="_blank">http://{{SERVERNAME}}
  
 
*                                                                         All Rights Reserved
 
*                                                                         All Rights Reserved

2019年11月19日 (二) 09:21的版本

<tbody></tbody>

/********************************************************************************************************

  • File : ws_iic_port.h
  • Hardware Environment: 
  • Build Environment : Silicon LABs 3.42.00 / uVision3 V3.80 20100913
  • Version : 
  • By : Su Wei Feng
  •                                                           (c) Copyright 2005-2010, WaveShare
  •                                                                      <a class="Blue_2_12px_" href="http://wiki.diustou.com/" style="color: rgb(7, 66, 184);" target="_blank">http://wiki.diustou.com
  •                                                                          All Rights Reserved
                                                                                                                                                                                                                  • /
  1. ifndef _WS_IIC_PORT_H_
  2. define _WS_IIC_PORT_H_
  3. define SMB_FREQUENCY 100000 // Target SCL clock rate

// This example supports in 100kHz void SMBus_Init(void); void Check_SDA(void); void SMBus_Write(uint wrDAdr,uchar Data1,uchar Data2,uchar Num); void SMBus_Read(uint wrDAdr,uchar *Data,uchar Num); /*Hardware Environment:DVK501 && F320+ EX*/

  1. if defined(_DVK501_F320_EX_)

void Timer1_Init(void); void Timer3_Init(void); void Enb_Interrupt(void); void SMBus_ISR(void); void Timer3_ISR(void); // 16-bit SFR declarations sfr16 TMR3RL = 0x92; // Timer3 reload registers sfr16 TMR3 = 0x94; // Timer3 counter registers sbit SDA = P1^0; // SMBus on P1.0 sbit SCL = P1^1; // and P1.1 void SMBus_Init(void)  { XBR0 |= 0x07; // Enable SMBus pins P1MDOUT = 0x00; // All P1 pins open-drain output P1 = 0xFF; SMB0CF = 0x5D; // Use Timer1 overflows as SMBus clock source; // Disable slave mode; // Enable setup & hold time extensions; // Enable SMBus Free timeout detect; // Enable SCL low timeout detect; SMB0CF |= 0x80; // Enable SMBus  Timer1_Init(); Timer3_Init(); } 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.

  1. if ((SYSCLK/SMB_FREQUENCY/3) < 255)
  2. define SCALE 1

CKCON |= 0x08; // Timer1 clock source = SYSCLK

  1. elif ((SYSCLK/SMB_FREQUENCY/4/3) < 255)
  2. define SCALE 4

CKCON |= 0x01; CKCON &= ~0x0A; // Timer1 clock source = SYSCLK / 4

  1. 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 Enb_Interrupt(void) { EIE1 |= 0x01; // Enable the SMBus interrupt EA = 1; // Global interrupt enable }

  1. else
  2. warning "iic interface undefined."
  3. endif
  4. include <../../../../library/C8051F/ws_iic.h>
  5. endif /*_WS_IIC_PORT_H_*/

  /********************************************************************************************************

  • File : ws_iic.h
  • Hardware Environment: 
  • Build Environment : Silicon LABs 3.42.00 / uVision3 V3.80 20100913
  • Version : 
  • By : Su Wei Feng
  •                                                           (c) Copyright 2005-2010, WaveShare
  •                                                                      <a class="Blue_2_12px_" href="http://wiki.diustou.com/" style="color: rgb(7, 66, 184);" target="_blank">http://wiki.diustou.com
  •                                                                          All Rights Reserved
                                                                                                                                                                                                                  • /
  1. ifndef _WS_IIC_H_
  2. define _WS_IIC_H_

//----------------------------------------------------------------------------- // Global CONSTANTS //-----------------------------------------------------------------------------

  1. define WRITE 0x00 // SMBus WRITE command
  2. define READ 0x01 // SMBus READ command

// Status vector - top 4 bits only

  1. define SMBus_MTSTA 0xE0 // (MT) start transmitted
  2. define SMBus_MTDB 0xC0 // (MT) data byte transmitted
  3. define SMBus_MRDB 0x80 // (MR) data byte received

// End status vector definition //----------------------------------------------------------------------------- // Global VARIABLES //----------------------------------------------------------------------------- unsigned char SMBus_DATA_IN[3]; // Global holder for SMBus data // All receive data is written here unsigned char SMBus_DATA_OUT[2]; // Global holder for SMBus data. // All transmit data is read from here unsigned char COMMAND,num[2]; // Target SMBus slave address bit SMBus_BUSY; // Software flag to indicate when the // SMB_Read() or SMB_Write() functions // have claimed the SMBus bit SMBus_WR; // SMBus READ or WRITE, 0 is READ, 1 is WRITE //----------------------------------------------------------------------------- // Check_SDA //----------------------------------------------------------------------------- // If slave is holding SDA low because of an improper SMBus reset or error void Check_SDA(void) {  uchar i; // Dummy variable counters while(!SDA) { // Provide clock pulses to allow the slave to advance out // of its current state. This will allow it to release SDA. XBR1 = 0x40; // Enable Crossbar SCL = 0; // Drive the clock low for(i = 0; i < 255; i++); // Hold the clock low SCL = 1; // Release the clock while(!SCL); // Wait for open-drain // clock output to rise for(i = 0; i < 10; i++); // Hold the clock high XBR1 = 0x00; // Disable Crossbar } } //----------------------------------------------------------------------------- // wrDAdr:I2C address // dat:I2C data //----------------------------------------------------------------------------- void SMBus_Write(uint wrDAdr,uchar Data1,uchar Data2,uchar Num) { while(SMBus_BUSY); // Wait for SMBus to be free. SMBus_BUSY = 1; // Claim SMBus (set to busy) COMMAND = wrDAdr;  SMBus_DATA_OUT[0] = Data1; SMBus_DATA_OUT[1] = Data2; num[0] = Num; SMBus_WR = 0; STO = 0; STA = 1; // Start transfer while(SMBus_BUSY); // Wait for SMBus to be free. } //----------------------------------------------------------------------------- // wrDAdr:I2C address //----------------------------------------------------------------------------- void SMBus_Read(uint wrDAdr,uchar *Data,uchar Num) { uchar i; while(SMBus_BUSY); // Wait for bus to be free. SMBus_BUSY = 1; // Claim SMBus (set to busy) COMMAND = wrDAdr; num[1] = Num; SMBus_WR = 1; STO = 0; STA = 1; // Start transfer  while(SMBus_BUSY); // Wait for transfer to complete for(i=0;i<Num;i++) Data[i] = SMBus_DATA_IN[i]; } void SMBus_ISR(void) interrupt 7 { bit FAIL = 0; // Used by the ISR to flag failed transfers static uchar sent_byte_counter,rec_byte_counter; if (ARBLOST == 0) // Check for errors { // Normal operation switch (SMB0CN & 0xF0) // Status vector { // Master Transmitter/Receiver: START condition transmitted. case SMBus_MTSTA: { SMB0DAT = COMMAND; // Load address of the target slave STA = 0; // Manually clear START bit sent_byte_counter = 1; rec_byte_counter = 1;  break; } // Master Transmitter: Data byte transmitted case SMBus_MTDB: { if (ACK) // Slave ACK? { if (SMBus_WR == WRITE) // If this transfer is a WRITE, { if (sent_byte_counter <= num[0]) { // send data byte SMB0DAT = SMBus_DATA_OUT[sent_byte_counter-1]; sent_byte_counter++; } else { STO = 1; // Set STO to terminate transfer SMBus_BUSY = 0; // And free SMBus interface } } } else // If slave NACK, { STO = 1; // Send STOP condition, followed STA = 1; // By a START } break; } // Master Receiver: byte received case SMBus_MRDB: {  if (rec_byte_counter < num[1]) { SMBus_DATA_IN[rec_byte_counter-1] = SMB0DAT; // Store received byte ACK = 1; // Send ACK to indicate byte received rec_byte_counter++; // Increment the byte counter } else { SMBus_DATA_IN[rec_byte_counter-1] = SMB0DAT; // Store received byte SMBus_BUSY = 0; // Free SMBus interface ACK = 0; // Send NACK to indicate last byte of this transfer STO = 1; // Send STOP to terminate transfer } break; } default: { FAIL = 1; // Indicate failed transfer and handle at end of ISR break; } } // end switch } else { // ARBLOST = 1, error occurred... abort transmission FAIL = 1; } // end ARBLOST if if (FAIL) // If the transfer failed, { SMB0CF &= ~0x80; // Reset communication SMB0CF |= 0x80; STA = 0; STO = 0; ACK = 0; SMBus_BUSY = 0; // Free SMBus } SI = 0; // Clear interrupt flag } void Timer3_ISR(void) interrupt 14 { SMB0CF &= ~0x80; // Disable SMBus SMB0CF |= 0x80; // Re-enable SMBus TMR3CN &= ~0x80; // Clear Timer3 interrupt-pending flag STA = 0; SMBus_BUSY = 0; // Free SMBus }

  1. endif /*_WS_IIC_H_*/