📄 main.c
字号:
/************************************************************/
/* PROJECT NAME: I2C */
/* Project: LPC2100 Training course */
/* Engineer: T Martin tmartin@hitex.co.uk */
/* Filename: MAIN.C */
/* Language: C */
/* Compiler: Keil ARM V1.3 */
/* Assembler: */
/* */
/************************************************************/
/* COPYRIGHT: Hitex UK Ltd 2004 */
/* LICENSE: THIS VERSION CREATED FOR FREE DISTRIBUTION */
/************************************************************/
/* Function: */
/* */
/* Interrupt driven I2C example for LPC2106 */
/* */
/* The Transfer byte routine starts a single byte transfer */
/* on the I2C bus. The development board has two port */
/* expanders one at address 0x42 with a 7 segment LCD a */
/* second at 0x41 with a four switch header. The code reads */
/* the switches and writes the pattern to the LED's */
/* */
/* Oscillator frequency 14.7456 Mhz */
/* Target board Ashling EVBA7 */
/************************************************************/
#include <LPC210x.H>
#include <stdarg.h>
void I2CISR (void) __irq ; //I2C interrupt routine
void I2CTransferByte(unsigned int I2CAddr,unsigned char MemAddr,unsigned char count,...); //Background call to start master send and receive byte transfers
unsigned char message[4] = {0x01,0x02,0x03,0x04};
unsigned char messageIn[4];
unsigned char *I2CData,
I2Counter,
I2CAddress,
MemAddress,
lock; //Define Function prototypes and Global variables
int main(void)
{
lock = 0; //Initilise the lock flag
VICVectCntl1 = 0x00000029; //select a priority slot for a given interrupt
VICVectAddr1 = (unsigned)I2CISR; //pass the address of the IRQ into the VIC slot
VICIntEnable = 0x00000200; //enable interrupt
PINSEL0 = 0x50; //Switch GPIO to I2C pins
I2SCLH = 0x08; //Set bit rate 14.7456Mhz/VPBDIV+SCLH+SCLL = 14.7456/4+8+8 = 57.6Khz
I2SCLL = 0x08;
I2CTransferByte(0x40,0,4,message); //write data to the I2C Memory
I2CTransferByte(0x40,0,0); //set address to zero
I2CTransferByte(0x41,0,4,messageIn); //read back data
while(1)
{
;
}
}
void I2CTransferByte(unsigned int I2CAddr,unsigned char MemAddr,unsigned char count,...)
{
va_list ap;
va_start(ap,count);
while(lock == 1) //Wait for interrupt to signal end of I2C activity
{
;
}
lock = 1; //Set I2C bus as active
I2CAddress = I2CAddr; //Place address and data in Globals to be used by the interrupt
if(count >0)
{
I2CData = va_arg(ap,unsigned char *);
}
I2Counter = count;
MemAddress = MemAddr;
I2CONCLR = 0x000000FF; //Clear all I2C settings
I2CONSET = 0x00000040; //Enable the I2C interface
I2CONSET = 0x00000020; //Start condition
va_end(ap);
}
void I2CISR (void) __irq //I2C interrupt routine
{
switch (I2STAT) //Read result code and switch to next action
{
// Start and Send byte conditions
case ( 0x08): //Start bit
I2CONCLR = 0x20; //Clear start bit
I2DAT = I2CAddress; //Send address and write bit
break;
case (0x18): //Slave address+W, ACK
I2DAT = MemAddress; //Write Mem,ory start address to tx register
break;
case (0x20): //Salve address +W, Not ACK
I2DAT = I2CAddress; //Resend address and write bi
break;
case (0x28):
if(I2Counter-->0) //Data sent, Ack
{
I2DAT = *I2CData; //Write data to tx register
I2CData++;
}
else
{
I2CONSET = 0x10; //Stop condition
lock = 0; //Signal end of I2C activity
}
break;
case (0x30) : //Data sent, NOT Ack
I2DAT = *I2CData; //Write data to tx register
break;
//Receive byte conditions
case (0x40) : //Slave Address +R, ACK
I2CONSET = 0x04; //Enable ACK for data byte
break;
case (0x48) : //Slave Address +R, Not Ack
I2CONSET = 0x20; //Resend Start condition
break;
case (0x50) : //Data Received, ACK
if(--I2Counter>0)
{
*I2CData = I2DAT;
I2CData++;
}
else
{
I2CONSET = 0x10; //Stop condition
lock = 0; //Signal end of I2C activity
}
break;
case (0x58): //Data Received, Not Ack
I2CONSET = 0x20; // Resend Start condition
break;
default :
break;
}
I2CONCLR = 0x08; //Clear I2C interrupt flag
VICVectAddr = 0x00000000; //Clear interrupt in
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -