//Pre-Processor Directives: #include #include "system.h" //Werte zur Berechnung von dem Baudrateprescaler siehe dsPIC_CAN_Manual.pdf 23.10 //--------------------------------------------------------------------- //Reference Manual #define FCY 15000000 // 15 MHz !! #define BITRATE 500000 // 0,5Mbps oder 500KHz #define NTQ 15 // Number of Tq cycles which will make the //CAN Bit Timing . #define BRP_VAL ((FCY/(2*NTQ*BITRATE))-1) //Formel für Baudrateprescaler C1CFG1bits.BRP //--------------------------------------------------------------------- //Declaration to Link External Functions & Variables: //Functions and Variables with Global Scope: void CAN_Init ( unsigned int pos); void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void); //Interrupt Routine zum Empfangen von CAN Nachrichten // Buffer Registers for CAN data to be send out in the transmit mode. // hier stehen die Daten, die man über CAN schickt //unsigned int OutData0[2] = {0x0000, 0x0001}; //Position Byte 0&1:, Command Byte 2 z.B. 1 für Positionieren // Intilializing the receive registers to be 0 unsigned int InData0[4] = {0, 0, 0, 0}; unsigned int InData1[2] = {0, 0}; unsigned int InData2[4] = {0, 0, 0, 0}; unsigned int InData3[2] = {0, 0}; //--------------------------------------------------------------------- //Functions //CAN_Init() sets up the CAN-Module void CAN_Init (unsigned int pos) { //C1CTRLbits.CANCAP = 1; //-------------------------------------------------------------------------------------------------------------------- //Initialization of CAN1 Module and Enabling of CAN1 Interrupts //-------------------------------------------------------------------------------------------------------------------- // siehe dsPIC_CAN_Manual.pdf 23.10.1 Bit Timing und 23.2.6 CAN Baud Rate Registers C1CTRLbits.CANCKS = 1; // Select the CAN Master Clock . It is equal to Fcy here. // equal to Fcy.(Fcy=15Mhz) C1CFG1bits.SJW=2; //Synchronized jump width time is 3 x TQ when SJW is equal to 0b10 C1CFG1bits.BRP = BRP_VAL; //((FCY/(2*NTQ*BITRATE))-1) // siehe dsPIC_CAN_Manual.pdf 23.2.6 CAN Baud Rate Registers, Register 23-20: CiCFG2: Baud Rate Configuration Register 2 C1CFG2 = 0x02FA; // SEG1PH=8Tq, SEG2PH=2Tq, PRSEG=2Tq, Tsync=1Tq // Sample 1 times // Each bit time is Tsync+SEG1PH+SEG2PH+PRSEG=13Tq // Nach Baudrate-Berechnung sollte 15Tq rauskommen, wegen Taktabweichung sollte aber auf 13Tq gestellt werden ///Interrupt Section of CAN Peripheral C1INTF = 0; //Reset all The CAN Interrupts IFS1bits.C1IF = 0; //Reset the Interrupt Flag status register C1INTE = 0x00FF; //Enable all CAN interrupt sources IEC1bits.C1IE = 1; //Enable the CAN1 Interrupt //----------------------------------------------------------------------------------------------------------------------- // Configure Receive registers, Filters and Masks //----------------------------------------------------------------------------------------------------------------------- // We are initializing the Receive Buffer 0 and Receive Buffer 1 for CAN C1RX0CON = 0x0000; // Receive Buffer 0 -- dsPIC Family reference Manual Seite.8//0x0006 C1RX1CON = 0x0000; //Receive Buffer 1 and Control Register for CAN1 -- dsPIC Family reference Manual Seite.8 // Identifier Actuator_to_Tool : 0x08FF1082 Receive register wird in SID und EID aufgeteilt //von bit 0 bis bit 17 in den EID, den Rest in den SID C1RX0SID = C1RX1SID = 0x08FD; // SID 0x23F --dsPIC Family reference Manual Seite.10 C1RX0SIDbits.RXIDE = C1RX1SIDbits.RXIDE = 1; C1RX0EID = C1RX1EID = 0x0C42; // EID 0x31082 C1RX0DLC = C1RX1DLC = 0xFC04; //Select the Data word Length for CAN1 Receive Buffer0 // Acceptance Mask Register0SID and Register1SID associated with Recieve Buffer0 // and Receive Buffer1 for CAN1 C1RXM0SID = C1RXM1SID =0x1FFD; C1RXM0SIDbits.MIDE = C1RXM1SIDbits.MIDE = 1; // Acceptance Mask Register0EIDH and Register1EIDH associated with Recieve Buffer0 // and Receive Buffer1 for CAN1 C1RXM0EIDH = C1RXM1EIDH = 0x0FFF; // Acceptance Mask Register0EIDL and Register1EIDL associated with Recieve Buffer0 //and Receive Buffer1 for CAN1 C1RXM0EIDL = C1RXM1EIDL = 0xFC00; // Acceptance Filter wird in SID und EID aufgeteilt C1RXF0SID = 0x08FD; C1RXF0SIDbits.EXIDE = 1; C1RXF0EIDH =0x0C42; C1RXF0EIDL =0x0800; C1RXF2SID = 0x08FD; //CAN1 Receive Acceptance Filter2 SID C1RXF2SIDbits.EXIDE = 1; C1RXF2EIDH =0x0C42; //CAN1 Receive Acceptace Filter2 Extended Identifier high byte C1RXF2EIDL =0x0800; //CAN1 Receive Acceptance Filter2 Extended identifier low byte //----------------------------------------------------------------------------------------------------------------------- // Configure Transmit Registers Buffer 0 and Transmit Buffer 1 //----------------------------------------------------------------------------------------------------------------------- C1TX0CON = 0x0003; // High priority //Steller identifier SRA 0x08FF8201 wird in SID und EID aufgeteilt //von bit 0 bis bit 17 in den EID, den Rest in den SID C1TX0SID = 0x40FD; // SID 0x23F C1TX0EID = 0xE008; // EID 0x38201 C1TX0DLC = 0x0420; //Select the Data word Length for CAN1 Transmit Buffer0 which is 4 byte // identifier SRA 0x08FF8201 wird aufgeteilt auf Extended und Standard Identifier // Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 4 bytes selected by DLC OutData0[0]=pos; //Übergabeparameter pos umgerechnet von Analogspannung Poti, oder Messgalgen C1TX0B1 = OutData0[0]; //Zuweisung der Pos. Byte 0&1 ind den Buffer 1 schreiben C1TX0B2 = OutData0[1]; //Zuweisung des Behehls z.B. 1 für Positionieren, 2 für Einlernen //Change to Normal Operation Mode from Configuration Mode C1CTRLbits.REQOP = 0; while(C1CTRLbits.OPMODE != 0);//Wait for CAN1 mode change from Configuration Mode to Normal mode //Enable transmission C1TX0CONbits.TXREQ = 1; C1TX1CONbits.TXREQ = 1; } //-------------------------------------------------------------------------------------------------------------------------- //Interrupt Section for CAN1 //-------------------------------------------------------------------------------------------------------------------------- void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void) { IFS1bits.C1IF = 0; //Clear interrupt flag if(C1INTFbits.TX0IF) { LATBbits.LATB1 =~ LATBbits.LATB1; //Toggle LATB1 (LED D4 blinkt beim Senden) C1INTFbits.TX0IF = 0; //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt } else if(C1INTFbits.TX1IF) { LATBbits.LATB1 =~ LATBbits.LATB1; C1INTFbits.TX1IF = 0; //If the Interrupt is due to Transmit1 of CAN1 Clear the Interrupt } if(C1INTFbits.RX0IF ) { LATBbits.LATB0 =~ LATBbits.LATB0;//Toggle LATB0 (LED D3 soll beim Empfang blinken...tut aber nichts) 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; //InData - Empfangene Daten können ausgewertet werden } else if(C1INTFbits.RX1IF) { LATBbits.LATB0 =~ LATBbits.LATB0; //Toggle LATB0 (LED D3 blinkt soll beim Empfang blinken...tut aber nichts) 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; } }