初步成功的代码贴出来和大家分享了:
#include "LPC23xx.h"
#include "type.h"
#include "irq.h"
#include "can.h"
#include "uart.h"
// Receive Queue: one queue for each CAN port
extern CAN_MSG MsgBuf_RX1;
extern volatile DWORD CAN1RxDone;
extern volatile DWORD FullCANRxDone;
DWORD CANStatus;
DWORD CAN1RxCount = 0;
DWORD CAN1ErrCount = 0;
_AF_AUTO_STORE_MSG FullCanAutoMsg;
/******************************************************************************
** Function name: CAN_ISR_Rx1
**
** Descriptions: CAN Rx1 interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void CAN_ISR_Rx1( void )
{
DWORD * pDest;
Print_Enter();
Print_String("The pro has entered the CAN_ISR_Rx1!");
// 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
CAN1RxDone = TRUE;
CAN1CMR = CAN1CMR | 0x04; // release receive buffer and reset RI flag
return;
}
/*****************************************************************************
** Function name: CAN_Handler
**
** Descriptions: CAN interrupt handler
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void CAN_Handler(void) __irq
{
unsigned int StatInt;
unsigned int StatIntOfFullCAN;
unsigned int dat;
unsigned int *pFrame;
_AF_ATUO_FRMSTAT_MSG * pAutoFrm;
//print the CAN1ICR register
StatInt = CAN1ICR; //when CAN1ICR is read,the relevant bit will be cleared but the RI
Print_Enter();
Print_String("The Pro has entered the CAN_Handler!");
Print_Enter();
PrintLong(StatInt);
//print the CAN_FULLCAN_IC0 register
Print_Enter();
StatIntOfFullCAN = CAN_FULLCAN_IC0;
Print_String("The CAN_FULLCAN_IC0 is : ");
PrintLong(StatIntOfFullCAN);
Print_Enter();
if(StatIntOfFullCAN) //received the FULLCAN Message
{
FullCANRxDone = TRUE;
//the Index is certain to be 2, and it may be modified.
pFrame = (unsigned int *)(0xE0038000+Size_LookUp_Table+2*12);
pAutoFrm = (_AF_ATUO_FRMSTAT_MSG *)(0xE0038000+Size_LookUp_Table+2*12);
//save the Message Frame State
FullCanAutoMsg.FRM.dwValue = *pFrame;
PrintLong(*pFrame); //print the Frame State
pAutoFrm->Bits.SEM = 0; //clear the semaphore
Print_Enter();
pFrame++;
FullCanAutoMsg.DataA = *pFrame; //Get the Data
PrintLong(FullCanAutoMsg.DataA);
Print_Enter();
pFrame++;
FullCanAutoMsg.DataB = *pFrame; //Get the Data
PrintLong(FullCanAutoMsg.DataB);
Print_Enter();
}
if(StatInt)
{
if(StatInt & (1<<0)) //the receive int
{
CAN_ISR_Rx1();
}
if(StatInt & (1<<1)) //the TX1 Interrupt
{
Print_Enter();
Print_String("The TX1 Int has taken place!");
}
if(StatInt & (1<<2)) //the error warning Interrupt
{
Print_Enter();
Print_String("The error warning Int has taken place!");
}
if(StatInt & (1<<3)) //the data overrun Interrupt
{
Print_Enter();
Print_String("The data overrun Int has taken place!");
}
if(StatInt & (1<<4)) //the Wake-Up Interrupt
{
Print_Enter();
Print_String("The Wake-Up Int has taken place!");
}
if(StatInt & (1<<5)) //the error passive Interrupt
{
Print_Enter();
Print_String("The Error Passive Int has taken place!");
}
if(StatInt & (1<<6)) //the Arbitration Lost Interrupt
{
Print_Enter();
Print_String("The Arbitration Lost Int has taken place!");
}
if(StatInt & (1<<7)) //the Bus Error Interrupt
{
Print_Enter();
Print_String("The Bus Error Int has taken place!");
}
if(StatInt & (1<<8)) //the ID Ready Interrupt
{
Print_Enter();
Print_String("The ID Ready Int has taken place!");
}
if(StatInt & (1<<9)) //the TX2 Interrupt
{
Print_Enter();
Print_String("The TX2 Int has taken place!");
}
if(StatInt & (1<<10)) //the TX3 Interrupt
{
Print_Enter();
Print_String("The TX3 Int has taken place!");
}
}
if ( CAN1GSR & (1 << 6 ) )
{
/* The error count includes both TX and RX */
CAN1ErrCount = (CAN1GSR >> 16 );
}
VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
/******************************************************************************
** Function name: CAN_Init
**
** Descriptions: Initialize CAN, install CAN interrupt handler
**
** parameters: bitrate
** Returned value: true or false, false if initialization failed.
**
******************************************************************************/
DWORD CAN_Init( DWORD can_btr )
{
CAN1RxDone = FALSE;
FullCANRxDone = FALSE;
PCONP |= (1 << 13) | (1 << 14); // Enable clock to the peripheral
PINSEL0 &= ~0x00000F0F;
PINSEL0 |= 0x0000A05; // port0.0~1, function 0x01, port0.4~5, function 0x10
CAN1MOD = CAN2MOD = 1; // Reset CAN
CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
CAN1BTR = CAN2BTR = can_btr;
CAN1MOD = CAN2MOD = 0x0; // CAN in normal operation mode
// Install CAN interrupt handler
install_irq( 23, (void *)CAN_Handler, HIGHEST_PRIORITY );
CAN1IER = CAN2IER = EIE | DOIE | WUIE | EPIE | ALIE | BEIE;//0x7FF;//0x01; // Enable receive interrupts
return( TRUE );
}
/******************************************************************************
** Function name: CAN_SetACCF_Lookup
**
** Descriptions: Initialize CAN, install CAN interrupt handler
**
** parameters: bitrate
**
** Returned value: true or false, false if initialization failed.
**
** Revised: 2009.11.1: add enable-bit of fullcan interrupt
******************************************************************************/
void CAN_SetACCF_Lookup( void )
{
DWORD address = 0;
_AF_SFF_CELL Id_Sff_Set;
CAN_SFF_SA = Size_LookUp_Table; // Set byte size of fullcan look-up table;
Id_Sff_Set.dwValue = 0;
Id_Sff_Set.Bits.UpID = EXP_STD_ID - 1; //the upper id
Id_Sff_Set.Bits.UpFuE = 1; //enble fullcan int bit
Id_Sff_Set.Bits.UpCh = 0;
Id_Sff_Set.Bits.LoID = EXP_STD_ID - 2; //the lower id
Id_Sff_Set.Bits.LoFuE = 1;
Id_Sff_Set.Bits.LoCh = 0;
*((volatile DWORD *)(CAN_MEM_BASE + address)) = Id_Sff_Set.dwValue;
address += 4;
Id_Sff_Set.dwValue = 0;
Id_Sff_Set.Bits.UpID = EXP_STD_ID+1; //the upper id
Id_Sff_Set.Bits.UpFuE = 1; //enble fullcan int bit
Id_Sff_Set.Bits.UpCh = 0;
Id_Sff_Set.Bits.LoID = EXP_STD_ID; //the lower id
Id_Sff_Set.Bits.LoFuE = 1;
Id_Sff_Set.Bits.LoCh = 0;
*((volatile DWORD *)(CAN_MEM_BASE + address)) = Id_Sff_Set.dwValue;
address += 4;
CAN_SFF_GRP_SA = address; // Set group standard Frame
CAN_EFF_SA = address; // Set explicit extended Frame
CAN_EFF_GRP_SA = address; // Set group extended Frame
CAN_EOT = address; // Set End of Table
CAN_FULLCAN_IE = 0x01; // Global Enable-bit of FullCan interrupt
return;
}
/******************************************************************************
** Function name: CAN_SetACCF
**
** Descriptions: Set acceptance filter and SRAM associated with
**
** parameters: ACMF mode
** Returned value: None
**
**
******************************************************************************/
void CAN_SetACCF( DWORD ACCFMode )
{
switch ( ACCFMode )
{
case ACCF_OFF:
CAN_AFMR = ACCFMode;
CAN1MOD = CAN2MOD = 1; // Reset CAN
CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
break;
case ACCF_BYPASS:
CAN_AFMR = ACCFMode;
break;
case ACCF_ON:
case ACCF_FULLCAN:
CAN_AFMR = ACCF_OFF;
CAN_SetACCF_Lookup();
CAN_AFMR = ACCF_FULLCAN;//ACCFMode;
break;
default:
break;
}
return;
}
/******************************************************************************
** Function name: CAN1_SendMessage
**
** Descriptions: Send message block to CAN1
**
** parameters: pointer to the CAN message
** Returned value: true or false, if message buffer is available,
** message can be sent successfully, return TRUE,
** otherwise, return FALSE.
**
******************************************************************************/
DWORD CAN1_SendMessage( CAN_MSG *pTxBuf )
{
DWORD CANStatus;
CANStatus = CAN1SR;
if ( CANStatus & 0x00000004 ) //visit TBS1 bit
{
CAN1TFI1 = pTxBuf->Frame & 0xC00F0000;
CAN1TID1 = pTxBuf->MsgID;
CAN1TDA1 = pTxBuf->DataA;
CAN1TDB1 = pTxBuf->DataB;
CAN1CMR = 0x21; //set TR and STB1 bit
return ( TRUE );
}
else if ( CANStatus & 0x00000400 )
{
CAN1TFI2 = pTxBuf->Frame & 0xC00F0000;
CAN1TID2 = pTxBuf->MsgID;
CAN1TDA2 = pTxBuf->DataA;
CAN1TDB2 = pTxBuf->DataB;
CAN1CMR = 0x41; //set TR and STB2 bit
return ( TRUE );
}
else if ( CANStatus & 0x00040000 )
{
CAN1TFI3 = pTxBuf->Frame & 0xC00F0000;
CAN1TID3 = pTxBuf->MsgID;
CAN1TDA3 = pTxBuf->DataA;
CAN1TDB3 = pTxBuf->DataB;
CAN1CMR = 0x81; //set TR and STB3 bit
return ( TRUE );
}
return ( FALSE );
}
/******************************************************************************
** End Of File
******************************************************************************/
|