Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Вкратце - не

Отправлено scorpion 19 февраля 2007 г. 12:26
В ответ на: А не затруднит вкратце описать проблему, а то мне скоро с i2c блтно работать? отправлено gruzza 19 февраля 2007 г. 12:04

совсем точное описание и примеры работы с I2C в описании LPC214x. Если точно следовать рекомендациям, то нихрена не запустится. Такое впечатление, что NXP пошла по пути Microsoft - наняла индусов для писания документации. Вот тут ниже .h и .c файл с функциями для I2C0 (работает, ненужные закомментированные участки можно убрать):

h-файл :
//==================================================================
//------------------- i2c.h --------------------------
#ifndef __i2c_h_
#define __i2c_h_
//---------------------------------------------------------
#include
#include "type.h"
/////////////////////////////////////////////////////////
typedef struct {
BYTE SlaveAddr;
BYTE Data; //
BOOL RWbit;
BYTE RxCnt;
BYTE TxCnt;
BYTE RxBuf[64]; //
BYTE TxBuf[64]; //
BYTE RxLen; //сколько байт нужно принять
BYTE TxLen; //сколько байт нужно передать
} I2C_Params;


///////////////////////////////////////////////////////////////////

extern void I2C0Enable(void);
extern void I2C0Disable(void);

extern void I2C0Init(void);

extern void I2C0Transmit(BYTE, BYTE*, BYTE);
extern void I2C0Receive(BYTE, BYTE*, BYTE);

extern void WrPCF8574A(BYTE, BYTE);
extern BYTE RdPCF8574A(BYTE);

extern void WrDS1805Pot(BYTE, BYTE);
extern BYTE RdDS1805Pot(BYTE);


//////////////////////////////////////////////////////////////

#endif
//==================================================================


c-файл :
//==================================================================
//------------------------ i2c.c ------------------------

#include "common.h"
#include "uart.h"
#include "i2c.h"

//================================================================
#define VIC_I2C0 9
//================================================================

void I2C0_Irq(void) __irq;

void ISR0_hex0(void); // Bus error, p.164 of UM10139.pdf
void ISR0_hex8(void); // A Start condition has been
// transmitted
void ISR0_hex10(void); //
void ISR0_hex18(void); //
void ISR0_hex20(void); //
void ISR0_hex28(void); //
void ISR0_hex30(void); //
void ISR0_hex38(void); //
void ISR0_hex40(void); //
void ISR0_hex48(void); //
void ISR0_hex50(void); //
void ISR0_hex58(void); //


//BYTE SlaveAddr = 0x50;
//BYTE I2C0data;
//BOOL I2C0operation; //0 - write, 1 - read


I2C_Params I2C0;

