LPC1768 - CAN interrupt

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

LPC1768 - CAN interrupt

2,309件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by teslabox on Thu Feb 16 02:31:48 MST 2012
Hello everyone,

I have CAN interrupt as folllows:


NVIC_EnableIRQ (CAN_IRQn);
...
void CAN_IRQHandler ()
{
    if ( (LPC_CAN2->ICR) && (0x08))    // IDIE
    {
        LPC_GPIO1->FIOSET |= (1<<28);
        delay (150);
    }
    LPC_GPIO1->FIOCLR |= (1<<28);
    delay (150);
}


It generaly works but how to stop this interrupt. The ICR register is read only so I can't do "(LPC_CAN2->ICR &=~(1<<8);" to go out of the IRQ loop.
0 件の賞賛
返信
3 返答(返信)

1,850件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Fri Feb 17 03:03:14 MST 2012
Just a few notes :rolleyes:

Note#1: It's not necessary to read FIOSET / FIOCLR register, so:[INDENT]
LPC_GPIO1->FIOSET = (1<<28);
[/INDENT]is doing the same job (faster)

Note#2: Could be helpful to Release Receive Buffer even if your RID isn't received:[INDENT]
LPC_CAN2->CMR = 0x01 << 2; /* release receive buffer */
[/INDENT]Note#3: CMR is WO register, so it's useless to read it

Note#4: Could be useful to read Transmitter Holding Register Empty (THRE) before writing to UART to avoid strange behaviour.

Note#5: Usually a complete message is stored and a flag is set to avoid timing problems in ISR.

Note#6: There are working samples available They show how to work with CAN interrupt. Example: can.c of CAN project (NXP_LPCXpresso1769_MCB1700_2011-02-11.zip)

/******************************************************************************
** Function name:        CAN_ISR_Rx1
**
** Descriptions:        CAN Rx1 interrupt handler
**
** parameters:            None
** Returned value:        None
** 
******************************************************************************/
void CAN_ISR_Rx1( void )
{
  uint32_t * pDest;

  /* initialize destination pointer    */
  pDest = (uint32_t *)&MsgBuf_RX1;
  *pDest = LPC_CAN1->RFS;  /* Frame    */

  pDest++;
  *pDest = LPC_CAN1->RID; /* ID    */

  pDest++;
  *pDest = LPC_CAN1->RDA; /* Data A */

  pDest++;
  *pDest = LPC_CAN1->RDB; /* Data B    */
    
  CAN1RxDone = TRUE;
  LPC_CAN1->CMR = 0x01 << 2; /* release receive buffer */
  return;
}

/******************************************************************************
** Function name:        CAN_ISR_Rx2
**
** Descriptions:        CAN Rx2 interrupt handler
**
** parameters:            None
** Returned value:        None
** 
******************************************************************************/
void CAN_ISR_Rx2( void )
{
  uint32_t *pDest;

  /* initialize destination pointer    */
  pDest = (uint32_t *)&MsgBuf_RX2;
  *pDest = LPC_CAN2->RFS;  /* Frame    */

  pDest++;
  *pDest = LPC_CAN2->RID; /* ID    */

  pDest++;
  *pDest = LPC_CAN2->RDA; /* Data A    */

  pDest++;
  *pDest = LPC_CAN2->RDB; /* Data B    */

  CAN2RxDone = TRUE;
  LPC_CAN2->CMR = 0x01 << 2; /* release receive buffer */
  return;
}

/*****************************************************************************
** Function name:        CAN_Handler
**
** Descriptions:        CAN interrupt handler
**
** parameters:            None
** Returned value:        None
** 
*****************************************************************************/
void CAN_IRQHandler(void)  
{        
  CANStatus = LPC_CANCR->RxSR;
  if ( CANStatus & (1 << 8) )
  {
    CAN1RxCount++;
    CAN_ISR_Rx1();
  }
  if ( CANStatus & (1 << 9) )
  {
    CAN2RxCount++;
    CAN_ISR_Rx2();
  }
  if ( LPC_CAN1->GSR & (1 << 6 ) )
  {
    /* The error count includes both TX and RX */
    CAN1ErrCount = LPC_CAN1->GSR >> 16;
  }
  if ( LPC_CAN2->GSR & (1 << 6 ) )
  {
    /* The error count includes both TX and RX */
    CAN2ErrCount = LPC_CAN2->GSR >> 16;
  }
  return;
}
0 件の賞賛
返信

1,850件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by teslabox on Fri Feb 17 00:52:12 MST 2012
I wrote this part of code as follows:

...
int main (void)
{
    UART1_Init ();
    UART1_Bitrate (115200);
    CAN2_Init ();
    CAN2_Bitrate (125000);
    NVIC_EnableIRQ (CAN_IRQn);   
    LPC_CAN2->IER |= (1<<8);
    ...
    for (;;) {}
  
   return (0);
}
void CAN_IRQHandler ()
{
    uint32_t temp = 0;

    if (LPC_CAN2->ICR & (1<<8))     //read IDI
    {
        LPC_GPIO1->FIOSET |= (1<<28);
        if ((LPC_CAN2->RID) == 182)
        {
            temp = (((LPC_CAN2->RDB) & (0x00FF0000)) >> 16);
            LPC_UART1->THR = temp;
            LPC_CAN2->CMR |= (1<<2);
        }
    }
    LPC_GPIO1->FIOCLR |= (1<<28);
}

and it works quite good but there is one strange behavior.There is some byte shift between CAN Transmitter and UART Receiver. I write an example:


Quote:
CAN Transmitter: 00 00 00 04  05 06 07 08 (bytes values)
UART Receiver:  00 00 00 00 04 05 06 07 08 (bytes values) -> first byte is always 00 (it doesn't matter whtat was sent from CAN)

I send CAN messages from CAN King KVASER from my PC and I receive UART bytes on the Termite or RealTerm (RS-232 terminal) on my PC.

It isn't a big problem but why it happens?
0 件の賞賛
返信

1,850件の閲覧回数
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu Feb 16 03:30:16 MST 2012
I'm not sure what you are trying to do :eek:

What's that?


Quote:

if ( (LPC_CAN2->ICR) [B][COLOR=Red]&&[/COLOR][/B] ([B][COLOR=DarkOrange]0x08[/COLOR][/B]))    // IDIE

Are you trying to read DOI or IDI?


Quote:

if (LPC_CAN2->ICR & (1<<8))    //read IDI

User manual:

Quote:
16.7.4 CAN Interrupt and Capture Register (CAN1ICR - 0x4004 400C, CAN2ICR - 0x4004 800C)
Bits in this register indicate information about events on the CAN bus. This register is
read-only.

The Interrupt flags of the Interrupt and Capture Register allow the identification of an
interrupt source. When one or more bits are set, a CAN interrupt will be indicated to the
CPU. [COLOR=Red]After this register is read from the CPU all interrupt bits are reset[/COLOR] except of the
Receive Interrupt bit. The Interrupt Register appears to the CPU as a read-only memory.
Bits 1 through 10 clear when they are read.

0 件の賞賛
返信