⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 I2c code for LPC2148
💻 C
字号:
/*
Important information of i2c
From the LPC2148 User Manual section 11.7.8:

I2C Bit Frequency = PCLK / (I2CSCLH + I2CSCLL)

PCLK is whatever you set it to when you set up when you set up VPBDIV
but that is based on CCLK which is set to some multiple of the crystal
frequency when you set up PLL0.

So, maybe the crystal is 12 MHz and the PLL multiplies by 5 so CCLK is
60 MHz. Then maybe VPBDIV is set to divide by 4 (if that is what you
want; it can divide by 1, 2 or 4) so PCLK is 15 MHz.

Now, maybe you want 100 kHz for the I2C bit frequency (slow I2C) so:

100,000 = (15000000) / (I2CSCLH + I2CSCLL)

400,000 = (30000000) / (I2CSCLH + I2CSCLL)

Then I2CSCLH + I2CSCLL = 30000000 / 400000 or 75.

100,000 = (30000000) / (I2CSCLH + I2CSCLL)

Then I2CSCLH + I2CSCLL = 30000000 / 100000 or 300.


Then is no reason the 2 values aren't the same so set them both for 75
to get 50% duty cycle on the clock. For a 400 kHz I2C, you need to
read the I2C spec to get the proper duty cycle. Google for it.

It all ties together but you have to start with crystal freq -> PLL
multiplication to get CCLK -> VPBDIV to get PCLK -> desired I2C clock
rate to get (I2CSCLH + I2CSCLL) -> I2C Spec to get the required duty
cycle if the I2C bit rate is not 100 kHz.
*/


#include "LPC21xx.h"
#include "i2c.h"
#include "myLib.h"
#include "uart.h"


/*
#define I2CONSET        I2C->conset     // Control Set Register 
#define I2STAT          I2C->stat       // Status Register 
#define I2DAT           I2C->dat        // Data Register 
#define I2ADR           I2C->adr        // Slave Address Register 
#define I2SCLH          I2C->sclh       // SCL Duty Cycle Register (high half word)
#define I2SCLL          I2C->scll       // SCL Duty Cycle Register (low half word) 
#define I2CONCLR        I2C->conclr     // Control Clear Register 
*/
void InitEEPROM(void)
{
//	PCONP |= 0x00000080; //turn on power to I2C
	PINSEL0 = (PINSEL0 & ~I2C_PINMASK) | I2C_PINSEL;
	I2SCLH = 24;
	I2SCLL = 50;
	I2CONCLR = I2C_STA | I2C_STO | I2C_SI | I2C_AA;
	I2CONSET = I2C_EN;
}//InitEEPROM


void AddressEEPROM(unsigned char ChipID, unsigned short Address)
{
	do {
			I2CONSET = I2C_STA | I2C_SI;	//setup start condition
			I2CONCLR = I2C_SI;				//send start condition
			while (~I2CONSET & I2C_SI);		//wait for start to be sent
			I2DAT = EEPROM_WRITE | (ChipID & 0x7) << 1; //load the EEPROM address
			I2CONCLR = I2C_STA | I2C_SI;	//send EEPROM address
			while (~I2CONSET & I2C_SI);		//wait for address to be sent
	}while (I2STAT != 0x18);				//repeat if no ACK received
	I2DAT = (Address >> 8) & 0xFF;			//load high address
	I2CONCLR = I2C_SI;						//send data
	while (~I2CONSET & I2C_SI);				//wait
	I2DAT = Address & 0xFF;					//load low address
	I2CONCLR = I2C_SI;						//send data
	while (~I2CONSET & I2C_SI);				//wait
}//AddressEEPROM

void WriteEEPROM(unsigned char ChipID, unsigned short Address, unsigned char Data)
{
	AddressEEPROM(ChipID, Address);
	I2DAT = Data;							//load data
	I2CONCLR = I2C_SI;						//send data
	while (~I2CONSET & I2C_SI);				//wait for data to be sent
	I2CONSET = I2C_STO;						//setup stop condition
	I2CONCLR = I2C_SI;						//start sending stop
	while (I2CONSET & I2C_STO);				//wait for stop to be sent
}//WriteEEPROM

unsigned char ReadEEPROM (unsigned char ChipID)
{
	unsigned char Data;
	
	do 
	{
		I2CONSET = I2C_STA | I2C_SI;		//setup start condition
		I2CONCLR = I2C_SI;					//send start condition
		while (~I2CONSET & I2C_SI);			//wait for start to be sent
		I2DAT = EEPROM_READ|(ChipID&0x07)<<1;//load address of eeprom
		I2CONCLR = I2C_STA | I2C_SI;		//start sending address
		while (~I2CONSET & I2C_SI);			//wait for address to be sent
	} while (I2STAT != 0x40);				//repeat if no ack received
	I2CONCLR = I2C_SI;						//start reading data
	while (~I2CONSET & I2C_SI);				//wait for data to be received
	Data = I2DAT;
	I2CONSET = I2C_STO;						//setup stop condition
	I2CONCLR = I2C_SI;						//send stop condition
	while (I2CONSET & I2C_STO);				//wait for stop to be sent
	return Data;							//return the data
}//ReadEEPROM

unsigned long SizeEEPROM (unsigned char ChipID)
{
	//This function returns the size of the EEPROM, in bytes
	unsigned char TestByte;
	unsigned long AddressPtr = 0x20000;

	I2CONSET = I2C_STA | I2C_SI;			//setup start condition
	I2CONCLR = I2C_SI;						//send start condition
	while (~I2CONSET & I2C_SI);				//wait for start to be sent
	I2DAT = EEPROM_WRITE | (ChipID & 0x7) << 1; //load the EEPROM address
	I2CONCLR = I2C_STA | I2C_SI;			//send EEPROM address
	while (~I2CONSET & I2C_SI);				//wait for address to be sent
	if (I2STAT != 0x18)						//if chip does not ACK
		return 0;
	I2DAT = 0x00;							//load high address
	I2CONCLR = I2C_SI;						//send data
	while (~I2CONSET & I2C_SI);				//wait
	I2DAT = 0x00;							//load low address
	I2CONCLR = I2C_SI;						//send data
	while (~I2CONSET & I2C_SI);				//wait
	TestByte = ~ReadEEPROM(ChipID);
	WriteEEPROM(ChipID, 0x0000, TestByte);

	do {
		AddressPtr >>=1;
		AddressEEPROM(ChipID, AddressPtr);
	} while (TestByte == ReadEEPROM(ChipID));

	TestByte = ~TestByte;
	WriteEEPROM(ChipID, 0x0000, TestByte);

	do {
		AddressPtr <<= 1;
		AddressEEPROM(ChipID, AddressPtr);
	} while (TestByte != ReadEEPROM(ChipID));

	return AddressPtr;
}//SizeEEPROM


void testEEPROM(void)
{
	WriteEEPROM(0,0,0xB5);
	WriteEEPROM(0,1,'W');
	WriteEEPROM(0,2,'I');
	WriteEEPROM(0,3,'P');

	uart0Puts("Data Write Successfully\r\n");
	dlay(1000);

	AddressEEPROM(0,0);
	if (ReadEEPROM(0)==0xB5)
	{
		uart0Puts("First\r\n");
		if (ReadEEPROM(0)== 'W')
		{
			uart0Puts("Second\r\n");
			if (ReadEEPROM(0)== 'I')
			{
				uart0Puts("Third\r\n");
				if (ReadEEPROM(0)== 'P')
				{
					uart0Puts("EEPROM Tested \r\n");
				}
			}
		}
	}			
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -