/********************************************************************************************************
*
* 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
*http://www.waveshare.net
*All Rights Reserved
*
*********************************************************************************************************/
#ifndef _WS_IIC_PORT_H_
#define _WS_IIC_PORT_H_
#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*/
#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.
#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 Enb_Interrupt(void)
{
EIE1 |= 0x01; // Enable the SMBus interrupt
EA = 1; // Global interrupt enable
}
#else
#warning "iic interface undefined."
#endif
#include <../../../../library/C8051F/ws_iic.h>
#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
*http://www.waveshare.net
*All Rights Reserved
*
*********************************************************************************************************/
#ifndef _WS_IIC_H_
#define _WS_IIC_H_
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define WRITE 0x00 // SMBus WRITE command
#define READ 0x01 // SMBus READ command
// Status vector - top 4 bits only
#define SMBus_MTSTA 0xE0 // (MT) start transmitted
#define SMBus_MTDB 0xC0 // (MT) data byte transmitted
#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
}
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
}
#endif /*_WS_IIC_H_*/
Previous article:Using PCF8574 to expand the I/O port of C8051F
Next article:Using 74LS165 to expand C8051F's serial port input to parallel port input
Recommended ReadingLatest update time:2024-11-23 06:20
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- A new type of microstrip array antenna
- EEWORLD University ---- ESP32 Video Tutorial
- How to purchase website core points?
- Mobile TV: Who will take the helm of the “mobile angel”?
- Substation Monitoring System Based on CAN Bus
- Can this zero-crossing detection realize zero-crossing detection in two directions? What is the working principle?
- FPGA Design Skills and Case Development Detailed Explanation (2nd Edition)
- [Raspberry Pi 4B Review] Installing the router system OpenWrt on Raspberry Pi 4
- Hiring embedded software engineer
- Chapter 2: Creation of Development Environment