còn đây là code của chương trình main và xử lý ngắt của CAN
Code:
#include <p30F4012.h>
_FOSC(CSW_FSCM_OFF & FRC_PLL16)
;
_FWDT(WDT_OFF)
;
_FBORPOR(PBOR_OFF & MCLR_EN & PWMxL_ACT_HI & PWMxH_ACT_HI)
;
_FGS(CODE_PROT_OFF)
;
//Cac hang so cua chuong trinh (gia tri tuc thoi dung trong chuong trinh)
#define PWM_PORT PORTE //Cac tin hieu PWM nam o cong E
#define PWM_TRIS TRISE //Thanh ghi 3 trang thai cho cac tin hieu PWM
#define PWM_LAT LATE //Thanh ghi chot cac tin hieu PWM
#define FCY 30000000 // 30 MHz
#define BITRATE 1000000 // 1Mbps
#define NTQ 15 // Number of Tq cycles which will make the
//CAN Bit Timing .
#define BRP_VAL ((FCY/(2*NTQ*BITRATE))-1) //Formulae used for C1CFG1bits.BRP
#define BlueLed _LATE3
#define RedLed _LATE4
#define Switch _RE2
//---------------------------------------------------------------------
void init_can1(void);
void Init_ADC10(void);
// Buffer Registers for CAN data to be send out in the transmit mode.
unsigned int OutData0[4] = {0x5251, 0x5453, 0x5655, 0x5857};
unsigned int OutData1[2] = {0x5A59, 0x5C5B};
// Intilializing the receive registers to be 0
unsigned int InData0[4] = {0x5251, 0x5453, 0x5655, 0x5857};
unsigned int InData1[2] = {0x5A59, 0x5C5B};
//---------------------------------------------------------------------
unsigned long BlueLedCounter=0;
unsigned int ADCValue;
int main(void)
{
init_can1();
// Init_ADC10();
TRISD = 0x0000; // Initialize the PORTD as output
LATD = 0xFFFF;
LATE = 0xffe7;
TRISE = 0xFFe7; // LED noi vao E4 va E3
// Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 8 bytes selected by DLC
C1TX0B1 = OutData0[0];
C1TX0B2 = OutData0[1];
C1TX0B3 = OutData0[2];
C1TX0B4 = OutData0[3];
//Data Field 1, Data Field 2 // 4 bytes selected by DLC
C1TX1B1 = OutData1[0];
C1TX1B2 = OutData1[1];
while(1)
{
BlueLedCounter++;
if(BlueLedCounter>120000)
{
BlueLedCounter=0;
if(Switch==0)
{
C1TX1B1 = OutData1[0];
C1TX1B2 = OutData1[1];
C1TX1CONbits.TXREQ = 1;
}
else{
C1TX0B1 = OutData0[0];
C1TX0B2 = OutData0[1];
C1TX0B3 = OutData0[2];
C1TX0B4 = OutData0[3];
C1TX0CONbits.TXREQ = 1;
}
}
} //end while loop
}
//--------------------------------------------------------------------------------------------------------------------------
//Interrupt Section for CAN1
//--------------------------------------------------------------------------------------------------------------------------
void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void)
{
IFS1bits.C1IF = 0; //Clear interrupt flag
if(C1INTFbits.TX0IF)
{
C1INTFbits.TX0IF = 0; //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt
}
else if(C1INTFbits.TX1IF)
{
C1INTFbits.TX1IF = 0; //If the Interrupt is due to Transmit1 of CAN1 Clear the Interrupt
}
if(C1INTFbits.RX0IF)
{
C1INTFbits.RX0IF = 0; //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt
InData0[0] = C1RX0B1;
InData0[1] = C1RX0B2; //Move the recieve data from Buffers to InData
InData0[2] = C1RX0B3;
InData0[3] = C1RX0B4;
if ((InData0[0]==OutData0[0]) && (InData0[1]==OutData0[1]) && (InData0[2]==OutData0[2]) && (InData0[3]==OutData0[3]))
RedLed^=1; // If the data received is same which was transmitted
}
else if(C1INTFbits.RX1IF)
{
C1INTFbits.RX1IF = 0; //If the Interrupt is due to Receive1 of CAN1 Clear the Interrupt
InData1[0] = C1RX1B1; //Move the data received to Indata Registers
InData1[1] = C1RX1B2;
//if ((InData1[0]==OutData1[0]) && (InData1[1]==OutData1[1]))
if(InData1[0]==0x5A59)
BlueLed^=1; //If the data received is same which was transmitted
}
C1RX0CON = C1RX1CON = 0x0000;
}
trong này, tôi có định nghĩa 2 led để kiểm tra dữ liệu nhận được. chương trình này được nạp trực tiếp cho 2 chip 30f4012 giao tiếp thử nghiệm với nhau.