1 | //Pre-Processor Directives:
|
2 | #include <p30fxxxx.h>
|
3 | #include "system.h"
|
4 |
|
5 | //Werte zur Berechnung von dem Baudrateprescaler siehe dsPIC_CAN_Manual.pdf 23.10
|
6 | //--------------------------------------------------------------------- //Reference Manual
|
7 | #define FCY 15000000 // 15 MHz !!
|
8 | #define BITRATE 500000 // 0,5Mbps oder 500KHz
|
9 | #define NTQ 15 // Number of Tq cycles which will make the
|
10 | //CAN Bit Timing .
|
11 | #define BRP_VAL ((FCY/(2*NTQ*BITRATE))-1) //Formel für Baudrateprescaler C1CFG1bits.BRP
|
12 | //---------------------------------------------------------------------
|
13 |
|
14 |
|
15 | //Declaration to Link External Functions & Variables:
|
16 |
|
17 |
|
18 | //Functions and Variables with Global Scope:
|
19 | void CAN_Init ( unsigned int pos);
|
20 | void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void); //Interrupt Routine zum Empfangen von CAN Nachrichten
|
21 |
|
22 | // Buffer Registers for CAN data to be send out in the transmit mode.
|
23 | // hier stehen die Daten, die man über CAN schickt
|
24 |
|
25 | //unsigned
|
26 | int OutData0[2] = {0x0000, 0x0001}; //Position Byte 0&1:, Command Byte 2 z.B. 1 für Positionieren
|
27 |
|
28 |
|
29 | // Intilializing the receive registers to be 0
|
30 |
|
31 | unsigned int InData0[4] = {0, 0, 0, 0};
|
32 | unsigned int InData1[2] = {0, 0};
|
33 | unsigned int InData2[4] = {0, 0, 0, 0};
|
34 | unsigned int InData3[2] = {0, 0};
|
35 |
|
36 | //---------------------------------------------------------------------
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | //Functions
|
43 | //CAN_Init() sets up the CAN-Module
|
44 |
|
45 |
|
46 | void CAN_Init (unsigned int pos)
|
47 | {
|
48 |
|
49 | //C1CTRLbits.CANCAP = 1;
|
50 | //--------------------------------------------------------------------------------------------------------------------
|
51 | //Initialization of CAN1 Module and Enabling of CAN1 Interrupts
|
52 | //--------------------------------------------------------------------------------------------------------------------
|
53 |
|
54 | // siehe dsPIC_CAN_Manual.pdf 23.10.1 Bit Timing und 23.2.6 CAN Baud Rate Registers
|
55 |
|
56 | C1CTRLbits.CANCKS = 1; // Select the CAN Master Clock . It is equal to Fcy here.
|
57 | // equal to Fcy.(Fcy=15Mhz)
|
58 |
|
59 |
|
60 | C1CFG1bits.SJW=2; //Synchronized jump width time is 3 x TQ when SJW is equal to 0b10
|
61 |
|
62 |
|
63 | C1CFG1bits.BRP = BRP_VAL; //((FCY/(2*NTQ*BITRATE))-1)
|
64 | // siehe dsPIC_CAN_Manual.pdf 23.2.6 CAN Baud Rate Registers, Register 23-20: CiCFG2: Baud Rate Configuration Register 2
|
65 | C1CFG2 = 0x02FA; // SEG1PH=8Tq, SEG2PH=2Tq, PRSEG=2Tq, Tsync=1Tq
|
66 | // Sample 1 times
|
67 | // Each bit time is Tsync+SEG1PH+SEG2PH+PRSEG=13Tq
|
68 | // Nach Baudrate-Berechnung sollte 15Tq rauskommen, wegen Taktabweichung sollte aber auf 13Tq gestellt werden
|
69 |
|
70 | ///Interrupt Section of CAN Peripheral
|
71 |
|
72 | C1INTF = 0; //Reset all The CAN Interrupts
|
73 | IFS1bits.C1IF = 0; //Reset the Interrupt Flag status register
|
74 | C1INTE = 0x00FF; //Enable all CAN interrupt sources
|
75 | IEC1bits.C1IE = 1; //Enable the CAN1 Interrupt
|
76 |
|
77 | //-----------------------------------------------------------------------------------------------------------------------
|
78 | // Configure Receive registers, Filters and Masks
|
79 | //-----------------------------------------------------------------------------------------------------------------------
|
80 |
|
81 | // We are initializing the Receive Buffer 0 and Receive Buffer 1 for CAN
|
82 |
|
83 | C1RX0CON = 0x0006; // Receive Buffer 0 -- dsPIC Family reference Manual Seite.8
|
84 | C1RX1CON = 0x0000; //Receive Buffer 1 and Control Register for CAN1 -- dsPIC Family reference Manual Seite.8
|
85 |
|
86 | // Identifier Actuator_to_Tool : 0x18FF0D82 Receive register wird in SID und EID aufgeteilt
|
87 | //von bit 0 bis bit 17 in den EID, den Rest in den SID
|
88 |
|
89 | C1RX0SID = 0x18FD; // SID 0x63F --dsPIC Family reference Manual Seite.10
|
90 | C1RX0EID = 0x0C36; // EID 30D82
|
91 | C1RX0DLC = 0x0806; //Select the Data word Length for CAN1 Receive Buffer0
|
92 |
|
93 |
|
94 | // Acceptance Mask Register0SID and Register1SID associated with Recieve Buffer0
|
95 | // and Receive Buffer1 for CAN1
|
96 | C1RXM0SID = C1RXM1SID = 0x18FC; //siehe dsPIC_CAN_Manual.pdf--dsPIC Family reference Manual Seite.22
|
97 |
|
98 | // Acceptance Mask Register0EIDH and Register1EIDH associated with Recieve Buffer0
|
99 | // and Receive Buffer1 for CAN1
|
100 | C1RXM0EIDH = C1RXM1EIDH = 0x0C36;
|
101 |
|
102 | // Acceptance Mask Register0EIDL and Register1EIDL associated with Recieve Buffer0
|
103 | //and Receive Buffer1 for CAN1
|
104 | C1RXM0EIDL = C1RXM1EIDL = 0x800;
|
105 |
|
106 |
|
107 | // Acceptance Filter wird in SID und EID aufgeteilt
|
108 |
|
109 | C1RXF0SID = C1RXF1SID = C1RXF2SID = C1RXF3SID = C1RXF4SID = C1RXF5SID = 0x18FD; //CAN1 Receive Acceptance Filter2 SID
|
110 | C1RXF0EIDH = C1RXF1EIDH = C1RXF2EIDH = C1RXF3EIDH = C1RXF4EIDH = C1RXF5EIDH = 0xC36; //CAN1 Receive Acceptace Filter2 Extended Identifier high byte
|
111 | C1RXF0EIDL = C1RXF1EIDL = C1RXF2EIDL = C1RXF3EIDL = C1RXF4EIDL = C1RXF5EIDL = 0x800; //CAN1 Receive Acceptance Filter2 Extended identifier low byte
|
112 |
|
113 | InData0[0] = C1RX0B1;
|
114 | InData0[1] = C1RX0B2; //Move the recieve data from Buffers to InData
|
115 | InData0[2] = C1RX0B3;
|
116 | InData0[3] = C1RX0B4;
|
117 | InData1[0] = C1RX1B1; //Move the data received to Indata Registers
|
118 | InData1[1] = C1RX1B2;
|
119 |
|
120 |
|
121 |
|
122 | // Enable reception
|
123 |
|
124 | /*C1CTRLbits.CANCAP = 1;
|
125 | C1CTRLbits.REQOP = 0;
|
126 | while(C1CTRLbits.OPMODE != 0);*/
|
127 |
|
128 |
|
129 | C1RX0CONbits.DBEN = 1;
|
130 | C1RX0CONbits.JTOFF = 1;
|
131 |
|
132 |
|
133 | //-----------------------------------------------------------------------------------------------------------------------
|
134 | // Configure Transmit Registers Buffer 0 and Transmit Buffer 1
|
135 | //-----------------------------------------------------------------------------------------------------------------------
|
136 |
|
137 | C1TX0CON = 0x0003; // High priority
|
138 | //Steller identifier SRA 0x08FF8201 wird in SID und EID aufgeteilt
|
139 | //von bit 0 bis bit 17 in den EID, den Rest in den SID
|
140 | C1TX0SID = 0x40FD; // SID 0x23F
|
141 | C1TX0EID = 0xE008; // EID 0x38201
|
142 | C1TX0DLC = 0x0420; //Select the Data word Length for CAN1 Transmit Buffer0 which is 4 byte
|
143 | // identifier SRA 0x08FF8201 wird aufgeteilt auf Extended und Standard Identifier
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | // Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 4 bytes selected by DLC
|
149 |
|
150 | OutData0[0]=pos; //Übergabeparameter pos umgerechnet von Analogspannung Poti, oder Messgalgen
|
151 |
|
152 | C1TX0B1 = OutData0[0]; //Zuweisung der Pos. Byte 0&1 ind den Buffer 1 schreiben
|
153 | C1TX0B2 = OutData0[1]; //Zuweisung des Behehls z.B. 1 für Positionieren, 2 für Einlernen
|
154 |
|
155 |
|
156 |
|
157 |
|
158 | //Change to Normal Operation Mode from Configuration Mode
|
159 |
|
160 | C1CTRLbits.REQOP = 0;
|
161 | while(C1CTRLbits.OPMODE != 0);//Wait for CAN1 mode change from Configuration Mode to Normal mode
|
162 |
|
163 | //Enable transmission
|
164 |
|
165 | C1TX0CONbits.TXREQ = 1;
|
166 | C1TX1CONbits.TXREQ = 1;
|
167 |
|
168 |
|
169 |
|
170 |
|
171 | }
|
172 |
|
173 | //--------------------------------------------------------------------------------------------------------------------------
|
174 | //Interrupt Section for CAN1
|
175 | //--------------------------------------------------------------------------------------------------------------------------
|
176 |
|
177 | void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void)
|
178 | {
|
179 |
|
180 | IFS1bits.C1IF = 0; //Clear interrupt flag
|
181 |
|
182 | if(C1INTFbits.TX0IF)
|
183 | {
|
184 | LATBbits.LATB1 =~ LATBbits.LATB1; //Toggle LATB1 (LED D4 blinkt beim Senden)
|
185 | C1INTFbits.TX0IF = 0; //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt
|
186 |
|
187 | }
|
188 | else if(C1INTFbits.TX1IF)
|
189 | {
|
190 | LATBbits.LATB1 =~ LATBbits.LATB1;
|
191 | C1INTFbits.TX1IF = 0; //If the Interrupt is due to Transmit1 of CAN1 Clear the Interrupt
|
192 |
|
193 | }
|
194 |
|
195 | if(C1INTFbits.RX0IF )
|
196 | {
|
197 | LATBbits.LATB0 =~ LATBbits.LATB0; //Toggle LATB0 (LED D3 soll beim Empfang blinken...tut aber nichts)
|
198 | C1INTFbits.RX0IF = 0; //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt
|
199 |
|
200 | InData0[0] = C1RX0B1;
|
201 | InData0[1] = C1RX0B2; //Move the recieve data from Buffers to InData
|
202 | InData0[2] = C1RX0B3;
|
203 | InData0[3] = C1RX0B4;
|
204 |
|
205 | //InData - Empfangene Daten können ausgewertet werden
|
206 | }
|
207 |
|
208 | else if(C1INTFbits.RX1IF)
|
209 | {
|
210 | LATBbits.LATB0 =~ LATBbits.LATB0; //Toggle LATB0 (LED D3soll beim Empfang blinken...tut aber nichts)
|
211 | C1INTFbits.RX1IF = 0; //If the Interrupt is due to Receive1 of CAN1 Clear the Interrupt
|
212 | InData1[0] = C1RX1B1; //Move the data received to Indata Registers
|
213 | InData1[1] = C1RX1B2;
|
214 | }
|
215 | }
|