Требуется организовать обмен данными по интерфейсу I2C между МК LPC2368 и RTC M41T11. Взял пример из книги Тревора Мартина, тк раньше с I2C не работал. Скомпилировал, запустил - не работает((( Посмотрите свежим взглядом, где может быть ошибка?
Код
#include <LPC23xx.H>
#include <stdarg.h>
#include "uart.h"
void I2CISR (void) __irq;
void I2CTransferByte(unsigned int I2CAddr,unsigned char MemAddr,unsigned char count,...);
unsigned char message[4] ={0x01,0x02,0x03,0x04};
unsigned char messageIn[4];
unsigned char *I2CData,
I2Counter,
I2CAddress,
MemAddress,
lock;
int main(void)
{
UART0_Init(115200); // инициализация интерфейса уарт0. работает 100%
UART_PutData(0, "I2C Test...", 11); //посылка в 0-ой уарт строки. работает 100%
lock = 0; //Initilise the lock flag
PINSEL1|=0x400000; //инициализация выводов
PINSEL1|=0x1000000;
PCONP |= 1 << 7; //включение питания модуля
I20SCLH = 0x50; //установка частоты шины (нужно 100 кГц)
I20SCLL = 0x50;
VICVectAddr9 = (unsigned)I2CISR; //Настраиваем VIC
VICVectCntl9 = 0x00000008;
VICIntEnable = 1 << 9;
I2CTransferByte(0xD0,0,4,message); //write data to the I2C Memory
I2CTransferByte(0xD0,0,0); //set address to zero
I2CTransferByte(0xD1,0,4,messageIn); //read back data
UART_PutData (0, (unsigned char*)&messageIn, 4); //посылаем в уарт0 считанные данные
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;
I20CONCLR = 0x000000FF; //Clear all I2C settings
I20CONSET = 0x00000040; //Enable the I2C interface
I20CONSET = 0x00000020; //Start condition
va_end(ap);
}
void I2CISR (void) __irq //I2C interrupt routine
{
switch (I20STAT) //Read result code and switch to next action
{
// Start and Send byte conditions
case ( 0x08): //Start bit
I20CONCLR = 0x20; //Clear start bit
I20DAT = I2CAddress; //Send address and write bit
break;
case (0x18): //Slave address+W, ACK
I20DAT = MemAddress; //Write Mem,ory start address to tx register
break;
case (0x20): //Salve address +W, Not ACK
I20DAT = I2CAddress; //Resend address and write bi
break;
case (0x28):
if(I2Counter-->0) //Data sent, Ack
{
I20DAT = *I2CData; //Write data to tx register
I2CData++;
}
else
{
I20CONSET = 0x10; //Stop condition
lock = 0; //Signal end of I2C activity
}
break;
case (0x30) : //Data sent, NOT Ack
I20DAT = *I2CData; //Write data to tx register
break;
//Receive byte conditions
case (0x40) : //Slave Address +R, ACK
I20CONSET = 0x04; //Enable ACK for data byte
break;
case (0x48) : //Slave Address +R, Not Ack
I20CONSET = 0x20; //Resend Start condition
break;
case (0x50) : //Data Received, ACK
if(--I2Counter>0)
{
*I2CData = I20DAT;
I2CData++;
}
else
{
I20CONSET = 0x10; //Stop condition
lock = 0; //Signal end of I2C activity
}
break;
case (0x58): //Data Received, Not Ack
I20CONSET = 0x20; // Resend Start condition
break;
default :
break;
}
I20CONCLR = 0x08; //Clear I2C interrupt flag
VICVectAddr = 0x00000000; //Clear interrupt in
#include <stdarg.h>
#include "uart.h"
void I2CISR (void) __irq;
void I2CTransferByte(unsigned int I2CAddr,unsigned char MemAddr,unsigned char count,...);
unsigned char message[4] ={0x01,0x02,0x03,0x04};
unsigned char messageIn[4];
unsigned char *I2CData,
I2Counter,
I2CAddress,
MemAddress,
lock;
int main(void)
{
UART0_Init(115200); // инициализация интерфейса уарт0. работает 100%
UART_PutData(0, "I2C Test...", 11); //посылка в 0-ой уарт строки. работает 100%
lock = 0; //Initilise the lock flag
PINSEL1|=0x400000; //инициализация выводов
PINSEL1|=0x1000000;
PCONP |= 1 << 7; //включение питания модуля
I20SCLH = 0x50; //установка частоты шины (нужно 100 кГц)
I20SCLL = 0x50;
VICVectAddr9 = (unsigned)I2CISR; //Настраиваем VIC
VICVectCntl9 = 0x00000008;
VICIntEnable = 1 << 9;
I2CTransferByte(0xD0,0,4,message); //write data to the I2C Memory
I2CTransferByte(0xD0,0,0); //set address to zero
I2CTransferByte(0xD1,0,4,messageIn); //read back data
UART_PutData (0, (unsigned char*)&messageIn, 4); //посылаем в уарт0 считанные данные
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;
I20CONCLR = 0x000000FF; //Clear all I2C settings
I20CONSET = 0x00000040; //Enable the I2C interface
I20CONSET = 0x00000020; //Start condition
va_end(ap);
}
void I2CISR (void) __irq //I2C interrupt routine
{
switch (I20STAT) //Read result code and switch to next action
{
// Start and Send byte conditions
case ( 0x08): //Start bit
I20CONCLR = 0x20; //Clear start bit
I20DAT = I2CAddress; //Send address and write bit
break;
case (0x18): //Slave address+W, ACK
I20DAT = MemAddress; //Write Mem,ory start address to tx register
break;
case (0x20): //Salve address +W, Not ACK
I20DAT = I2CAddress; //Resend address and write bi
break;
case (0x28):
if(I2Counter-->0) //Data sent, Ack
{
I20DAT = *I2CData; //Write data to tx register
I2CData++;
}
else
{
I20CONSET = 0x10; //Stop condition
lock = 0; //Signal end of I2C activity
}
break;
case (0x30) : //Data sent, NOT Ack
I20DAT = *I2CData; //Write data to tx register
break;
//Receive byte conditions
case (0x40) : //Slave Address +R, ACK
I20CONSET = 0x04; //Enable ACK for data byte
break;
case (0x48) : //Slave Address +R, Not Ack
I20CONSET = 0x20; //Resend Start condition
break;
case (0x50) : //Data Received, ACK
if(--I2Counter>0)
{
*I2CData = I20DAT;
I2CData++;
}
else
{
I20CONSET = 0x10; //Stop condition
lock = 0; //Signal end of I2C activity
}
break;
case (0x58): //Data Received, Not Ack
I20CONSET = 0x20; // Resend Start condition
break;
default :
break;
}
I20CONCLR = 0x08; //Clear I2C interrupt flag
VICVectAddr = 0x00000000; //Clear interrupt in