LPC1114 + Accelerometer

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

LPC1114 + Accelerometer

1,788件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syntx on Thu Aug 18 20:16:21 MST 2011
Hi I'm trying to interface an LPC1114 + Accelerometer (LIS331DLH), I'm configuring the accelerometer to generate an interrupt for data-ready (when a data conversion is finished), this interrupt will be open-drain, active low and if the interrupt is generated and I'll not read the data the interrupt still actived. So I configurated my gpio with no pull-up, edge interrupt, edge single, active low. The problem is this. After I configure the accelerometer (I already checked with the ST if the configuration of the accelerometer is correct and they confirmed it), after this It starts to generate interrupts, so the first interrupt I got read and send by uart the information, as I have a counter inside the IRQ_Handler I'm sending inside while(1) the value of the counter, after read the data of the accelerometer the accelerometer generates other interrupt, the LPC1114 detect, the counter goes counter++ BUT, nothing else happens, the interrupt flag is cleaned, and microcontoller keeps working and don't read the interrupt in the accelerometer, that still waiting for a read.

void systemInit()
{
  cpuInit();
  systickInit((CFG_CPU_CCLK / 1000) * CFG_SYSTICK_DELAY_IN_MS);
  pmuInit();  

  // Initialise UART with the default baud rate (set in projectconfig.h)
  uartInit(CFG_UART_BAUDRATE);

  // Set LED pin as output and turn LED off
  gpioSetDir(CFG_LED_PORT, CFG_LED_PIN, 1);
  gpioSetValue(CFG_LED_PORT, CFG_LED_PIN, CFG_LED_ON);

  // Set GPIO0_11 and GPIO1.0 to INPUT
  gpioSetDir(0, 11, gpioDirection_Input);
  gpioSetDir(1,  0, gpioDirection_Input);

  // Disable the internal pullup/down resistor on P0.11 and P1.0
  gpioSetPullup (&IOCON_JTAG_TDI_PIO0_11, gpioPullupMode_Inactive);
  gpioSetPullup (&IOCON_JTAG_TMS_PIO1_0 , gpioPullupMode_Inactive);

  // Setup an interrupt on GPIO0.11
  gpioSetInterrupt(0,                               // Port
     11,                              // Pin
           gpioInterruptSense_Edge,         // Edge Sensitive
   gpioInterruptEdge_Single,        // Single Edge
   gpioInterruptEvent_ActiveLow);   // Active Low
 
  // Setup an interrupt on GPIO1.0
  gpioSetInterrupt(1,                               // Port
   0,                               // Pin
   gpioInterruptSense_Edge,         // Edge Sensitive
   gpioInterruptEdge_Single,        // Single Edge
   gpioInterruptEvent_ActiveLow);   // Active Low
  
 // Enable the interrupts
  gpioIntEnable(0, 11);
  gpioIntEnable(1,  0);

  // Initialise and Configure LIS331
  #ifdef CFG_LIS331
    accdata_t X, Y, Z;
    accsensorInit(); 
    lis331GetAcceleration (&X, &Y, &Z);  
  #endif
}

lis331Error_e lis331GetAcceleration (accdata_t *ax, accdata_t *ay, accdata_t *az)
{
  if (!_lis331Initialised) lis331Init();

  // Read accelerations
lis331Read16 (LIS331_OUT_X_L_A, &ax->data);
lis331Read16 (LIS331_OUT_Y_L_A, &ay->data);
lis331Read16 (LIS331_OUT_Z_L_A, &az->data);

  return LIS331_ERROR_OK;
}

static lis331Error_e lis331Read16(uint8_t reg, int16_t *value)
{
if (!_lis331Initialised) lis331Init();

uint32_t i;
// Clear buffers
  for ( i = 0; i < I2C_BUFSIZE; i++ )
  {
    I2CMasterBuffer = 0x00;
I2CSlaveBuffer = 0x00;
  }

  I2CWriteLength = 2;
  I2CReadLength = 2;
  I2CMasterBuffer[0] = LIS331_ADDRESS_WRITE;      // I2C device Write address
  I2CMasterBuffer[1] = reg | I2C_AUTO_INCREMENT;  // Command register just for data acceleration registers)
  I2CMasterBuffer[2] = LIS331_ADDRESS_READ;       // I2C device Read address
 
  i2cEngine();

  // Shift values to create properly formed integer
  *value = ((I2CSlaveBuffer[1] << 8) | I2CSlaveBuffer[0]) >> 4;

  //  Sign extend negative numbers
  if (I2CSlaveBuffer[1] & 0x80)
  {
    // Negative value
    *value ^= *value;
    *value += 1;
  }
  return LIS331_ERROR_OK;
}

