Forum: Mikrocontroller und Digitale Elektronik pc<-RS232->Pic datenfluss kontrollieren


von Christoph H. (obbedair)


Lesenswert?

hallo,
ein Pc sendet 12Byte zu einem Pic. Diese 12Byte sind ein Frame für den 
CanBus.
mein Problem: derPc sendet schneller als der Pic den kram verarbeiten 
kann. jetzt stellt sich für mich die frage wie ich das am besten in den 
griff bekomme. handshake? oder jedes empfangene byte zurückschicken, 
quasi als kontrolle und als zeichen das wieder geschickt werden kann???
was ist in diesem Fall die eleganteste Lösung???

Ps: es sind eigentlich nur 6Byte aber ich wollte jedes Byte noch einmal 
aufteilen und die ersten 4 Bit quasi zur numerierung nutzen.

von Frank K. (fchk)


Lesenswert?

Die übliche Lösung heißt RTS-CTS Handshake. Die größeren PICs können das 
auch in Hardware machen.

fchk

von Max H. (hartl192)


Lesenswert?

Ich sende in solchen Fällen nach jedem Byte ein ACK. Der PC wartet auf 
ACK bevor er das nächste byte sendet.

von A+B=B+A (Gast)


Lesenswert?

Christoph Herzog schrieb:
> hallo,
> ein Pc sendet 12Byte zu einem Pic. Diese 12Byte sind ein Frame für den
> CanBus.

Welche Baudrate?


> mein Problem: derPc sendet schneller als der Pic den kram verarbeiten
> kann. jetzt stellt sich für mich die frage wie ich das am besten in den
> griff bekomme. handshake?

Braucht min 1 Leitung mehr

> oder jedes empfangene byte zurückschicken,

löst das Problem nicht

> quasi als kontrolle und als zeichen das wieder geschickt werden kann???
> was ist in diesem Fall die eleganteste Lösung???

Wenn der Pic einen UART hat (also kein Soft-Uart genutzt wird):

Jedes Byte einzeln senden und warten bis es zurück gesendet wird.

Dann das nächste.

Die Uart Hardware ist autonom und meldet wenn das Byte da ist.

Kannst auch Xon/Xoff Software handshake nehmen, das ist ein Standard.

>
> Ps: es sind eigentlich nur 6Byte aber ich wollte jedes Byte noch einmal
> aufteilen und die ersten 4 Bit quasi zur numerierung nutzen.

Das ist die Applikationsebene, hat mit sicherem senden/empfangen nichts 
zu tun.

von Christoph H. (obbedair)


Lesenswert?

Baudrate bestimmt der PC... momentan 19200.
ich benutze einen PIC18F2480, dieser scheint kein Hardware-Handshake zu 
haben...
bedeutet ich muss doch einfach ein pin vom pic über den RS232-Treiber an 
den Stecker zum RS232 Kabel löten und kann dann bei Dateneingang sofort 
erstmal sagen "pic busy" und wenn fertig verarbeitet wurde dann "pic 
ready?

von TK (Gast)


Lesenswert?

Bei einer Baudrate von 19200 ist nicht der PIC das Problem, sondern 
Deine Programmierung und das Abspeichern der Daten in einem Puffer!

TK

von spontan (Gast)


Lesenswert?

>ich benutze einen PIC18F2480, dieser scheint kein Hardware-Handshake zu
>haben...

Was heißt scheint? Datenblatt gelesen? Handshake geht auch aus der 
Software raus.

Aber wie TK schon schrieb, bei der Baudrate langweilt sich ein PIC18. 
Alle Probleme sind in der Sofwtare zu suchen.

Zeig die doch mal.

von Christoph H. (obbedair)


Lesenswert?

spontan schrieb:
>>ich benutze einen PIC18F2480, dieser scheint kein Hardware-Handshake zu
>>haben...
>
> Was heißt scheint? Datenblatt gelesen? Handshake geht auch aus der
> Software raus.

Datenblatt hab ich gelesen und nichts zum Handshake gefunden.

zum Code, ich denke das alles direkt im Interrupt zu verarbeiten ist 
eine sehr unglückliche Variante... mir ist aber noch nichts besseres 
eingefallen

