ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
25 ноября
159362
Ruslan (20.06.2009 02:40, просмотров: 3686)
Как правильно описать прерывания от I2C в LPC2148? Достался вот такой кусок кода. Никак не могу заставить работать прерывания от I2C . Среда keil 3.70. В void i2c_ISR (void) входит только один раз при I2C0STAT = 0x08. Дальше висит. type.h #ifndef __TYPE_H__ #define __TYPE_H__ #ifndef NULL #define NULL ((void *)0) #endif #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (1) #endif typedef unsigned char UINT8; typedef unsigned short UINT16; typedef unsigned long UINT32; #endif /* __TYPE_H__ */ i2c.c #include "LPC214X.h" #include "i2c.h" #define I2C_EN (1<<6) #define I2C_START (1<<5) #define I2C_STOP (1<<4) #define I2C_INT (1<<3) #define I2C_ACK (1<<2) BYTE I2C_address; BYTE I2C_data; struct { UINT8 DevAddr; UINT8 Addr; UINT8 Counter; UINT8 Data[2]; UINT8 Done; } I2C; void i2c_lpc_init(int Mode) { VICVectCntl1 = 0x00000029; //select a priority slot for a given interrupt VICVectAddr1 = (unsigned)i2c_ISR; //pass the address of the IRQ into the VIC slot VICIntEnable = 0x00000200; //enable interrupt PINSEL0 = 0x50; if(Mode == I2C_SPEED_400) { //--- I2C Timing for Pclk = 15 MHz // 15/(19+19) = 0,394 Mhz I2C0SCLH = 19; I2C0SCLL = 19; } else //Slow { I2C0SCLH = 75; I2C0SCLL = 75; } I2C0CONCLR = 0xFF; //-- Clear all flags I2C0CONSET = 0x40; //-- Set Master Mode } void i2c_ISR (void) __irq //I2C interrupt routine { switch (I2C0STAT) { case (0x8): // START DONE I2C0DAT = I2C.DevAddr; // Посылаем адрес и бит записи (0) I2C0CONCLR = (I2C_INT | I2C_START); // Сбрасываем флаг состояния START и флаг прерывания break; case (0x20): // SLA+W, NACK I2C0CONSET = I2C_STOP | I2C_START; // generate stop I2C0CONCLR = I2C_INT; //I2C0DAT = I2C_address; break; case (0x18): // Slave addr ACK I2C0DAT = I2C.Addr; I2C0CONCLR = I2C_INT; break; case (0x28): // Byte transfer ACK if(I2C.DevAddr & (1<<0)) { I2C0CONSET = I2C_START; // generate repeated start I2C0CONCLR = I2C_INT; } else //write { if (I2C.Counter < 2) { I2C0DAT = I2C.Data[I2C.Counter]; I2C.Counter++; } else { I2C0CONSET = I2C_STOP; I2C.Done = 1; } I2C0CONCLR = I2C_INT; } break; case 0x10: // Repeated start done I2C0DAT = I2C.DevAddr; // SEND SLA+R I2C0CONCLR = (I2C_INT | I2C_START); break; case 0x40: // Slave ACKed SLA+R if (I2C.Counter < 2) { I2C0CONSET = I2C_ACK; // send ACK if not last byte } I2C0CONSET = I2C_INT; break; case 0x50: // Byte received with ACK I2C.Data[I2C.Counter] = I2C0DAT; I2C.Counter++; if (I2C.Counter == 1) { I2C0CONCLR = I2C_ACK; // send NACK after last byte } I2C0CONCLR = I2C_INT; break; case 0x58: // Last byte received I2C.Data[I2C.Counter] = I2C0DAT; I2C.Counter++; I2C0CONSET = I2C_STOP; I2C.Done = 0; I2C0CONCLR = I2C_INT; break; default:; } VICVectAddr = 0; // Reset VIC logic } void pca9555_config(void) { I2C.DevAddr = 0x40 | (0x00 << 1); // Доп. адрес I2C.Addr = I2C_PCA9555_CONF_P0; I2C.Data[0] = 0x00; I2C.Data[1] = 0x00; I2C.Counter = 0; I2C.Done = 0; I2C0CONCLR = ( I2C_ACK | I2C_START | I2C_STOP | I2C_INT ); I2C0CONSET = ( I2C_EN | I2C_START ); while(I2C.Done != 1); } main.c #include <LPC214x.H> #include "main.h" #include "i2c.h" #include "input_trigger.h" void main() { i2c_lpc_init(I2C_SPEED_400); pca9555_config(); while (1); }