Hi,
ich habe zwei boards mit je einem dspic30f4011, die über can
kommunizieren. Board a schickt eine nachricht los, board b antwortet.
1 | unsigned int OutData0[4] = {0x0000, 0x4444, 0x71C7, 0xAABA}; //SendData stored in OutData0 array.
|
2 | //Buffer {Byte 1&0, Byte 3&2, Byte 5&4, Byte 7&6};
|
3 |
|
4 | int CANModul(void){
|
5 | //Configuration Mode
|
6 | C1CTRLbits.REQOP = 0x4;
|
7 | while (C1CTRLbits.OPMODE != 0x4) {
|
8 | }
|
9 |
|
10 | //Configurate Bitrate
|
11 | C1CTRLbits.CANCKS = 0x01; // Fcan=Fcy
|
12 | C1CFG1bits.SJW = 0x00; // Sync=1Tq
|
13 | C1CFG1bits.BRP = BRP_VAL;
|
14 | C1CFG2 = 0x07FD; // SEG1PH=8Tq, SEG2PH=8Tq, PRSEG=6Tq
|
15 | // Each bit time is 23Tq
|
16 |
|
17 | ///Interrupt Section of CAN Peripheral
|
18 | C1INTF = 0; //Reset all The CAN Interrupts
|
19 | IFS1bits.C1IF = 0; //Reset the Interrupt Flag status register
|
20 | C1INTE = 0x00FF; //Enable all CAN interrupt sources
|
21 | IEC1bits.C1IE = 1; //Enable the CAN1 Interrupt
|
22 | CANModul_R();
|
23 | CANModul_T();
|
24 | //Change to Normal Operation Mode from Configuration Mode
|
25 | C1CTRLbits.REQOP = 0;
|
26 | while (C1CTRLbits.OPMODE != 0);
|
27 |
|
28 | return 0;
|
29 | }
|
30 |
|
31 | int CANModul_R(void){
|
32 | // Configure Receive registers, Filters and Masks
|
33 | C1RX0CON = 0x0000; //low priority in all received registers
|
34 | // Mask
|
35 | C1RXM0SID = 0x0001; // Mask for SID
|
36 | C1RXM0EIDH = 0x03FC; // Mask for EID high adress
|
37 | C1RXM0EIDL = 0x0000; // Mask for EID low adress
|
38 | // Filter 1 messages for iVA (0x01) will arrive
|
39 | C1RXF0SID = 0x0001; // Filter for SID
|
40 | C1RXF0EIDH = 0x0004; // Filter for EID high adress
|
41 | C1RXF0EIDL = 0x0000; // Filter for EID low adress
|
42 | // Filter 2 messages for everyone (0x00) will arrive
|
43 | C1RXF1SID = 0x0001; // Filter for SID
|
44 | C1RXF1EIDH = 0x0000; // Filter for EID high adress
|
45 | C1RXF1EIDL = 0x0000; // Filter for EID low adress
|
46 |
|
47 | return 0;
|
48 | }
|
49 |
|
50 | int CANModul_T(void) {
|
51 | // Configure Transmit Registers Buffer 0 and Transmit Buffer 1
|
52 | C1TX0CON = 0x0003; // High priority
|
53 | C1TX0SIDbits.TXIDE = 1; // TXIDE is set because extendet identifier is used
|
54 | // PRIO
|
55 | C1PRIO(0x00); // PRIO 0x0000 (priority -> highest priority)
|
56 | // SRC
|
57 | C1SRC(0x01); // SCR 0x01 (transceiver 0x01 -> iv)
|
58 | // DEST
|
59 | C1DEST(0x00); // DEST 0x00 (0x00 -> all)
|
60 | // CMD
|
61 | C1CMD(0x00); // CMD 0x01 (command 0x00 or request 0x01 -> request)
|
62 |
|
63 | C1TX0DLCbits.DLC = 0x1; // number of bytes
|
64 |
|
65 | // Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 8 bytes selected by DLC
|
66 | C1TX0B1 = OutData0[0];
|
67 | C1TX0B2 = OutData0[1];
|
68 | C1TX0B3 = OutData0[2];
|
69 | C1TX0B4 = OutData0[3];
|
70 |
|
71 | return 0;
|
72 | }
|
das ist der Code für die konfiguration des cans
1 | void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void) {
|
2 | if (C1INTFbits.TX0IF) {
|
3 | C1INTFbits.TX0IF = 0; //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt
|
4 | }
|
5 | if (C1INTFbits.RX0IF) {
|
6 | data = C1RX0B1; // now for display
|
7 | if(data==0x01){ // answer of attendance check (member is attendant)
|
8 | SRC = 4*C1RX0SIDbits.SID0 + 2*C1RX0EIDbits.EID17 + C1RX0EIDbits.EID16; // calculation of SRC
|
9 | if(SRC == 0x01)
|
10 | Rx_Flag |= Rx_iv;
|
11 | else if(SRC == 0x02)
|
12 | Rx_Flag |= Rx_el;
|
13 | else if(SRC == 0x03)
|
14 | Rx_Flag |= Rx_im_1;
|
15 | else if(SRC == 0x04)
|
16 | Rx_Flag |= Rx_im_2;
|
17 | }
|
18 | else{
|
19 | new_message = 1; // for MAIN-function
|
20 | }
|
21 | C1RX0CONbits.RXFUL = 0; // Clear the Buffer RXFUL to receive new messages
|
22 | C1INTFbits.RX0IF = 0; //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt
|
23 | }
|
24 | IFS1bits.C1IF = 0; //Clear interrupt flag
|
25 | }
|
dies ist der can-interrupt code für board a. Wenn board b mit den daten
0x01 antwortet, wird ein bestimmtes flag gesetzt. wenn nicht, wird mit
der nachricht etwas anderes gemacht.
1 | void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void) {
|
2 | if (C1INTFbits.TX0IF) {
|
3 | C1INTFbits.TX0IF = 0; //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt
|
4 | }
|
5 | if (C1INTFbits.RX0IF) {
|
6 | C1TX0B1 = 0x01; // answer -> active
|
7 | C1DEST(0x01); // DEST
|
8 |
|
9 | // send message as el 0x02
|
10 | LATBbits.LATB0 = 1; // Turn on LED D3
|
11 | C1SRC(0x02); // SRC -> el 0x02
|
12 | C1TX0CONbits.TXREQ = 1; //Start to send
|
13 | while (C1TX0CONbits.TXREQ == 1) {} //TXREQ reset automatically, when the transmission completes
|
14 |
|
15 | // send message as im_1 0x03
|
16 | LATBbits.LATB0 = 1; // Turn on LED D3
|
17 | C1SRC(0x03); // SRC -> im_1 0x03
|
18 | C1TX0CONbits.TXREQ = 1; //Start to send
|
19 | while (C1TX0CONbits.TXREQ == 1) {} //TXREQ reset automatically, when the transmission completes
|
20 |
|
21 | // send message as im_2 0x04
|
22 | LATBbits.LATB0 = 1; // Turn on LED D3
|
23 | C1SRC(0x04); // SRC -> im_2 0x04
|
24 | C1TX0CONbits.TXREQ = 1; //Start to send
|
25 | while (C1TX0CONbits.TXREQ == 1) {} //TXREQ reset automatically, when the transmission completes
|
26 |
|
27 | LATBbits.LATB0 = 0; // Turn off LED D3
|
28 | C1RX0CONbits.RXFUL = 0; // Clear the Buffer RXFUL to receive new messages
|
29 | C1INTFbits.RX0IF = 0; //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt
|
30 | }
|
31 | IFS1bits.C1IF = 0; //Clear interrupt flag
|
32 | }
|
board b soll einfach bei einer einkommenden nachricht antworten mit den
daten 0x01 an den empfänger 0x01.
wenn ich auf einen Taster drücke, wird ein timer gestartet, welcher dann
in regelmäßigen abständen von board a eine nachricht an board b schickt.
(nur solange Rx_Flag = 0x0E ist, bedeutet 3 nachrichten wurden von board
b an board a als antwort gesendet.)
Das Problem ist, dass beim empfangen irgendetwas schief geht. Eigentlihc
sende ich mit Board b durch C1TX0B1=0x01 die daten 0x01.
Wenn ich beim Board a nach einer einkommenden NAchricht C1RX0B1 abfrage,
bekomme ich aber als daten C1RX0B1=0xD201. Dadurch werden die Flags
nicht mehr gesetzt und eine erneute Abfrage findet nicht mehr statt.
ist in der konfiguration etwas falsch? oder in der abfrage? weil meiner
meinung nach müsste es funktionieren. ich weiss auch nicht, warum mir
andere daten (C1RX0B1) angezeigt werden.
ein weiteres Problem ist, dass selbst, wenn ich anstelle von
schreiben würde, springt er nicht in diese bedingung herein.
wäre nett, wenn einer mal über meinen code gucken könnte um einen
eventuellen Fehler zu finden.
Johannes