реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Интерфейс I2C в LPC2368
Oleg-K
сообщение Aug 4 2008, 12:58
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 4-08-08
Пользователь №: 39 413



Здравствуйте.
Требуется организовать обмен данными по интерфейсу 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
Go to the top of the page
 
+Quote Post
Alex03
сообщение Aug 5 2008, 02:44
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Какието странные у Вас выравнивания кода....
А SCL/SDA резюками подтянуты?
как минимум переменная lock должна быть хотя бы volatile.
Go to the top of the page
 
+Quote Post
Oleg-K
сообщение Aug 5 2008, 04:31
Сообщение #3





Группа: Новичок
Сообщений: 3
Регистрация: 4-08-08
Пользователь №: 39 413



Цитата
А SCL/SDA резюками подтянуты?

да, подтянуты внешними резисторами 4.7 кОм

Цитата
как минимум переменная lock должна быть хотя бы volatile.

исправил, но ситуацию это не меняет... Может еще что-то не так?
Go to the top of the page
 
+Quote Post
Alex03
сообщение Aug 5 2008, 05:57
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Oleg-K @ Aug 5 2008, 10:31) *
да, подтянуты внешними резисторами 4.7 кОм
исправил, но ситуацию это не меняет... Может еще что-то не так?

Зажигание включил? Бензонасос пашет? Искра при прокрутке есть?
Что не работает то?
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Aug 5 2008, 08:42
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Странная конструкция. Например это:
Код
case (0x20):                                //Salve address +W, Not ACK
I20DAT       = I2CAddress;                     //Resend address and write bi
break;

Если слейв не опознал свой адрес, или его вообще нет/поломался , то будем вечно долбить шину этим адресом. А в основном потоке также вечно ожидать завершения.
Код
case (0x30)    :                                //Data sent, NOT Ack
I20DAT       = *I2CData;                        //Write data to tx register
break;

Тоже интересный подход - если слейв не может принимать данные, надо его ими закидать по самые помидоры... Причем тоже без конца...
Почитайте про шину I2C, там ничего сложного нет.
Go to the top of the page
 
+Quote Post
Oleg-K
сообщение Aug 7 2008, 06:29
Сообщение #6





Группа: Новичок
Сообщений: 3
Регистрация: 4-08-08
Пользователь №: 39 413



Всем спасибо, проблема решена. Ошибка была в другом модуле)
2 Qwertty: Ваши замечания учту.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 11:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01412 секунд с 7
ELECTRONIX ©2004-2016