Forum: Mikrocontroller und Digitale Elektronik CAN informationen sind falsch


von Johannes (Gast)


Lesenswert?

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
1
if(data==0x01){
2
...
1
if(data==data){
2
...
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

von Lutz (Gast)


Lesenswert?

Da ich gerade gegessen habe (und es auch drin bleiben soll), habe ich 
den Code jetzt nicht durchgeschaut.

Ganz spontan:
Johannes schrieb:
> ein weiteres Problem ist, dass selbst, wenn ich anstelle
> vonif(data==0x01){
> ...
> if(data==data){
> ...
> schreiben würde, springt er nicht in diese bedingung herein.

if (C1INTFbits.RX0IF)
kommt ja noch darüber. Ist diese Bedingung erfüllt; also springt er dort 
überhaupt rein? Wenn nicht, kann er data==data gar nicht testen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.