//////////////////////////////////////////////////////////////////
void I2C0Enable(void)
{
I2C0CONSET = 0x40; //p.135, 163 of UM10139
}//void I2C0Enable(void)
/////////////////////////////////////////////////////////////////////////////////////////
void I2C0Disable(void)
{
I2C0CONCLR = 0x40; //p.118 of LPC2106 user manual
}//void I2C0Disable(void)
/////////////////////////////////////////////////////////////////////////////////////////
void I2C0Init(void)
{
//Initialize I2C - pages 8, 12 of AN10369.pdf
I2C0CONCLR = 0x7c;//0x6c; //clearing all flags (control clear register), p.144 of UM10139
I2C0CONSET = 0x40; //enabling I2C0 (control set register)
I2C0SCLH = 600;//300;//150; //100 kHz
I2C0SCLL = 600;//300;//40; //page 8 of AN10369.pdf, p.146 of UM10139.pdf

// 0x20 - interrupt channel enabled, 9 - channel number for I2C0
VICVectCntl5 = 0x20 | VIC_I2C0;
// VIC routine address
VICVectAddr5 = (DWORD)I2C0_Irq;

// I2C0 interrupt enable
VICIntEnable |= (1< // update interrupt logic
VICVectAddr = 0;
}//void I2C0Init(void)
/////////////////////////////////////////////////////////////////
void I2C0_Irq(void) __irq //I2C0 ISR
{
int temp = 0;


temp = I2C0STAT;

switch(temp)
{
case 0x00: ISR0_hex0();
break; //case 0x00

case 0x08: //START condition is transmitted
ISR0_hex8();
break; //case 0x08

case 0x10: //next transfer started with a
//Repeated Start condition
ISR0_hex10();
break; //case 0x10

case 0x18: //SLA+W has been transmitted,
//ACK has been received
ISR0_hex18();
break; //case 0x18

case 0x20: //SLA+W has been transmitted,
//NOT ACK has been received
ISR0_hex20();
break; //case 0x20

case 0x28:
ISR0_hex28();
break; //case 0x28

case 0x30: //
ISR0_hex30();
break; //case 0x30

case 0x38: //
ISR0_hex38();
break; //case 0x38

case 0x40: //
ISR0_hex40();
break; //case 0x40

case 0x48: //
ISR0_hex48();
break; //case 0x48

case 0x50: //
ISR0_hex50();
break; //case 0x50

case 0x58: //
ISR0_hex58();
break; //case 0x58

default : break;
}//switch(temp)

VICVectAddr = 0;
}//void I2C0_Irq(void) __irq
/////////////////////////////////////////////////////////////////////////////////////////
//=========== Non mode specific States ======================
void ISR0_hex0(void) //Bus error
{
I2C0CONSET = 0x14; //set STO & AA bits, p.164 of UM10139
I2C0CONCLR = 0x08; //Clear SI flag, p.164 of UM10139


}//void ISR0_hex0(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex8(void) //Start condition has been transmitted,
//p.164 of UM10139
{//The Slave address + R/W bit will be transmitted,
// an ACK bit will be received
I2C0DAT = (I2C0.SlaveAddr & 0xfe) | I2C0.RWbit;

I2C0CONSET = 0x04; //set AA bit, p.164 of UM10139

I2C0CONCLR = 0x28; //Clear SI and Start flag , p.154 of UM10139

I2C0.TxCnt = 0;
I2C0.RxCnt = 0;


}//void ISR0_hex8(void)
/////////////////////////////////////////////////////////////
void ISR0_hex10(void) //A repeated Start condition has been transmitted, p.165 of UM10139 (next transfer started with a Repeated Start condition)
{ //The Slave address + R/W bit will be transmitted, an ACK bit will be received
I2C0DAT = (I2C0.SlaveAddr & 0xfe) | I2C0.RWbit;

I2C0CONSET = 0x04; //set AA bit, p.165 of UM10139

I2C0CONCLR = 0x08; //Clear SI flag, p.165 of UM10139

I2C0.TxCnt = 0;
I2C0.RxCnt = 0;


}//void ISR0_hex10(void)
/////////////////////////////////////////////////////////////////////////////////////////
//=============== Master Transmit States ======================
void ISR0_hex18(void) //SLA+W has been transmitted, ACK has been received from slave, p.165 of UM10139
{ //(previous state was State 0x08 or State 0x10)
//The first data byte will be transmitted, an ACK bit will be received
I2C0DAT = I2C0.TxBuf[I2C0.TxCnt]; //Data to be transmitted - first data byte from Master transmit buffer, p.165 of UM10139

I2C0CONSET = 0x04; //set AA bit, p.165 of UM10139

I2C0CONCLR = 0x08; //Clear SI, p.165 of UM10139

I2C0.TxCnt++;


}//void ISR0_hex18(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex20(void) //SLA+W has been transmitted, NOT ACK has been received
{ //A Stop condition will be transmitted, p.165 of UM10139
I2C0CONSET = 0x14; //set STO & AA bits

I2C0CONCLR = 0x08; //Clear SI

// IOSET1 = 0x02000000; //P1.25 = SHDN = Red ---------------------------

// uSend1Data("ISR0_hex20", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex20(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex28(void) //Data has been transmitted, ACK has been received from slave.
{ //If the transmitted data was the last data byte then transmit a Stop condition,
//otherwise transmit the next data byte, p.165 of UM10139
I2C0.TxLen--;

if(I2C0.TxLen == 0)
{
I2C0CONSET = 0x14; //set STO & AA bits
// I2C0CONSET = 0x10; //set STO & AA bits
}
else
{
I2C0DAT = I2C0.TxBuf[I2C0.TxCnt]; //Data to be transmitted - next data byte from Master transmit buffer, p.166 of UM10139

I2C0CONSET = 0x04; //set AA bit

I2C0.TxCnt++;
}//else of if(I2C0.TxLen == 0)

I2C0CONCLR = 0x08; //Clear SI

// uSend1Data("ISR0_hex28", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex28(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex30(void) //Data has been transmitted, NOT ACK received.
{ //A Stop condition will be transmitted, p.166 of UM10139
I2C0CONSET = 0x14; //set STO & AA bits

I2C0CONCLR = 0x08; //Clear SI

// uSend1Data("ISR0_hex30", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex30(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex38(void) //Arbitration has been lost during Slave Address + Write or data.
{ //The bus has been released and not addressed Slave mode is entered.
//A new Start condition will be transmitted when the bus is free again, p.166 of UM10139
I2C0CONSET = 0x24; //set STA & AA bits

I2C0CONCLR = 0x08; //Clear SI

// uSend1Data("ISR0_hex38", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex38(void)
/////////////////////////////////////////////////////////////////////////////////////////
//========================== Master Receive States ==============================
void ISR0_hex40(void) //Previous state was State 0x08 or 0x10. Slave address + Read has been transmitted,
{ //ACK has been received. Data will be received and ACK returned, p.166 of UM10139
I2C0CONSET = 0x04; //set AA bit

I2C0CONCLR = 0x08; //Clear SI

// uSend1Data("ISR0_hex40", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex40(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex48(void) //Slave address + Read has been transmitted, NOT ACK has been received.
{ //A Stop condition will be transmitted, p.166 of UM10139
I2C0CONSET = 0x14; //set STO & AA bits

I2C0CONCLR = 0x08; //Clear SI

// uSend1Data("ISR0_hex48", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex48(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex50(void) //Data has been received, ACK has been returned. Data will be read from I2DAT.
{ //Additional data will be received. If this is the last data byte then NOT ACK
//will be returned, otherwise ACK will be returned, p.167 of UM10139
I2C0.RxBuf[I2C0.RxCnt] = I2C0DAT; //p.167 of UM10139

I2C0.RxLen--;

if(I2C0.RxLen)
{//åù¸ íå âñå áàéòû ïðèíÿòû
I2C0CONSET = 0x04; //set AA bit
I2C0CONCLR = 0x08; //Clear SI
I2C0.RxCnt++;
}
else
{
I2C0CONCLR = 0x0c; //Clear SI flag & AA bit, p.167 of UM10139
}//else of if(I2C0.RxLen)

// uSend1Data("ISR0_hex50", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex50(void)
/////////////////////////////////////////////////////////////////////////////////////////
void ISR0_hex58(void) //Data has been received, NOT ACK has been returned. Data will be read from I2DAT.
{ //A Stop condition will be transmitted, p.167 of UM10139
I2C0.RxBuf[I2C0.RxCnt] = I2C0DAT; //p.167 of UM10139

I2C0CONSET = 0x14; //set STO & AA bits

I2C0CONCLR = 0x08; //Clear SI

// uSend1Data("ISR0_hex58", 10); //"uart.c" ---------------------------------------

}//void ISR0_hex58(void)
/////////////////////////////////////////////////////////////////////////////////////////
//=======================================================================================
void I2C0Transmit(BYTE Addr, BYTE* buf, BYTE numb)
{//ïåðåäàòü ïî i2c0 "numb" áàéò èç áóôåðà "buf" â I2C-óñòðîéñòâî ñ àäðåñîì "Addr", p.164 of UM10139
BYTE i;

I2C0.TxCnt = 0;

I2C0.SlaveAddr = Addr;

I2C0.RWbit = 0; //0 - Writing

for(i=0;i// I2C0.TxBuf[0] = 0xfe; //---------------------------------
// I2C0.TxBuf[1] = 0xf0; //---------------------------------

I2C0.TxLen = numb;

// I2C0CONCLR = 0x3c; //Clear STA, STO, SI and AA bits, p.148 of UM10139

I2C0CONSET = 0x40; //set I2C0En bit, p.148 of UM10139

I2C0CONSET = 0x20; //set STA bit for transmission begin, p.148, 164 of UM10139

}//void I2C0Transmit(BYTE Addr, BYTE* buf, BYTE numb)
/////////////////////////////////////////////////////////////////////////////////////////
void I2C0Receive(BYTE Addr, BYTE* buf, BYTE numb)
{//ïîëó÷èòü ïî i2c0 "numb" áàéò â áóôåð "buf" èç I2C-óñòðîéñòâà ñ àäðåñîì "Addr", p.164 of UM10139
BYTE i;

I2C0.RxCnt = 0;

I2C0.SlaveAddr = Addr;

I2C0.RWbit = 1; //1 - Reading

I2C0.RxLen = numb;

// I2C0CONCLR = 0x3c; //Clear STA, STO, SI and AA bits, p.148 of UM10139

I2C0CONSET = 0x40; //set I2C0En bit, p.148 of UM10139

I2C0CONSET = 0x20; //set STA bit for transmission begin, p.148 of UM10139

for(i=0;i}//void I2C0Receive(BYTE Addr, BYTE* buf, BYTE numb)
/////////////////////////////////////////////////////////////////////////////////////////
void WrPCF8574A(BYTE AddrOnBus, BYTE data)
{
BYTE buf1[2];//buf1[10];

buf1[0] = data;
// buf1[1] = 0xf0;

// I2C0Transmit(0x70, buf1, 1);
I2C0Transmit((0x70 | ((AddrOnBus<<1)&0x0e)), buf1, 1);

}//void WrPCF8574A(BYTE data)
/////////////////////////////////////////////////////////////////////////////////////////
BYTE RdPCF8574A(BYTE AddrOnBus)
{
BYTE buf1[2];

I2C0Receive((0x70 | ((AddrOnBus<<1)&0x0e)), buf1, 1);

return buf1[0];
}//BYTE RdPCF8574A(BYTE AddrOnBus)
/////////////////////////////////////////////////////////////////////////////////////////
void WrDS1805Pot(BYTE AddrOnBus, BYTE data)
{
BYTE buf1[2];

buf1[0] = 0xaa;
buf1[1] = data;

I2C0Transmit((0x50 | ((AddrOnBus<<1)&0x0e)), buf1, 2);

}//void WrDS1805Pot(BYTE data)
/////////////////////////////////////////////////////////////////////////////////////////
BYTE RdDS1805Pot(BYTE AddrOnBus)
{
BYTE buf1[2];

I2C0Receive((0x50 | ((AddrOnBus<<1)&0x0e)), buf1, 2);

return buf1[1];
}//BYTE RdDS1805Pot(BYTE AddrOnBus)
////////////////////////////////////////////////////////////
//==================================================================




Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
введите число 69:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru