Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
17.03.2012, 02:48
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
|
LPC2378 I2C
Проблема - после успешной посылки "СТАРТ" снятие бита SI (установка SIC в I2C0CONCLR) привод к снятию всех битов контроля - I2EN, I2STA, что, в свою очередь переводит интерфейс в нерабочее положение.
Причем на виртуальном отладчике uVision такой проблемы не было, а при отладке железяки через keil ulink - есть...
__________________
Sex, Druggs, Rock&Roll
|
|
|
|
19.03.2012, 02:34
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
|
Re: LPC2378 I2C
При чем еще странность - при отладке железа вот такой вот баг - в регистрах I2C0CONSET и I2C0CONCLR всегда одинаковое значение. И вотч не видит эти регистры (отображаются ????)...
__________________
Sex, Druggs, Rock&Roll
|
|
|
|
19.03.2012, 07:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: LPC2378 I2C
Вот куски моего рабочего кода для I2C LPC2468 (думаю, примерно то же самое):
I2C1Timer уменьшается до нуля в прерывании от таймера (1 мс).
Использую для отсчета времени записи в 24с512, ну и для таймаута (на всякий случай).
В принципе, можно выкинуть, если не критично.
#define cAT24Addr 0xA4
#define cAT24RdAddr (cAT24Addr | 0x01)
volatile byte I2C1TmpWrBuff[4];
volatile byte I2C1TmpRdBuff[4];
volatile byte *I2C1WritePtr, *I2C1ReadPtr, *I2C1WrTmpPtr;
volatile dword I2C1WriteCount, I2C1ReadCount;
volatile dword I2C1TmpWriteCount;
volatile dword I2C1Status;
volatile dword I2C1Timer;
void StartWrite24C512(word addr, byte cnt, byte *buff){
// I20CONCLR=0x24;
I2C1CONCLR=0x64;
I2C1Status=0;
//I20CONCLR=0x08; //очщаем SI
I2C1TmpRdBuff[0]=0;
I2C1ReadCount=0;
I2C1ReadPtr=0;
I2C1WrTmpPtr=I2C1TmpWrBuff;
I2C1TmpWrBuff[0]=cAT24Addr;
I2C1TmpWrBuff[1]=addr››8;
I2C1TmpWrBuff[2]=addr;
I2C1TmpWriteCount=3;
I2C1WriteCount=cnt;
I2C1WritePtr=buff;
I2C1Timer=(cnt+4)+10;
I2C1CONSET=0x40;
I2C1CONSET=0x20; //STA
}
void StartRead24C512(word addr, byte cnt, byte *buff){
I2C1CONCLR=0x64;
I2C1Status=0;
//I20CONCLR=0x08; //очщаем SI
I2C1TmpRdBuff[0]=2;
I2C1TmpRdBuff[1]=cAT24RdAddr;
I2C1ReadCount=cnt;
I2C1ReadPtr=buff;
I2C1WrTmpPtr=I2C1TmpWrBuff;
I2C1TmpWrBuff[0]=cAT24Addr;
I2C1TmpWrBuff[1]=addr››8;
I2C1TmpWrBuff[2]=addr;
I2C1TmpWriteCount=3;
I2C1WriteCount=0;
I2C1WritePtr=0;
I2C1Timer=(cnt+4);
I2C1CONSET=0x40;
I2C1CONSET=0x20; //STA
}
__irq void I2C_HandlerTwo (void){
dword st;
st=I2C1STAT & 0xF8;
I2C1CONCLR=0x24;
switch (st){
case 0x08: //передан STA
case 0x10:
case 0x18: //передан SLA+W и получен ACK
case 0x28: //передан байт и получен ACK
if (I2C1TmpWriteCount) {
I2C1DAT=*I2C1WrTmpPtr;
I2C1TmpWriteCount--;
I2C1WrTmpPtr++;
}
else if (I2C1WriteCount)
{
I2C1DAT=*I2C1WritePtr;
I2C1WriteCount--;
I2C1WritePtr++;
}
else { switch (I2C1TmpRdBuff[0]) {
case 0x02://есть чтение
I2C1CONSET=0x20; //STA
I2C1TmpRdBuff[0]=1;
break;
case 0x01: //шлем адрес чтения
I2C1DAT=I2C1TmpRdBuff[1];
I2C1TmpRdBuff[0]=0;
break;
default: //стоп
I2C1CONSET=0x10; //STO
I2C1Timer=0;
I2C1Status=1;
};//switch
};
break;
case 0x40:
//первый байт равен адресу чтения
I2C1CONSET=0x04; //AA
break;
case 0x50:
if (I2C1ReadCount) {
*I2C1ReadPtr=I2C1DAT;
I2C1ReadPtr++;
I2C1ReadCount--;
};
if (I2C1ReadCount) I2C1CONSET=0x04; //AA
else {I2C1CONSET=0x10; //STO
I2C1Timer=0;
I2C1Status=1;
};
break;
default://стоп
I2C1CONSET=0x10; //STO
I2C1Timer=0;
I2C1Status=2;
};//switch (st)
I2C1CONCLR=0x08; //очщаем SI
VICVectAddr=0;
}
dword Write24C512(word addr, byte DataSize, byte *data){
WaitI2C1();
StartWrite24C512(addr, DataSize, data);
return WaitI2C1();
}
dword Read24C512(word addr, byte sz, byte* buff){
dword st;
WaitI2C1();
StartRead24C512(addr, sz, &buff[0]);
st=WaitI2C1();
if (st!=1) sz=0;
return sz;
}
dword WaitI2C1(void) {
while (!I2C1Status && I2C1Timer);
return I2C1Status;
}
|
|
|
|
19.03.2012, 13:17
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
|
Re: LPC2378 I2C
Пытаюсь делать по аналогии, только без прерываний.
Код:
|
void tI2C::Init (void)
{
PCONP |= (1‹‹7);
PCLKSEL0 |= (1‹‹15)|(1‹‹14);
PINSEL1 &= ~((1‹‹25)|(1‹‹24)|(1‹‹23)|(1‹‹22));
PINSEL1 |= (1‹‹24)|(1‹‹22);
I20CONCLR = (1‹‹2)|(1‹‹3)|(1‹‹5)|(1‹‹6);
I20SCLH = 0x20;
I20SCLL = 0x20;
I20ADR = 0x00;
I20CONSET = (1‹‹6);
}
void tI2C::Write(unsigned char data)
{
Send_Byte(data);
}
void tI2C::Start(void)
{
I20CONSET = (1‹‹5);
Wait();
}
void tI2C::Stop(void)
{
I20CONSET = (1‹‹4);
Wait();
}
void tI2C::Send_Byte(unsigned char data)
{
I20DAT = data;
Wait();
}
void tI2C::Send_Address(unsigned char address,bool write)
{
if (write)
Send_Byte (address‹‹1&0xFE);
else
Send_Byte (address‹‹1|0x01);
}
unsigned int tI2C::Wait(void)
{
unsigned int status;
while(!(I20CONSET&(1‹‹3)));
status = I20STAT;
I20CONCLR = (1‹‹3);
return status;
} |
Код:
|
tI2C I2C;
tI2C* Interface=&I2C;
Interface-›Start();
Interface-›Send_Address(LCD_ADDR_CFG,TWI_WRITE);
Interface-›Send_Byte (0x3B); // BIAS 6
Interface-›Send_Byte (0x81); // Set Vbias Potentiometer
Interface-›Send_Byte (0x50);
Interface-›Send_Byte (0xAF); // Set Display Enable
Interface-›Send_Byte (0x84); // Disable Partial Display
Interface-›Send_Byte (0xC4); // Set LCD Mapping Control
Interface-›Send_Byte (0x88); // Set RAM Address Control
Interface-›Stop(); |
Передается СТАРТ, затем адрес, но вот когда должны идти данные почему-то передается повторный СТАРТ. Там же полтора регистра, где же можно накосячить-то....
__________________
Sex, Druggs, Rock&Roll
|
|
|
|
19.03.2012, 14:21
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: LPC2378 I2C
Подробно вдаваться нет времени, но вот, например, вижу:
у вас после чтения байта статуса
I20CONCLR = (1‹‹3); (т.е. 0x08 )
а у меня:
st=I20STAT & 0xF8;
I20CONCLR=0x24;
P.S. Посмотрел сейчас под отладчиком - 0x08 в I20CONCLR тоже посылаю перед выходом из прерывания.
После отправки STA у меня в I20STAT появляется 0х08, потом после отравки байта - 0х18.
Последний раз редактировалось pambaru; 19.03.2012 в 14:31.
|
|
|
Сказали "Спасибо" pambaru
|
|
|
19.03.2012, 14:37
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: LPC2378 I2C
Моя инициализация, на всякий случай:
void InitI2C0(void){
VICVectAddr9=(unsigned)I2C_Handler;
VICVectCntl9=0x08; //приоритет
PINSEL1=(PINSEL1 & (~(0x0F ‹‹ 22))) | (0x05 ‹‹ 22); //разрешаем SCL0 и SDA0
I20SCLH=12; //12 - 375 кГц
I20SCLL=12;
I20CONCLR=0x40;
VICIntEnable = (1 ‹‹ 9); //разрешаем I2C0
}
|
|
|
|
19.03.2012, 15:25
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
|
Re: LPC2378 I2C
Моя ошибка была еще и в том, что я после старта дожидался флага прерывания.
Теперь работает, правда дисплей все еще не отвечает...
И еще странность - после стопа, следующий старт не передается... Только если включить/выключить весь интерфейс (флагом I2EN)...
__________________
Sex, Druggs, Rock&Roll
|
|
|
|
19.03.2012, 16:40
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: LPC2378 I2C
Сообщение от alberio
|
Моя ошибка была еще и в том, что я после старта дожидался флага прерывания.
Теперь работает, правда дисплей все еще не отвечает...
И еще странность - после стопа, следующий старт не передается... Только если включить/выключить весь интерфейс (флагом I2EN)...
|
После отправки старта прерывание возникает.
st=I2C1STAT & 0xF8;
выдает st=0x08
А затем после записи байта данных st=0x18
|
|
|
|
19.03.2012, 16:44
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: LPC2378 I2C
А что за странный Wait у вас ?
Только обратил внимание.
Правильно же как то так будет:
unsigned int tI2C::Wait(void)
{
unsigned int status;
do {
status=I20STAT;
}while(!(status & (1‹‹3)));
I20CONCLR = (1‹‹3);
return status;
}
Разве нет ?
А то Вы I20CONSET проверяете.
|
|
|
|
19.03.2012, 16:48
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
|
Re: LPC2378 I2C
Верно. Если после установки I2STA сбросить SI интерфейс переходит в состояние "передан адрес" - 0х20 (это без ACK от слэйва).
И как же тогда быть ?
__________________
Sex, Druggs, Rock&Roll
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
i2c
|
vsalomasov |
TTL и CMOS логика |
4 |
06.12.2010 14:14 |
I2C подскажите.
|
Andrewg |
Микроконтроллеры, АЦП, память и т.д |
35 |
13.08.2007 07:35 |
?-быстродействие I2C
|
giran |
Микроконтроллеры, АЦП, память и т.д |
1 |
15.05.2007 15:14 |
I2C
|
chipic128 |
Микроконтроллеры, АЦП, память и т.д |
4 |
23.02.2005 02:19 |
I2C
|
zevs |
Микроконтроллеры, АЦП, память и т.д |
0 |
11.01.2005 16:11 |
Часовой пояс GMT +4, время: 19:38.
|
|