I2C.h
#define AT24C64NW 0xA0
#define AT24C64NR 0xA1
#define MAX_TIMEOUT 0x00FFFFFF
#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */
#define I2CONSET_AA 0x00000004
#define I2CONSET_SI 0x00000008
#define I2CONSET_STO 0x00000010
#define I2CONSET_STA 0x 00000020
#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */
#define I2CONCLR_SIC 0x00000008
#define I2CONCLR_STAC 0x00000020
#define I2CONCLR_I2ENC 0x00000040
#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
#define I2SCLH_SCLH 0x00000080 /* I2C SCL Duty Cycle High Reg */
#define I2SCLL_SCLL 0x00000080 /* I2C SCL Duty Cycle Low Reg * /
#define SDA0 0x08000000 //p0.27
#define SCL0 0x10000000 //p0.28
#define SDA0CON 0x08000000
#define SCL0CON 0x10000000
extern DWORD I2CInit( UINT32 Fi2c );
extern DWORD I2CStart( void );
extern DWORD I2CS top( void );
extern DWORD I2CStartAgain( void );
extern DWORD I2C_ReadByte(BYTE ACK, BYTE *RcvData);
extern DWORD I2C_SendNByte(UINT16 SubAddr,UINT8 *Data,UINT8 Length);
extern DWORD I2C_ReadNByte(UINT16 SubAddr,UINT8 *Data,UINT8 Length);
I2C.c
DWORD I2CInit( UINT32 Fi2c )
{
if (Fi2c > 400000)
Fi2c = 400000;
PINSEL1 &= ~0x03C00000;
PINSEL1 |= 0x01400000; /* set PIO0.27 and PIO0.28 to I2C0 SDA and SCK */
I20SCLH = (Fpclk/Fi2c + 1) / 2; /* Set I2C clock */
I20SCLL = (Fpclk/Fi2c)/2;
I20CONCLR = 0x2C;//clear STA, SI,AA
I20CONSET = 0x40; // SET I2EN /* Enable master I2C */
return( TRUE );
}
DWORD I2CStart( void )
{
DWORD timeout = 0;
DWORD returnValue = FALSE;
/*--- Issue a start condition ---*/
I20CONCLR=I2CONCLR_SIC|I2CONCLR_AAC|I2CONCLR_STAC;
I20CONSET=I2CONSET_STA|I2CONSET_I2EN; /* Set Start flag */
/*--- Wait until START transmitted ---*/
while( 1 )
{
if (I20STAT==0x08)
{
returnValue = TRUE;
break;
}
if ( timeout >= MAX_TIMEOUT )
{
returnValue = FALSE;
break;
}
timeout++;
}
return(returnValue);
}
DWORD I2CStartAgain( void )
{
DWORD timeout = 0;
DWORD returnValue = FALSE;
/*--- Issue a start condition ---*/
I20CONCLR = I2CONCLR_SIC|I2CONCLR_AAC|I2CONCLR_STAC; // Be sure to clear SI before sending a repeated start condition
I20CONSET = I2CONSET_STA|I2CONSET_I2EN; /* Set Start flag */
/*--- Wait until START transmitted ---*/
while( 1 )
{
if ( I20STAT == 0x10 )
{
returnValue = TRUE;
break;
}
if ( timeout >= MAX_TIMEOUT )
{
returnValue = FALSE;
break;
}
timeout++;
}
return(returnValue);
}
DWORD I2CStop( void )
{
I20CONSET = I2CONSET_STO; /* Set Stop flag */
I20CONCLR = I2CONCLR_SIC|I2CONCLR_STAC|I2CONCLR_AAC; /* Clear SI flag */// modified
/*--- Wait for STOP detected ---*/
while( I20CONSET & I2CONSET_STO );
return TRUE;
}
void I2C_SendByte(UINT8 SData)
{
I20DAT=SData;
I20CONCLR =0x28; /* Clear SI, STA */
while (!(I20CONSET&I2CONCLR_SIC));// wait interrupt flag (waiting for SI==1)
}
DWORD I2C_SendNByte(UINT16 SubAddr,UINT8 *Data,UINT8 Length)
{
BYTE i;
I2CStart();
if(I20STAT==0x08) /* Start condition has been sent */
{
I2C_SendByte(AT24C64NW); // Device Address
if(I20STAT==0x18) /* SLA+W has been sent, ACK has been received */
{
I2C_SendByte((SubAddr>>8)&(0x00FF));
if(I20STAT==0x28) /* SubAddr_H has been sent, ACK has been received */
{
I2C_SendByte(SubAddr&(0x00FF));
if(I20STAT==0x28) /* SubAddr_L has been sent, ACK has been received */
{
for(i=0;i { do{ I2C_SendByte(Data[i]); }while(I20STAT!=0x28); } if(I2CStop()) { DelayNS(5); //10ms return TRUE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } DWORD I2C_ReadByte(BYTE ACK, BYTE *RcvData) { if (ACK==1) // send ACK { I20CONSET=I2CONSET_AA; } else // send NOACK if(ACK==0) { I20CONCLR=I2CONCLR_AAC; } I20CONCLR=I2CONCLR_SIC|I2CONCLR_STAC; // clear SI SAT while (!(I20CONSET&I2CONCLR_SIC));// wait interrupt flag (waiting for SI==1) if(ACK==1) { if((I20STAT&0xF8)==0x50) // receive data and get ack { *RcvData=I20DAT; return TRUE; } else return FALSE ; } else if(ACK==0) { if((I20STAT&0xF8)==0x58) // receive data and get NoAck (the last data you want to get) { *RcvData=I20DAT; return TRUE; } else return FALSE ; } return FALSE ; } DWORD I2C_ReadNByte(UINT16 SubAddr,UINT8 *Data,UINT8 Length) { BYTE i; if (!I2CStart()) { return FALSE; } if(I20STAT==0x08) /* Start condition has been sent */ { I2C_SendByte(AT24C64NW); // Device Address if(I20STAT==0x18) /* SLA+W has been sent, ACK has been received */ { I2C_SendByte((SubAddr>>8)&(0x00FF)); if(I20STAT==0x28) /* SubAddr_H has been sent, ACK has been received */ { I2C_SendByte(SubAddr&(0x00FF)); if(I20STAT==0x28) /* SubAddr_L has been sent, ACK has been received */ { if (I2CStartAgain()) //Send repeated start condition to switch to master receiving mode { I2C_SendByte(AT24C64NR); if(I20STAT==0x40)/*SLA+R sent, ACK received*/ { for(i=0;i { if(!(I2C_ReadByte(1,&Data[i]))) { return FALSE; } } if( !( I2C_ReadByte(0, &Data[Length-1]) ) ) //Read the last data { return FALSE; } if (I2CStop()) //Send stop condition { return TRUE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; } return FALSE; }
Previous article:Immediate values in ARM assembly
Next article:ADC function implementation of LPC23xx
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Tube Amplifiers (4th Edition)
- Is it feasible to use a digital bridge to measure the resistance of a hygroscopic resistor to indicate humidity?
- PADS to AD
- [SAMR21 New Gameplay] 33. RTC
- [NXP Rapid IoT Review] Rapid IoT Studio online IDE User Experience
- EEWORLD University Hall -- Disassembly of 3 Economical Digital Multimeters
- Topway Smart Screen: Latest "TOPWAY-SmartLCD-User-Handbook-SGTools-cn"
- Which circuit simulation software is the best? Which one do you use most often?
- CircuitPython Digital Clock
- (Take STM8/STM32 as an example) What is the significance of hardware i2c spi?