1
void interrupt ISR ()
2
    {
3
    INTCONbits.GIE = 0; 
4
        if (PIR1bits.RCIF == 1)         // USART
5
        {
6
            Data = RCREG;    // Auslesesn des USART-Puffers
7
            Data_A = Data & 0xF0;       // Adress_Teil für                 
8
            Data_D = Data & 0x0F;       // Daten_Teil
9
            if (Data_A == 0x10)
10
            {
11
                SIDH = Data;            // obere 4 Bit des Standart-ID-High
12
                SIDH = SIDH << 4;
13
            }
14
            else if (Data_A == 0x20)      
15
            {
16
                SIDH = Data_D | SIDH ; // untere 4 Bit des StandartID-HIGH
17
            }
18
            else if (Data == 0x30)
19
            {
20
                SIDL = Data_D;     // obere 4 Bit des Standart-ID-LOW
21
                SIDL = SIDL << 4;
22
            }
23
            else if (Data == 0x40 )
24
            {
25
                SIDL = Data_D | SIDL;
26
            }
27
            else
28
            {
29
                Fehler = 1;             // LED für Fehlererkennung 
30
            }
31
            PIR1bits.RCIF = 0;          // Puffer-full-bit wieder löschen!
32
        }
33
34
        if (PIR3bits.IRXIF == 1);       // CAN BUS ERROR
35
        {
36
            PIR3bits.IRXIF = 0;
37
            Fehler = !Fehler;
38
        }
39
 
40
        if (PIR3bits.ERRIF == 1)            // CAN Module Error
41
        {
42
            PIR3bits.ERRIF = 0;
43
        }
44
45
46
        if (PIR3bits.RXB0IF == 1)           // CANBUS
47
        {
48
            PIR3bits.RXB0IF = 0;
49
            Gelb = 1;
50
            Message_received = 1;
51
        }
52
53
        INTCONbits.GIE = 1;
54
}

: Bearbeitet durch User
von Christoph H. (obbedair)


Lesenswert?

Also... der Code sieht jetzt wie folgt aus... das ganze funktioniert 
auch bis einschließlich Case 7. Case 8 wird dann nicht mehr 
bearbeitet... kann das daran liegen weil ich alles im Interrupt mache 
und eh er dann bis Case 8 durchgefragt hat ist schon wieder das nächste 
Byte da und er verschluckt sich?
1
void interrupt ISR ()
2
    {
3
    INTCONbits.GIE = 0; 
4
        if (PIR1bits.RCIF == 1)         // USART
5
        {
6
            Data = RCREG;    // Auslesesn des USART-Puffers
7
            Data_A = Data & 0xF0;       //Adressteil der Nachricht
8
            Data_D = Data & 0x0F;       //Datenteil der Nachricht
9
            Data_A = Data_A >> 4;
10
            
11
            switch (Data_A)
12
            {
13
                case 1:
14
                    SIDH = Data;         // obere 4 Bit des StandartID-High
15
                    SIDH = SIDH << 4;
16
                    
17
                    break;
18
                case 2:
19
                    SIDH = Data_D | SIDH;// untere 4Bit des StandartID-HIGH
20
                    
21
                    break;
22
                case 3:
23
                    SIDL = Data_D;     // obere 4 Bit des Standart-ID-LOW
24
                    SIDL = SIDL << 4;
25
                    break;
26
                case 4:
27
                    SIDL = Data_D | SIDL;
28
                    break;
29
                case 5:
30
                    Data0 = Data_D;
31
                    Data0 = Data0 << 4;
32
                    break;
33
                case 6:
34
                    Data0 = Data_D | Data0;
35
                    break;
36
                case 7:
37
                    Data1 = Data_D;
38
                    Data1 = Data1 << 4;
39
                    break;
40
                case 8:
41
                    Data1 = Data_D | Data1;
42
                    Gelb = 1;
43
                    break;
44
                case 9:
45
                    Data2 = Data_D;
46
                    Data2 = Data2 << 4;
47
                    
48
                    break;
49
                case 10:
50
                    Data2 = Data_D | Data2;
51
                    break;
52
                case 11:
53
                    Data3 = Data_D;
54
                    Data3 = Data3 << 4;
55
                    break;
56
                case 12:
57
                    Data3 = Data_D | Data3;
58
                    Senden = 1;
59
                    break;
60
            }
61
            PIR1bits.RCIF = 0;          // Puffer-full-bit wieder löschen!
62
        }
63
64
        if (PIR3bits.IRXIF == 1);       // CAN BUS ERROR
65
        {
66
            PIR3bits.IRXIF = 0;
67
            Fehler = !Fehler;
68
            
69
        }
70
 
71
    if (PIR3bits.ERRIF == 1)            // CAN Module Error
72
        {
73
        PIR3bits.ERRIF = 0;
74
        }
75
76
77
    if (PIR3bits.RXB0IF == 1)           // CANBUS
78
        {
79
        PIR3bits.RXB0IF = 0;
80
        Gelb = 1;
81
        Message_received = 1;
82
        }
83
84
    INTCONbits.GIE = 1;
85
    }

von Max H. (hartl192)


Lesenswert?

Du könntest die Daten in der ISR nur im RAM speichern und dann in der 
main verarbeiten, wenn du Zeit hast.

von Christoph H. (obbedair)


Lesenswert?

ich werd es mal versuchen, Problem ist das momentan noch kein 
CAN-Bus-"Verkerh" ist... das wird später immer mehr...
aber in wie weit das den pic wirklich auslastet weiß ich noch nicht. 
Vielleicht ist es vorerst mit einer Fehlererkennung getan.
quasi wenn beim verarbeiten in der main ein fehler auftritt dann melde 
mir das und ich werde das nochmal genauer unter die Lupe nehmen.

: Bearbeitet durch User
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.