В данной теме хочу охватить сразу два вопроса:
1. Настройка CAN и PLL
2. Настройка прерывания по приему на CAN
1. Начал разбираться с CANом, настраиваю скорость CAN без PLL - все в прядке, включаю PLL - CAN не коректно работает.
Посмотрите код может что-то я упустил.
2. Не могу настроить прерывания по приходу данных на CAN.
CODE
Собственно сам код
#include "LPC23xx.h" /* LPC23xx definitions */
#include <stdlib.h>
#include "type.h"
#include "irq.h"
#define PLL_MValue 11
#define PLL_NValue 0
typedef struct
{
DWORD Frame; // Bits 16..19: DLC - Data Length Counter
// Bit 30: Set if this is a RTR message
// Bit 31: Set if this is a 29-bit ID message
DWORD MsgID; // CAN Message ID (11-bit or 29-bit)
DWORD DataA; // CAN Message Data Bytes 0-3
DWORD DataB; // CAN Message Data Bytes 4-7
} CAN_MSG;
CAN_MSG MsgBuf_RX1;
unsigned long ReceiveDate1;
unsigned long ReceiveDate2;
void ConfigurePLL ( void )
{
unsigned long MValue, NValue;
if ( PLLSTAT & (1 << 25) )
{
PLLCON = 1; /* Enable PLL, disconnected */
PLLFEED = 0xaa;
PLLFEED = 0x55;
}
PLLCON = 0; /* Disable PLL, disconnected */
PLLFEED = 0xaa;
PLLFEED = 0x55;
SCS |= 0x20; /* Enable main OSC */
while( !(SCS & 0x40) ); /* Wait until main OSC is usable */
CLKSRCSEL = 0x1; /* select main OSC, 12MHz, as the PLL clock source */
PLLCFG = PLL_MValue | (PLL_NValue << 16);
PLLFEED = 0xaa;
PLLFEED = 0x55;
PLLCON = 1; /* Enable PLL, disconnected */
PLLFEED = 0xaa;
PLLFEED = 0x55;
CCLKCFG = 3; /* Set clock divider */
while ( ((PLLSTAT & (1 << 26)) == 0) ); /* Check lock bit status */
MValue = PLLSTAT & 0x00007FFF;
NValue = (PLLSTAT & 0x00FF0000) >> 16;
while ((MValue != PLL_MValue) && ( NValue != PLL_NValue) );
PLLCON = 3; /* enable and connect */
PLLFEED = 0xaa;
PLLFEED = 0x55;
while ( ((PLLSTAT & (1 << 25)) == 0) ); /* Check connect bit status */
return;
}
void CANRec(void) __irq
{
DWORD * pDest;
// initialize destination pointer
pDest = (DWORD *)&MsgBuf_RX1;
*pDest = CAN1RFS; // Frame
pDest++;
*pDest = CAN1RID; // ID //change by gongjun
pDest++;
*pDest = CAN1RDA; // Data A
pDest++;
*pDest = CAN1RDB; // Data B
CAN1CMR = 0x04; // release receive buffer
VICVectAddr = 0;
return;
}
void InitCAN()
{
CAN1MOD = 1; // Reset CAN
PINSEL0 &= ~(0xF<<0);
PINSEL0 |= (0x5<<0); // enable PIN for CAN1
PCONP |= (1 << 13);
CAN1IER = 0; // Disable Receive Interrupt
//CAN1BTR = 0x0036002F;
// PCLKSEL0 = (1<<26);
CAN1BTR = 0x0015000C;
CAN_AFMR = 2;
CAN1IER = 0x00000001;
VICVectPriority0 = 0x00000001;
VICVectAddr0 = (unsigned)CANRec;
VICIntEnable = (1<<23);
CAN1MOD = 0;
}
void SendCAN(unsigned long Date)
{
while (CAN1SR&0x00000004)
{
CAN1TFI1 = 0x00040000;
CAN1TID1 = 0x00000001;
CAN1TDA1 = Date;
CAN1CMR = 1;
}
}
int main()
{
//ConfigurePLL();
InitCAN();
while (1)
{
if (MsgBuf_RX1.DataA == 0) SendCAN(0x55555555);
else SendCAN(MsgBuf_RX1.DataA);
for (long i=0; i<0x999999;i++);
}
}
Причина редактирования: Пользуйтесь тэгами для форматирования исходников