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.
Die übliche Lösung heißt RTS-CTS Handshake. Die größeren PICs können das auch in Hardware machen. fchk
Ich sende in solchen Fällen nach jedem Byte ein ACK. Der PC wartet auf ACK bevor er das nächste byte sendet.
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.
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?
Bei einer Baudrate von 19200 ist nicht der PIC das Problem, sondern Deine Programmierung und das Abspeichern der Daten in einem Puffer! TK
>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.
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 | }
|
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 | }
|
Du könntest die Daten in der ISR nur im RAM speichern und dann in der main verarbeiten, wenn du Zeit hast.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.