also mein programm soll quasi folgendes machen:
ich habe zwei systeme die sich gegenseitig synchronisieren (bzw. ihren
status vergleichen und bei differenz mit fehlermeldung abschalten). grob
gesehen machen beide programme nicht anders als einen zähler
hochzuzählen (0-255) und dann den wert an 8 an portb angeschlossenen
LEDs auszugeben.
somit habe ich portB mittels
als ausgang geschaltet. anschließend senden sie sich gegenseitig den
aktuellen status (über usart).. die routine für die synchronisation seht
ihr unten.
warum ändert sich dann der wert an portb? in der ISR, welche ja eine
fehlerroutine aufruft, wird an portb nichts verändert..
isr:
1 | SIGNAL(TIMER0_COMP_vect)
|
2 | {
|
3 | TCCR0A &= ~((1<<CS00)&(1<<CS02));
|
4 | ausfError();
|
5 | }
|
fehlerroutine:
1 | void ausfError(){
|
2 | wdt_disable(); // Watchdog deaktivieren
|
3 |
|
4 | while(1){
|
5 | // Fehlercode an PortD ausgeben. Fehlercode laut Tabelle
|
6 | PORTD = 0xFF;
|
7 | _delay_loop_2(65535);
|
8 | _delay_loop_2(65535);
|
9 | _delay_loop_2(65535);
|
10 | _delay_loop_2(65535);
|
11 | PORTD = 0x00;
|
12 | _delay_loop_2(65535);
|
13 | _delay_loop_2(65535);
|
14 | _delay_loop_2(65535);
|
15 | _delay_loop_2(65535);
|
16 | }
|
17 | }
|
das "do anything" sieht so aus:
1 | // Schleife zur überprüfung ob Synchronisation stattgefunden hat
|
2 | while(!iSyncDone){
|
3 | if(isCharAvailable() == 1){ // Wenn Data empfangen..
|
4 | string[count++] = receiveChar(); // prüfen ob Länge des Strings der erwarteten Länge entspricht
|
5 | if(count > 1){ // Falls nicht, Fehler melden
|
6 | stdError();
|
7 | }
|
8 | else{ // sonst Status vergleichen
|
9 | if(string[0] != cStatus){
|
10 | syncError();
|
11 | }
|
12 | string[0] = '\0';
|
13 | iSyncDone = 1;
|
14 | }
|
15 | }
|
16 | }
|
wenn ich statt dem counter vor der schleife einfach ein delay von <5ms
anbringe, dann läuft das programm wunderbar durch.
komplettabschnitt des codes:
1 | void doSync(){
|
2 | // Hilfsvariablen initialisieren
|
3 | char string[64];
|
4 | unsigned char count = 0;
|
5 | int iSyncDone = 0;
|
6 |
|
7 | // aktuellen Status senden
|
8 | if(cStatus <= iMaxStat)
|
9 | sendChar(cStatus);
|
10 | else
|
11 | stdError();
|
12 |
|
13 | // Wartezeit, falls nicht im Debug-Mode
|
14 | //if(!iDebug)
|
15 | //_delay_loop_2(10000);
|
16 |
|
17 | // Watchdog zurück setzen um keinen Alarm beim Warten auf Statusantwort zu schlagen
|
18 | wdt_reset();
|
19 |
|
20 | // Timer für die Synchronisation starten
|
21 | TCNT0 = 0; // Setzt den aktuellen Zählerstand auf 0
|
22 | OCR0A = iDelayMs; // Setzt den errechneten ms-Wert ins Compare-Register
|
23 | TCCR0A &= ~((1<<WGM00)&(1<<COM0A1)&(1<<COM0A0)&(1<<CS01));
|
24 | TCCR0A = (1<<CS00)|(1<<CS02)|(1<<WGM01);
|
25 |
|
26 | // Schleife zur überprüfung ob Synchronisation stattgefunden hat
|
27 | while(!iSyncDone){
|
28 | if(isCharAvailable() == 1){ // Wenn Data empfangen..
|
29 | string[count++] = receiveChar(); // prüfen ob Länge des Strings der erwarteten Länge entspricht
|
30 | if(count > 1){ // Falls nicht, Fehler melden
|
31 | stdError();
|
32 | }
|
33 | else{ // sonst Status vergleichen
|
34 | if(string[0] != cStatus){
|
35 | syncError();
|
36 | }
|
37 | string[0] = '\0';
|
38 | iSyncDone = 1;
|
39 | }
|
40 | }
|
41 | }
|
42 |
|
43 | TCCR0A &= ~((1<<CS00)&(1<<CS02));
|
44 | }
|
ebenso habe ich bei benutzung des counters ein synchronitätsproblem. ein
system meldet, dass das system einen falschen status bekommen hat,
worauf das andere sich dann korrekt mit "anderes system reagiert nicht"
verabschiedet. allerdings kommt das synchronitätsproblem NICHT zustande,
wenn ich den counter weg lasse, dafür aber ein delay von <5ms vor der
schleife einbaue.