int main(void)
{
        sysinit();
while (1){
GPIO_GPIO3DATA ^= (1 << CFG_LED_PIN);
systickDelay(30);

        // IRQ ACCELEROMETER
uartSendByte(gpio1_counter);

  if(_accInt1Initialised == true){
accInt1Handler();
}
  return 0;
}

void accInt1Handler(void)
{
lis331GetAcceleration (&aX, &aY, &aZ);

uartBuffer[1] = aX.byte[1];
uartBuffer[2] = aX.byte[0];
uartBuffer[4] = aY.byte[1];
uartBuffer[5] = aY.byte[0];
uartBuffer[7] = aZ.byte[1];
uartBuffer[8] = aZ.byte[0];
uartSend((uint8_t *)uartBuffer, 10);

_accInt1Initialised = false;
}

void PIOINT1_IRQHandler(void)
{
  if (GPIO_GPIO1MIS & 0x01)
  {
gpio1_counter++;
_accInt1Initialised = true;
GPIO_GPIO1IC |= 0x01;
__asm volatile ("nop"); // Recommended in Datasheet
__asm volatile ("nop");
}   
  return;
}


What is wrong ?? Another idea to deal properly with this interrupt? I don't want to poll the int, but in this way is like poll the pin because I can't work with everything inside the irq_handler because i need to use the i2c.
0 件の賞賛
返信
10 返答(返信)

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syntx on Fri Aug 19 11:42:24 MST 2011
ODR = 100Hz = 10ms.

You sad about faster baudrate I already tried with 57600 too but the reaction was the same. I measured the times yester, I think it was 30ms between and interrupt occurs, get data, send by uart and wait for another interrupt. I don't remember exactly right now cause I'm not at the lab this moment.

I tried the way to deal with the IRQ. As I'm doing this interrupt data-ready just for test and read some accelerations from the accelerometer. I disabled the IRQ inside the LPC1112 and created an Timer, every 5ms I read the data from the accelerometer and send by uart. Now it's working.

Thank you so much for your help!!
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Aug 19 11:12:32 MST 2011
Which ODR (Output data rate) are you using?

Try to test without slow UART. Can you scope or measure how long you need for UART output ?
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syntx on Fri Aug 19 10:50:16 MST 2011
I configureated now to clear the flag (accInt1Initialised) first, and toggling the led just inside  the if as you sad. So I can get some samples by uart and the led is toggling and after a while stop toggling the led and uart don't send anything else... I made other test sending the irqcounter and after a while he stops counting.
I think it's a problem of syncronization, I don't know how to fix it
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Aug 19 10:18:30 MST 2011
Toggling also in accInt1Initialised :confused:

if(_accInt1Initialised == true)
{
 LED_toggle;
 ...
}
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syntx on Fri Aug 19 10:07:58 MST 2011
Yes I'm toggling a led in inside the while(1) and the led still toggling...
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Aug 18 22:52:25 MST 2011
Try to reset your flags as soon as possible:

if(_accInt1Initialised == true){
 _accInt1Initialised == false;
  accInt1Handler();    
}

UART is a very 'slow' thing....

Quote:

...without debugger.... :eek:

What about toggling a LED?
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syntx on Thu Aug 18 22:46:53 MST 2011
I'm without debugger at the moment, I'll have to wait two weeks to get my debugger =/

At this point I'm debugging just watching the uart.
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Aug 18 22:44:41 MST 2011
Then use your debugger :)

Set a breakpoint at the end of your Interrupt handler and 'Add Watch Expression' for accInt1Initialised :)
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by syntx on Thu Aug 18 22:35:41 MST 2011

Quote: Zero

#1 Interrupt is firing and gpio1_counter++ is counting up ?
Yes

#2 _accInt1Initialised is true ?
In the first interrupt yes, after the first I don't know

#3 LPC_GPIO1->MIS is set, but accInt1Handler is not called ?
Just in the first time   

#4 Is _accInt1Initialised volatile?
Yes

#5 Is PIOINT1 NVIC enabled somewhere  (NVIC_EnableIRQ(1<<30))?
Yes, in gpioInit(); Just didn't put in this post.



In the first time the interrupt occurs and the gpio1_counter counts, but in the second the interrupt occurs too, gpio1_conter counts BUT I don't know if accInt1Initialised not goes true or the if(accInt1Initialised) inside while(1) is not working, so accInt1Handler never been called again.
0 件の賞賛
返信

1,741件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Aug 18 22:05:28 MST 2011
GPIO_GPIO1IC |= 0x01;
__asm volatile ("nop");         // Recommended in Datasheet
__asm volatile ("nop");
Looks OK (clear edge detection)

I'm not sure if I understand your problem. Can you confirm the following points:

#1 Interrupt is firing and gpio1_counter++ is counting up ?

#2 _accInt1Initialised is true ?

#3 LPC_GPIO1->MIS is set, but accInt1Handler is not called ?
   
Is _accInt1Initialised volatile?

Is PIOINT1 NVIC enabled somewhere  (NVIC_EnableIRQ(1<<30))  ?
0 件の賞賛
返信