Forum: Compiler & IDEs Problem mit Sprungadressen und Timer


von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Ich möchte einen Attiny24 mit folgendem Programm versehen:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#ifndef F_CPU
5
#define F_CPU 1000000UL
6
#endif
7
#ifndef TIMER0_OVF_vect
8
#define TIMER0_OVF_vect TIMER0_OVF0_vect
9
#endif
10
11
#include <util/delay.h>
12
int main(void)
13
14
{
15
 struct
16
 {
17
 unsigned eingangspin1:1; //Speicher Richtung1
18
 unsigned eingangspin2:1; //Speicher Richtung2
19
 unsigned schaltpin1:1;   //Richtungsumschalter
20
 
21
 }x;
22
23
 DDRA = 0b00011;
24
 PORTA = 0b11100;
25
 TCCR0 |= (1<<CS02)&(1<<CS00); //Timer mit 1/1024 der Taktfrequenz
26
 TIMSK |= (1<<TOIE0);
27
 sei ();
28
 while (0)
29
 {
30
  if (PINA&(1<<PINA2))
31
 {
32
  x.eingangspin1=1;      //Richtung 1 Einfahrt 
33
  }
34
  if (PINA&(1<<PINA3))
35
 {
36
  x.eingangspin1=0;      //Richtung 1 Ausfahrt
37
 }
38
  if (PINA&(1<<PINA4))
39
 {
40
  x.eingangspin2=1;      //Richtung 2 Einfahrt
41
 }
42
  if (PINA&(1<<PINA5))
43
 {
44
  x.eingangspin2=1;      //Richtung 2 Ausfahrt
45
 }
46
  
47
                          //Sprungadresse   
48
 }
49
 return (0);
50
 ISR (TIMER0_OVF_vect)
51
 {
52
53
 }
54
 if (0<<x.eingangspin1&(1<<x.schaltpin1))
55
  {
56
  PORTA = (1<<PORTA0)&(0<<PORTA1);
57
  x.schaltpin1=0;
58
  }
59
  if (0<<x.eingangspin2&(0<<x.schaltpin1))
60
  {
61
  PORTA = (0<<PORTA0)&(1<<PORTA1);
62
  x.schaltpin1=1;
63
  }
64
65
  
66
 
67
68
}
Meine Probleme mit diesem Programm:
1)Scheint mit der Timer noch nicht definiert zu sein. Stimmt das?
Der Compiler zeigt bei fast allen Befehlen, die mit dem Timer 
zusammnenhängen, Fehler an.
2)Ich suche schon vergebens nach den Befehlen für Sprünge im Programm. 
Sowohl die Forensuche als auch das Tutorial fördern nichts brauchbares 
zu Tage.
Hoffe auf Hilfe.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

> Der Compiler zeigt bei fast allen Befehlen, die mit dem Timer
> zusammnenhängen, Fehler an.

Fehler z.B. dass du die ISR innerhalb von main() definierst?
Und Warnungen, dass der Code nach return (0); nie erreicht werden kann?

von Helfer (Gast)


Lesenswert?

Sprünge im Programm vermeidet man.

Einerseits weil der Anfänger sich mit Sprüngen der Lächerlichkeit preis 
gibt und andererseits weil es in 99.9% der Fälle eine sprunglose 
Variante gibt.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
erstmal Danke für die Antworten.
Wie macht man es denn besser?
Ich habe noch nie Interrupts benutzt, deshalb weiß ich auch nicht wie es 
geht. Ich habe das zum großteil aus dem Tutorial.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

Im Tutorial stehen aber keine so vergurkten Beispiele, oder?

Es hapert an der elementaren Schreibweise eines C-Programms:
# Funktionsdefinition innerhalb einer Funktion...
# Code nach einem return auf oberster Funktionsebene...

Die C Syntax musste du einigermaßen beherrschen, bevor es an komplexere 
Funktion des Programmes wie Interrupts geht.

von Helfer (Gast)


Lesenswert?

Noch'n Tip:

Bevor du loscodest, schreib dir in normaler Sprache auf, was du machen 
willst. Welche Eingaben hast du, welche Ausgaben soll es geben und wie 
wirken die Eingaben auf die Ausgaben.

Und wenn du fit bist, setzt du diese umgangssprachliche Beschreibung in 
eine Statemachine um. In diesem Artikel siehst du auf den ersten 
beiden Seiten, wie Karl-Heinz das Problem "Ampelsteuerung" ohne C-Code 
beschrieben hat. Wenn du so in deinen Projekten vorgehst, wird es auf 
die Dauer einfacher, als das bisherige loscoden und nach Hilfe suchen.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ein Softwarekonzept existiert bereits, da ich dieses Programm erst 
geschrieben habe, nachdem ich mich mit meinen Partnern über die späteren 
Aufgaben unterhalten habe.
>Code nach einem return auf oberster Funktionsebene
denn Code habe ich da hingeschrieben, weil ich Sprungadressen benutzen 
wollte. Davon hast du mir gerade abgeraren, d.h. ich muss das erstmal 
änderen.
> Funktionsdefinition innerhalb einer Funktion
Wie macht man es denn richtig?
Muss ich ein extra void benutzen?
Gruß Jannis

von Stefan E. (sternst)


Lesenswert?

Da hapert es an allen Ecken und Kanten, auch an den grundlegendsten
1
if (0<<x.eingangspin1&(1<<x.schaltpin1))
Ich vermute, dass du folgendes realisieren wolltest:
1
Wenn eingangspin1 Null ist und schaltpin1 Eins ist, dann ...
Die Codezeile macht das noch nicht mal ansatzweise. Du hast 
offensichtlich einfach nur wild geraten.

Du kannst C aber nicht einfach durch Raten, Rumprobieren und Kopieren 
anderer Sourcen lernen. Du solltest dir ein C-Buch beschaffen, und das 
mal richtig von Anfang an durcharbeiten (notfalls auch ein 
Online-Tutorial (*)). Sämtliche Fragen hier hätten sich damit dann schon 
mal erledigt. Danach kannst du dich dann daran machen, ein konkretes 
Programm für deinen AVR zu schreiben, und hier Fragen zu konkreten 
Details zu stellen. Ich weiß, dass das eine extrem unbeliebte Antwort 
ist, aber es ist das einzig Sinnvolle in so einem Fall.

(*): Damit meine ich aber nicht das Tutorial hier, denn das ist für 
Leute gedacht, die bereits C können.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
das C-Buch ist bereits bestellt, aber leider noch nicht da.
Da in meinen vorrangegangenden Fragen immer auf das hiesige Tutorial 
verwiesen wurde, habe ich nur das zu Rate gezogen.
Was schreibt man den an Stelle von if 
(0<<x.eingangspin1&(1<<x.schaltpin1))?
Gruß Jannis

von Stefan E. (sternst)


Lesenswert?

Jannis C. schrieb:
>>Code nach einem return auf oberster Funktionsebene
> denn Code habe ich da hingeschrieben, weil ich Sprungadressen benutzen
> wollte. Davon hast du mir gerade abgeraren, d.h. ich muss das erstmal
> änderen.
>> Funktionsdefinition innerhalb einer Funktion
> Wie macht man es denn richtig?
> Muss ich ein extra void benutzen?

Auch das sind alles grundlegende Dinge, die sich komplett erledigen 
würden, würdest du mal C richtig von Anfang an lernen, statt wild drauf 
los zu probieren.

von Stefan E. (sternst)


Lesenswert?

> Was schreibt man den an Stelle von if
> (0<<x.eingangspin1&(1<<x.schaltpin1))?

Was würde es dir nützen, wenn ich da jetzt die korrekte Zeile 
hinschreiben würde? Du wärst dann trotzdem noch nicht in der Lage, den 
Rest des Programms selber zu schreiben (ich habe diese eine Zeile ja nur 
als Beispiel raus gefischt). Es würde darauf hinauslaufen, dass quasi 
das komplette Programm von uns (dem Forum) geschrieben würde, und das 
ist nicht Sinn der Sache.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
>Es würde darauf hinauslaufen, dass quasi
das komplette Programm von uns (dem Forum) geschrieben würde, und das
ist nicht Sinn der Sache.
Stimmt, dafür ist ein Forum nicht da. Hast du denn einen Vorschlag für 
ein gutes C-Tutorial, welches du ansprachst?
Ein Anhaltspunkt oder die Richtung der Fehler wären auch eine Lösung.
Nebenbei möchte ich auch nicht jedesmal, wenn ich ein Programm schreibe, 
mit jeder Kleinigkeit hier aufschlagen müssen.
Gruß JAnnis

von Stefan E. (sternst)


Lesenswert?

> Stimmt, dafür ist ein Forum nicht da. Hast du denn einen Vorschlag für
> ein gutes C-Tutorial, welches du ansprachst?

Ich kann keines konkret (aus eigener Erfahrung) empfehlen.
Hier ist eines, das ich so auf die Schnelle gefunden habe:
http://www.c-howto.de/tutorial-einfuehrung.html

> Ein Anhaltspunkt oder die Richtung der Fehler wären auch eine Lösung.

Ein großer Teil der Fehler hat mit AVRs im Speziellen nichts zu tun, 
sondern sind einfach nur mangelnde C-Grundkenntnisse.
Wie bereits gesagt, stelle dein AVR-Programm erst mal zurück, und 
konzentriere dich auf das C-Lernen. Danach sieht die Sache dann schon 
gleich ganz anders aus.

von Oliver (Gast)


Lesenswert?

Jannis C. schrieb:
> Ich habe das zum großteil aus dem Tutorial.

Jannis C. schrieb:
> Was schreibt man den an Stelle von if
> (0<<x.eingangspin1&(1<<x.schaltpin1))?

Anscheinend du hast das falsche Tutorial. Wenn du das C-Buch durch hast, 
geht es hier weiter:

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Oliver

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ist es richtig für die Abfrage von Variablen
 if ( Variable1 & (1<<Variable2)) zu schreiben, oder habe ich da das 
Tutorial missverstanden?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Hallo,
> ist es richtig für die Abfrage von Variablen

nicht Variablen

>  if ( Variable1 & (1<<Variable2)) zu schreiben, oder habe ich da das
> Tutorial missverstanden?

diese Schreibweise benutzt man wenn man wissen will, ob das Bit 
'Variable2' in Variable1 gesetzt ist oder nicht.

Willst du wissen ob am PINA das Bit PA2 gesetzt ist (weil da zb ein 
Taster drann hängt), dann schreibst du

   if( PINA & ( 1 << PA2 ) )
     mach was

von Jannis C. (kabelwurm)


Lesenswert?

Danke,
wieder was gelernt, habe jetzt ein Beispielprogramm zu der Abfrage von 
Variablen gefunden und da verwenden die ((Variable1>1)&(Variable2>1)).
Ist das besser?
Gruß Jannis

von Justus S. (jussa)


Lesenswert?

Jannis C. schrieb:
> Ist das besser?

als was?

von Helfer (Gast)


Lesenswert?

> ((Variable1>1)&(Variable2>1))

Falls das von dir richtig abgeschrieben wurde, ist es ein Gefummel im 
Originalprogramm.

Logische Bedingungen verknüpft man mit einem logischen Operator. Wenn 
ein logisches UND gewollt ist, dann ist && der entsprechende Operator.

... Variable1 größer 1 UND Variable2 größer 1 ...

Jemand der an dieser Stelle ein bitweises UND & als Operator benutzt, 
sollte einen guten Grund dafür haben. Sorry, einen guten Grund sehe ich 
an obiger Stelle nicht. Und damit sieht die Stelle nach "da weiss jemand 
nicht was er macht" (oder Schreibfehler) aus und entsprechend 
vorbelastet würde ich an den Rest des Codes oder des Tutorials ran 
gehen.

von Stefan E. (sternst)


Lesenswert?

Jannis C. schrieb:
> ((Variable1>1)&(Variable2>1))

Das ist für deinen Fall immer noch totaler Unsinn.
Du bist immer noch nur am Raten und Rumprobieren.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Ich habe mein Buch, welches sich speziel auf die AVRs bezieht nach einem 
Ähnlichen Fall wie bei mir durchsucht und rausgekommen sind halt die 
oben genannten Zeilen. Jetzt habe ich das C-Tutorial, welches schon 
genannt wurde, konsulidiert. 
http://www.c-howto.de/tutorial-verzweigungen-if-else.html. Ich denke, 
was da über die Verwendung von Variablen steht, past auch zu meinem 
Fall?
Gruß Jannis

von Serieller (Gast)


Lesenswert?

Du bist auf dem richtigen Weg, wenn du das C-Howto-Tutorial oder ein 
anderes durch arbeitest.

Behalte aber im Hinterkopf, dass

1. die Sachen dort C auf einem PC erklären. Es wird später bei C auf dem 
AVR Unterschiede und Feinheiten geben. Da setzt das AVR-GCC-Tutorial 
dann an.

2. das C-Howto-Tutorial hat auch Fehler (z.B. bei der Erklärung 
Deklaration und Definition von Variablen). Vergleiche mehrere Tutorials 
oder Bücher zu einem Thema oder frage bei Unklarheiten nach.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich habe das Programm noch mal nach Syntaxfehlern überarbeitet und die 
eine Lösung für mein Sprungadressenproblem gefunden.
Jetzt habe ich ein Problem mit dem Timer.
Ohne den Befehl TIMSK kann ich es vollständig compillieren, mit wirft er 
mit Error um sich.
Mein Code:#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#ifndef TIMER0_OVF_vect
#define TIMER0_OVF_vect TIMER0_OVF0_vect
#endif
struct
 {
 unsigned eingangspin1:1; //Speicher Richtung1
 unsigned eingangspin2:1; //Speicher Richtung2
 unsigned interuptbit:1;  //Wenn die Weiche schalten soll
 unsigned schaltpin1:1;   //Richtungsumschalter
  }x;
ISR (TIMER0_OVF_vect)
{
 x.interuptbit=1;
}
int main(void)

{

 DDRA = 0b00011;
 PORTA = 0b11100;
 TCCR0 |= (1<<CS02)&(1<<CS00); //Timer mit 1/1024 der Taktfrequenz
 TIMSK |= (1<<TOIE0);// Overflow Interrupt erlauben
  sei();// Global Interrupts aktivieren


 while (0)
 {
  if (PINA&(1<<PINA2))
 {
  x.eingangspin1=1;      //Richtung 1 Einfahrt
  }
  if (PINA&(1<<PINA3))
 {
  x.eingangspin1=0;      //Richtung 1 Ausfahrt
 }
  if (PINA&(1<<PINA4))
 {
  x.eingangspin2=1;      //Richtung 2 Einfahrt
 }
  if (PINA&(1<<PINA5))
 {
  x.eingangspin2=1;      //Richtung 2 Ausfahrt
 }
  if (1<<x.interuptbit)
  {
   if ((x.eingangspin1==0)&&(x.schaltpin1==1))
   {
   PORTA = (1<<PORTA0)&(0<<PORTA1);            //Richtung1Stellung
   x.schaltpin1=0;
   }
   if ((x.eingangspin1==0)&&(x.schaltpin1==0))
   {
   PORTA = (0<<PORTA0)&(1<<PORTA1);             //Richtung2Stellung
   x.schaltpin1=1;
   }
   x.interuptbit=0;

 }
 return (1);





}



}

von Serieller (Gast)


Lesenswert?

Tja.

> while (0)
> {
>   was hier ausgeführt werden soll wird NIE ausgeführt
> }

Der AVR-GCC ist wahrscheinlich so schlau den kompletten Anweisungsblock 
des while rückstandsfrei zu entsorgen.

> Ohne den Befehl TIMSK kann ich es vollständig compillieren, mit wirft er
> mit Error um sich.

Bei manchen AVR heisst dieses Timer-Mask-Register anders. Beim 
Attiny24 gibt es z.B. ein TIMSK0, ein TIMSK1 und ein TIMSK2, je nach 
dem ob du Timer0, Timer1 oder Timer2 beeinflussen willst.

TCCR0 ist der nächste Kandidat. Das gibt es beim Attiny24 so nicht. 
Dort gibt es mehr Einstellmöglichkeiten und dafür braucht es zwei 
Register TCCR0A und TCCR0B.

Steht aber alles im Datenblatt.

von Serieller (Gast)


Lesenswert?

> Steht aber alles im Datenblatt.

Selber reingefallen. Timer2 gibt es nicht, daher auch kein TIMSK2.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich habe versucht das Programm mit dem Datenblatt zu Korrigieren.
ich hoffe es ist jetzt korrekt. Ich habe auch die while-Schleife 
korriegiert.
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#ifndef F_CPU
5
#define F_CPU 1000000UL
6
#endif
7
#ifndef TIMER0_OVF_vect
8
#define TIMER0_OVF_vect TIMER0_OVF0_vect
9
#endif
10
struct
11
 {
12
 unsigned eingangspin1:1; //Speicher Richtung1
13
 unsigned eingangspin2:1; //Speicher Richtung2
14
 unsigned interuptbit:1;  //Wenn die Weiche schalten soll
15
 unsigned schaltpin1:1;   //Richtungsumschalter
16
  }x;
17
ISR (TIMER0_OVF_vect)
18
{
19
 x.interuptbit=1;
20
}
21
int main(void)
22
23
{
24
25
 DDRA = 0b00011;
26
 PORTA = 0b11100;
27
 TCCR0A |=(0<<COM0A1)&(0<<COM0A2);
28
 TCCR0B |= (1<<CS02)&(1<<CS00); //Timer mit 1/1024 der Taktfrequenz
29
 TIMSK |= (1<<TOIE0);// Overflow Interrupt erlauben
30
  sei();// Global Interrupts aktivieren
31
32
33
 while (1)
34
 {
35
  if (PINA&(1<<PINA2))
36
 {
37
  x.eingangspin1=1;      //Richtung 1 Einfahrt
38
  }
39
  if (PINA&(1<<PINA3))
40
 {
41
  x.eingangspin1=0;      //Richtung 1 Ausfahrt
42
 }
43
  if (PINA&(1<<PINA4))
44
 {
45
  x.eingangspin2=1;      //Richtung 2 Einfahrt
46
 }
47
  if (PINA&(1<<PINA5))
48
 {
49
  x.eingangspin2=1;      //Richtung 2 Ausfahrt
50
 }
51
  if (1<<x.interuptbit)
52
  {
53
   if ((x.eingangspin1==0)&&(x.schaltpin1==1))
54
   {
55
   PORTA = (1<<PORTA0)&(0<<PORTA1);            //Richtung1Stellung
56
   x.schaltpin1=0;
57
   }
58
   if ((x.eingangspin1==0)&&(x.schaltpin1==0))
59
   {
60
   PORTA = (0<<PORTA0)&(1<<PORTA1);             //Richtung2Stellung
61
   x.schaltpin1=1;
62
   }
63
   x.interuptbit=0;
64
65
 }
66
 return (0);
67
68
69
70
71
72
}
73
74
75
76
}
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
>TIMSK
selber übersehen.
Heißt natürlich
TIMSK0.
>TCCR0A |=(0<<COM0A1)&(0<<COM0A2);
Diese Zeile ist falsch. Ich bin aber auch ein Depp.
Der Compiller spuckt immernoch eine Warnug bezüglich der 
Interuptdeklaration aus. Muss ich da noch was ändern?
Gruß Jannis

von Serieller (Gast)


Lesenswert?

Welche Warnung?

> PORTA = (1<<PORTA0)&(0<<PORTA1); //Richtung1Stellung
> PORTA = (0<<PORTA0)&(1<<PORTA1); //Richtung2Stellung

Beeinflussen auch die internen Pullups. Das solltest du nicht machen!

> PORTA = 0b11100;

Da fehlt ein Pullup.

>  if (PINA&(1<<PINA2))
>  if (PINA&(1<<PINA3))

Diese Programmlogik gibt PINA3 einen Vorrang vor PINA2. Ist das 
beabsichtigt?

>  if (PINA&(1<<PINA2))
>  if (PINA&(1<<PINA3))

Diese Programmlogik verhindert, dass x.eingangspin1 einen neuen 
definierten Wert bekommt, wenn beide if-Bedingungen nich zutreffen. Darf 
der alte Wert von x.eingangspin1 dann weiter benutzen?

>  if (1<<x.interuptbit)

Ist immer wahr, selbst wenn x.interuptbit == 0 ist: 1<<0 == 1 und 1<<1 
== 2. Beides ist ungleich 0. C-Tutorial lesen.

>  if ((x.eingangspin1==0)&&(x.schaltpin1==1))
>  if ((x.eingangspin1==0)&&(x.schaltpin1==0))

Programmlogik ist nicht durchdacht.

>>> Bevor du loscodest, schreib dir in normaler Sprache auf, was du machen
>>> willst. Welche Eingaben hast du, welche Ausgaben soll es geben und wie
>>> wirken die Eingaben auf die Ausgaben.

von Serieller (Gast)


Lesenswert?

Die Anmerkungen zu Pinpaar A2/A3 gelten auch für das andere Pinpaar.

von Karl H. (kbuchegg)


Lesenswert?

1
   PORTA = (1<<PORTA0)&(0<<PORTA1);            //Richtung1Stellung

Ich weiss zwar nicht was du dir davon versprichst und ich kann es auch 
nicht erraten, weil dein Programm extrem konfus ist. Aber das macht mit 
Sicherheit nicht das, was du denkst das es machen sollte. Was auch immer 
das sein mag.

Kleiner Tip:
Wenn du umgangssprachlich bei dir denkst:

 Och, jetzt mach ich das UND dann mach ich noch das

dann bedeutet das in den seltensten Fällen, dass in einem formalen 
Ablauf wie zb in einem Programm, ein UND auftaucht. Das ist einfach nur 
eine Abfolge von Ereignissen und dieses umganssprachliche UND ist 
lediglich ein Füllwort ohne weitere Bedeutung.

Du willst:
   den Pin PA0 auf 1 setzen UND du willst den Pin PA1 auf 0 setzen.

UNd genau hier haben wir so einen Fall, wo dieses UND keine weitere 
Bedeutung hat und auf keinen Fall irgendetwas mit einem logischen oder 
binären UND zu tun hat. Dieses UND kennzeichnet einfach nur, dass eine 
Aktion abgeschlossen ist und dass eine neue Aktion anfängt.

Welche Aktionen sind das.
Da ist zum ersten die Aktion:           Pin PA0 auf 1 setzen
UNd zum zweiten ist die andere Aktion:  Pin PA1 auf 0 setzen

Und dafür setzt du jetzt die kanonischen Lösungen ein. Einen Pin auf 1 
setzen macht man mit

    port |= ( 1 << Pin )

und einen Pin auf 0 setzen macht man mit

    port &= ~( 1 << Pin )

Diese Dinge sind wie Phrasen in einer Umgangsprache und können meistens 
auch so verwendet werden. Wenn du bei dir denkst: Ach, wäre das jetzt 
schön, wenn ich den Pin auf 1 setzen würde, dann bedeutet das in C 
Schreibweise

    port |= ( 1 << Pin )

Das muss wie ein Automatismus sein: Du denkst 'Pin auf 1 setzen' und 
deine Finger schreiben die C-Form dieses Gedankens.

Sinngemäss natürlich für Pin auf 0 setzen genauso

Angewendet auf dein Beispiel bedeutet das, das nicht das hier
1
   PORTA = (1<<PORTA0)&(0<<PORTA1);            //Richtung1Stellung

richtig sein kann, sondern das hier
1
   PORTA |=  (1 << PORTA0);
2
   PORTA &= ~(1 << PORTA1);

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
die Warnung:
../SchleifeMEC.c:17: warning: 'TIMER0_OVF0_vect' appears to be a 
misspelled signal handler
Wieso beienflusst das die Pull-Ups? Das ist mit irgendwie nicht ganz 
klar.
Den fehlenden habe ich schon ergänzt. Danke.
Der Vorzug ist nicht relevant.
Danke für den Hinweis, die Eingangspins müssen aber immer neu abgefragt 
werden, sonst bringt das Programm nicht das, was es soll. Nach erneutem 
Nachdenken musste aber der Code geändert werden:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#ifndef F_CPU
5
#define F_CPU 1000000UL
6
#endif
7
#ifndef TIMER0_OVF_vect
8
#define TIMER0_OVF_vect TIMER0_OVF0_vect
9
#endif 
10
struct
11
 {
12
 unsigned eingangspin1:2; //Speicher Richtung1
13
 unsigned eingangspin2:2; //Speicher Richtung2
14
 unsigned interuptbit:2;  //Wenn die Weiche schalten soll
15
 unsigned schaltpin1:2;   //Richtungsumschalter
16
  }x;
17
ISR (TIMER0_OVF_vect)
18
{
19
 x.interuptbit=1;
20
}
21
int main(void)
22
23
{
24
25
 DDRA = 0b000011;
26
 PORTA = 0b111100;
27
 TCCR0B |= (1<<CS02)&(1<<CS00); //Timer mit 1/1024 der Taktfrequenz
28
 TIMSK0 |= (1<<TOIE0);// Overflow Interrupt erlauben 
29
  sei();// Global Interrupts aktivieren
30
31
 
32
 while (1)
33
 {
34
  if (PINA&(1<<PINA2))
35
 {
36
  x.eingangspin1=x.eingangspin1+1;      //Richtung 1 Einfahrt 
37
  }
38
  if (PINA&(1<<PINA3))
39
 {
40
  x.eingangspin1=x.eingangspin1-1;      //Richtung 1 Ausfahrt
41
 }
42
  if (PINA&(1<<PINA4))
43
 {
44
  x.eingangspin2=x.eingangspin2+1;      //Richtung 2 Einfahrt
45
 }
46
  if (PINA&(1<<PINA5))
47
 {
48
  x.eingangspin2=x.eingangspin2-1;      //Richtung 2 Ausfahrt
49
 }
50
  if (1==x.interuptbit)
51
  { 
52
   if ((x.eingangspin1==0)&&(x.schaltpin1==1))
53
   {
54
   PORTA = (1<<PORTA0)&(0<<PORTA1);            //Richtung1Stellung
55
   x.schaltpin1=0;
56
   }
57
   if ((x.eingangspin1==0)&&(x.schaltpin1==0))
58
   {
59
   PORTA = (0<<PORTA0)&(1<<PORTA1);             //Richtung2Stellung
60
   x.schaltpin1=1;
61
   }
62
   x.interuptbit=0;
63
                         
64
 }
65
 return (0);
66
 
67
 
68
69
 
70
  
71
}
72
  
73
 
74
75
}
>>>  if (1<<x.interuptbit)
Nóchmal danke für den Hinweis, das habe ich vergessen zu Ändern.
Sonst glaube, das es jetzt so funktioniert, wie ich es geplant hatte.
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:

> ../SchleifeMEC.c:17: warning: 'TIMER0_OVF0_vect' appears to be a
> misspelled signal handler

Schmeiss endlich das vermaledeite #define raus
1
#ifndef TIMER0_OVF_vect
2
#define TIMER0_OVF_vect TIMER0_OVF0_vect
3
#endif

> Wieso beienflusst das die Pull-Ups? Das ist mit irgendwie nicht ganz
> klar.

Weil du an den ganzen Port eine Zuweisung machst! Jedes einzelne Bit wir 
dneu beschrieben. Unter anderem auch die Bits PA2 bis PA5. Sie werden 
auf 0 gesetzt. Und damit sind dann die Pullup Widerstände an diesen Pins 
abgeschaltet.

> Den fehlenden habe ich schon ergänzt. Danke.
> Der Vorzug ist nicht relevant.
> Danke für den Hinweis, die Eingangspins müssen aber immer neu abgefragt
> werden, sonst bringt das Programm nicht das, was es soll.

Das tut es offenbar auch jetzt nicht

> Nach erneutem
> Nachdenken musste aber der Code geändert werden:

Genau:
Schmeiss das Programm weg und schreib ein neues. Aber diesmal vorher 
anfangen zu überlegen und vor allen Dingen nicht künsteln. Deine 
Bitflags kannst du dir alle in die Haare schmieren, braucht kein Mensch.

Und nenn die Dinge nicht .....pin
Deine Variablen haben eine logische Bedeutung! Das sind Bezeichnungen, 
die du als Variablenname benutzen kannst.

So wie ich das sehe, brauchst du auch keinen Timer. Der erfüllt keinen 
vernünftigen Zweck.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Sorry mein vorheriger Beitrag kamm leider bevor ich eure gelesen habe.
@Karl-Heinz:
 Kannst du Gedanken lesen?
Du hast recht, so habe ich gedacht.
Ist aber schon korriegiert.
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Okay,
bevor ich jetzt ein neues Programm schreibe, noch eine Frage:
Wie verhindere ich, dass ich die Pull-Ups beienflusse?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Okay,
> bevor ich jetzt ein neues Programm schreibe, noch eine Frage:
> Wie verhindere ich, dass ich die Pull-Ups beienflusse?
> Gruß Jannis

indem du um während des Programmlaufs um solche Dinge
1
   PORTA = ... was auch immer ...;

(also Zuweisungen an den kompletten Port) einen grossen Bogen machst, 
und immer mittels
1
   PORTA |=  (1 << PORTA0);
2
   PORTA &= ~(1 << PORTA1);

immer nur das eine Bit ansprichst, das du auf 0 oder 1 setzen willst.
Es ist wirklich ganz einfach. Durch die letzte Form ist gewährleistet, 
dass die anderen Bits an diesem Port nicht verändert werden.

von Karl H. (kbuchegg)


Lesenswert?

Was soll es denn eigentlich werden?

Deine Kommentare erinnern mich irgendwie an eine Art Ampelsteuerung in 
einer Parkhaus Ein/Ausfahrt.
Allerdings: So wird das höchst wahrscheinlich nichts.
Aber ehe ich da jetzt weiter spekuliere, warte ich mal auf die 
Projektbeschreibung.

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Okay,
> bevor ich jetzt ein neues Programm schreibe,

Erst über das Problem nachdenken!

Dann einen Ablaufplan auf Papier malen.
Dann diesen Plan mit dem Finger durchspielen und nachsehen ober 
funktioniert. Dabei beachten: Dein µC arbeitet rasend schnell. Deine 
Hauptschleife wird in ein paar µs einmal, in einer Sekunde also viele 
tausend mal abgearbeitet. Daraus folgt: Aus Sicht des µC sind externe 
Ereignisse selten und seeeeeehr langsam.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Und vor allem sollten die Einrückungen auch der entsprechenden 
Schachtelungstiefe entsprechen. Selbst wenn der Code aus dem obigen 
Listung einigermaßen korrekt wäre, würde er nach einem 
Schleifendurchlauf ins Nirvana springen. Mit sehr viel Glück (oder eher 
Pech...) würde die Programmausführung dann irgendwann wieder von vorne 
beginnen.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
also Projektbeschreibung:
Es handelt sich um eine Wendeschleife für das Carsystem, die Einspurig 
in beide Richtung befahrbahr sein soll. Am Anfang befindet sich eine 
Weiche die später mal mit Hilfe des Timers umgeschaltet werden soll. 
Dies darf aber nur passieren, wenn die Schleife leer ist. Ich muss in 
jede Richtung also Ein-und Ausfahrt kontrollieren mit jeweils einer 
Variablen. Wenn der Interupt jetzt eintritt, muss geschaut werden, ob 
die Schleife leer ist und wenn ja, dann schaltet er um.
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich habe jetzt ein neues Programm geschrieben, welches dem ersten doch 
recht änlich sieht, weil es das gleiche tun soll, was es aber vielleicht 
noch nicht tut.
Ich habe mich jetzt um volgende Dinge gekümmert:
1)Ich habe versucht es korreckt Einzurücken.
2)Ich bin von meinem Bitfeld abgerückt und habe jetzt richtige 
Variablen.
3)Die Variablen haben jetzt praktische Namen, die sich auf die 
Verwendung beziehn.
Ersteinmal der neue Code, zu dem ich noch eine Frage habe:
Ist die while-Schleife okay oder muss ich die noch modifizieren?
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#ifndef F_CPU
5
#define F_CPU 1000000UL
6
#endif
7
#include <util/delay.h>
8
uint8_t richtung1;
9
uint8_t richtung2;
10
uint8_t umschalter;
11
uint8_t interupt;
12
13
ISR (TIMER0_OVF_vect)
14
{
15
 interupt=1;
16
}
17
int main(void)
18
19
{
20
21
 DDRA = 0b000011;
22
 PORTA = 0b111100;
23
 TCCR0B |= (1<<CS02)&(1<<CS00); //Timer mit 1/1024 der Taktfrequenz
24
 TIMSK0 |= (1<<TOIE0);// Overflow Interrupt erlauben 
25
  sei();// Global Interrupts aktivieren
26
27
 
28
while (1)
29
 {
30
   if (PINA&(1<<PINA2))
31
    {
32
      richtung1=richtung1+1;  //Richtung 1 Einfahrt 
33
    _delay_ms(100);
34
     }
35
   if (PINA&(1<<PINA3))
36
    {
37
      richtung1=richtung1-1;   //Richtung 1 Ausfahrt
38
    _delay_ms(100);  
39
     }
40
   if (PINA&(1<<PINA4))
41
    {
42
      richtung2=richtung2+1;   //Richtung 2 Einfahrt
43
    _delay_ms(100);
44
     }
45
   if (PINA&(1<<PINA5))
46
    {
47
      richtung2=richtung2-1; //Richtung 2 Ausfahrt
48
    _delay_ms(100);
49
     }
50
   if (1==interupt)
51
    { 
52
      if ((richtung1==0)&&(umschalter==0));
53
      {
54
      PORTA |= (1<<PORTA0);
55
      PORTA &= ~(0<<PORTA1); 
56
      umschalter=1;               //Richtung1Stellung
57
      }
58
      if ((richtung2==0)&&(umschalter==1))
59
      {
60
      PORTA &= ~(0<<PORTA0);
61
      PORTA |= (1<<PORTA1);             //Richtung2Stellung
62
      umschalter=0;
63
   
64
      }
65
    interupt=0;
66
                         
67
    }
68
 return 0;
69
 
70
 
71
72
 
73
  
74
}
75
  
76
 
77
78
}
Gruß Jannis

von Helfer (Gast)


Lesenswert?

Die while-Schleife ist immer noch Mist, weil ein return 0; darin steht. 
Sie wird daher nur einmal ausgeführt, dann nie mehr.

Deine Beschreibung in 
Beitrag "Re: Problem mit Sprungadressen und Timer" geht in die richtige 
Richtung, aber eine Skizze wäre besser. In der Beschreibung fehlen alle 
Angaben wo die Sensoren (Eingaben) sitzen. Ohne diese Angaben kann die 
Programmlogik nicht kontrolliert werden.

Das Programm kann man lesbarer schreiben (s. unten). Korrigiert wurden 
die ### markierten Stellen. Die gewünschte Funktion der Umschaltung habe 
ich mir aus der Beschreibung zusammengereimt und abgeändert.
1
/*
2
 * Controller für Wendeschleife 
3
 * Attiny24 @ 1 Mhz
4
 */
5
#include <avr/io.h>
6
#include <stdint.h>
7
#include <avr/interrupt.h>
8
9
#ifndef F_CPU
10
#define F_CPU 1000000UL
11
#endif
12
#include <util/delay.h>
13
14
#define PRELLZEIT_MS 0 /* 100 */
15
#define BESETZT   1
16
#define FREI      0
17
#define RICHTUNG1 1
18
#define RICHTUNG2 0
19
20
uint8_t richtung1;
21
uint8_t richtung2;
22
uint8_t umschalter;
23
volatile uint8_t interupt; // ###
24
25
ISR(TIMER0_OVF_vect)
26
{
27
  interupt = 1;
28
}
29
30
void entprellen(void) 
31
{
32
  // Diese Zeit geht von der Reaktionszeit 
33
  // auf den Timer0 Interrupt ab! Nicht zu
34
  // lange einstellen!
35
#if PRELLZEIT_MS
36
  _delay_ms(PRELLZEIT_MS); 
37
#endif
38
}
39
40
int main(void)
41
{
42
  // PA5 ... PA2: interne Pullups ein
43
  PORTA = 0b00111100;
44
45
  // Grundstellung Wendeschleife
46
  PORTA |=  (1<<PORTA0);
47
  PORTA &= ~(1<<PORTA1);
48
  richtung1 = FREI; 
49
  richtung2 = FREI; 
50
  umschalter = RICHTUNG1;
51
52
  // PA1 ... PA0: Ausgang Wendeschleife
53
  // PA5 ... PA2: Eingang Sensoren
54
  DDRA  = 0b00000011;
55
56
  // Timer0 einstellen
57
  // t = 1/(1000000/256/1024) = ~262 ms
58
  TCCR0A = 0;                      // Normal Port Operation
59
  TCCR0B |= (1<<CS02) | (1<<CS00); // 1/1024 der Taktfrequenz ###
60
  TIMSK0 |= (1<<TOIE0);            // Overflow Interrupt erlauben 
61
  sei();                           // Global Interrupts aktivieren
62
 
63
  while (1) {
64
    // Ständig überwachen, ob Wendeschelife besetzt ist
65
    // Sensor Richtung 1 Einfahrt überfahren?
66
    if ( (PINA & (1<<PINA2)) ) {
67
      richtung1 = BESETZT;
68
      entprellen();
69
    }
70
    // Sensor Richtung 1 Ausfahrt überfahren?
71
    if ( (PINA & (1<<PINA3)) ) {
72
      richtung1 = FREI; 
73
      entprellen();
74
    }
75
    // Sensor Richtung 2 Einfahrt überfahren?
76
    if ( (PINA & (1<<PINA4)) ) {
77
      richtung2 = BESETZT; 
78
      entprellen();
79
    }
80
    // Sensor Richtung 2 Ausfahrt überfahren?
81
    if ( (PINA & (1<<PINA5)) ) {
82
      richtung2 = FREI; 
83
      entprellen();
84
    }
85
86
    // Regelmäßig und häufig (beim Timer0-Interrupt alle ~262 ms) 
87
    // versuchen die Wendeschleife umzuschalten. 
88
    if ( 1 == interupt ) {
89
      // Wendeschleife frei?
90
      if ( (richtung1 == FREI) && (richtung2 == FREI) ) {
91
        // ja, dann Richtung umschalten
92
        if ( (umschalter == RICHTUNG2) ) {
93
          PORTA |=  (1<<PORTA0);
94
          PORTA &= ~(1<<PORTA1); // ###
95
          umschalter = RICHTUNG1;
96
        } else {
97
          PORTA &= ~(1<<PORTA0); // ###
98
          PORTA |=  (1<<PORTA1);
99
          umschalter = RICHTUNG2;
100
        }
101
      }
102
      interupt = 0;
103
    }
104
  }
105
  return 0;
106
}

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
das Programm ist ja der Hammer. DANKE.
Ich habe aber noch zwei Verarständnisproblem:
1)Brauche ich bei einem Interupt immer volantine, wenn ich im Interupt 
eine Variable ändere?
2)Können sich jetzt auch mehere Autos in eine Richtung in der Schleife 
befinden?
Sonst ist das für mich ein klasse Anschauungsprogrammm. Nicht nur für 
den Stil.
Und wenn ich jetzt für den Timer ein externes Signal nehme, kann ich da 
einen Quarz verwenden? Ich muss dann natürlich noch TCCR0B ändern.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

1) Nein, nicht für alle. Aber für die gemeinsam mit dem 
Nicht-Interrupt-Teil benutzen Variablen. Ist im Artikel Interrupt 
erklärt.

2) Weiss ich nicht. Ich habe nur nebulöse Vorstellungen was ein 
Carsystem und eine Wendeschleife sein konnte. Deine Beschreibung ist für 
einen Laien auf diesem Gebiet wie mich zu dünn. Du hast jetzt das 
Problem, vor dem ich auch stand: Du versuchst aus dem Programmcode die 
Hardwaresituation zu ermitteln. Du merkst anscheinend wie schwer das 
ist.

3) In AVR-Tutorial: Equipment ist erklärt, wie du den AVR takten 
kannst. Ein externer Quarz kann Sinn machen, wenn du später mal eine 
rel. genaue Zeitnahme machen willst oder Datenübertragung zum PC planst. 
Im Moment ist ein Quarz nicht nötig.

von Jannis C. (kabelwurm)


Angehängte Dateien:

Lesenswert?

Hallo,
ich meinte,dass ich den Timer extern Takte.
Nun noch mal zu der Schleife.
Ich hänge mal eine Skizze an.
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Hallo,
> ich meinte,dass ich den Timer extern Takte.

Wozu soll das gut sein?

Um Entprellung kommst du sowieso nicht herum.
ALso kannst du auch in Software zählen wieviele Autos in der Schleife 
sind. (Nach einem Stromausfall stimmt die Zahl sowieso nicht mehr)

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich wollte den Timer nur deutlich langsamer haben, damit er nur alle 2 
min schaltet.
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich habe versucht, die Methode von Helfer, auf ein neues Programm zu 
übertragen. Ich wollte mal wissen, ob ich das mit den Abstufungen und 
den Deklarationen jetzt richtig verstanden habe. Der schon fertige Teil 
des Codes:
1
/*ParkplatzMEC
2
 *@Atmega8 mit 8MHZ
3
 */
4
#include <avr/io.h>
5
#include <stdint.h>
6
#include <avr/interrupt.h>
7
8
#ifndef F_CPU
9
#define F_CPU 8000000UL
10
#endif
11
#include <util/delay.h>
12
13
#define Prellzeit_MS 0
14
#define Parkplatz1 1
15
#define Parkplatz2 2
16
#define Parkplatz3 3
17
#define Parkplatz4 4
18
#define Frei 0
19
#define Besetzt 1    
20
21
uint8_t Einfahrt1;
22
uint8_t Einfahrt2;
23
uint8_t Einfahrt3;
24
uint8_t Einfahrt4;
25
uint8_t Ausfahrt;
26
volatile uint8_t Ausfahrttimer;
27
volatile uint8_t Busrunde;
28
29
ISR(TIMER0_OVF_vect)
30
{
31
}
32
ISR(EXT_INT0_vect)
33
{
34
 Busrunde=1;
35
}
36
ISR(EXT_INT1_vect)
37
{
38
}
39
int entprellen(void)
40
{
41
 _delay_ms(100);
42
43
 #if Prellzeit_MS
44
     _delay_ms(Prellzeit_MS);
45
 #endif
46
}
47
int busfahrt (void)
48
{
49
50
}
51
int main (void)
52
{
53
 ;
54
 DDRB = 0b0;
55
 DDRC = 0b0;
56
 DDRD = 0b0;
57
 PORTB = 0b0;
58
 PORTC = 0b0;
59
 PORTD = 0b0;
60
 MCUCR |= (1<<ISC10);
61
 MCUCR |= (1<<ISC00);
62
 GICR |= (1<<INT0);
63
 GICR |= (1<<INT1);
64
 sei();
65
 /*Grundstellung
66
 */
67
68
 while (1)
69
 {
70
 if (Busrunde==1){
71
 } 
72
  
73
 }
74
 return 0;
75
}
Ich habe noch nicht alle Teile vollständig ausgefüllt. Zum Beispiel den 
Timerl
Gruß Jannis

von Helfer (Gast)


Lesenswert?

Tut mir leid. Ich bin schwer von Begriff. Deine Skizze verstehe ich 
immer noch nicht. Die Richtung 1 und 2 sowie die Zuordnung der vier 
Sensoren ist mir immer noch ein Rätsel. Ich will auch nicht weiter mit 
"Zeig mal", "Mach doch" nerven und ziehe mich deshalb aus diesem Thread 
zurück. Einem Pferd, dass 46 Runden gelaufen ist, sollte man das 
Gnadenbrot gönnen.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
also
@Helfer: Meinen Skizze ist absoluter Mist. Ich werde eine neue machen, 
die man auch verstehen kann. Ich habe die meinen Partnern gezeigt, die 
wusten, worum es geht und die haben es auch nicht verstanden. Und 
desweiteren nervst du mich überhaupt nicht, ich freue mich immer über 
Intresse an meinen Projekten. Und wenn ich bedenke wie ich euch hier mit 
meinem Raten genervt habe, bin ich euch sehr dankbar, dass das hier 
überhaupt noch jemand liest.
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Hallo,
> also
> @Helfer: Meinen Skizze ist absoluter Mist. Ich werde eine neue machen,
> die man auch verstehen kann.

Beschreib auch den Ablauf, was passieren soll.
Aus Sicht eines Autos und aus Sicht der Wechselschleife

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
mach ich sofort, wenn ich wieder die Zeit habe.
Im Momment habe ich etwas Streß wegen ein paar Arbeiten.
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
mal eine Frage offtopic:
Was rechnet der Prozessor wenn ich inkremintieren (also ++x) ?
Wo liegt der Unterschied zwischen ++x und +x ?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Hallo,
> mal eine Frage offtopic:

Nicht wirklich.
Deine Frage zeigt ganz klar, dass du ganz dringend ein C-Buch brauchst 
und das auch durcharbeiten musst.

> Was rechnet der Prozessor wenn ich inkremintieren (also ++x) ?

inkrementieren bedeuet: 1 dazuzählen

In C gibt es 2 Formen:

++x  und x++

  i sei gleich 5

* j = ++x
       j erhält den inkrementierten Wert von i und i wird inkrementiert

       j ist dann gleich 6
       i ist dann gleich 6

* j = x++
      j erhält den Wert von i und i wird inkrementiert

      j ist dann gleich 5
      i ist dann gleich 6


> Wo liegt der Unterschied zwischen ++x und +x ?

+x ist kein Inkrement und hat auch nichts damit zu tun. das + an dieser 
Stelle ist einfach nur ein Vorzeichen, so wie auch - einfach nur ein 
Vorzeichen ist und -x den negativen Wert von x angibt. Nur dass sich bei 
einem + ganz einfach nichts tut und x sich nicht verändert.

-x  kann man als mathematisch kürzere Schreibweise für  (0-x) auffassen.
In diesem Sinne kann man +x auch als kürzere Schreibweise für (0+x) 
auffassen und da 0 plus irgendeine Zahl wieder die Zahl ergibt, ändert 
sich da nichts am Ergebnis.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo, damit ist meine Frage bestens beantwortet.
Ich fahre am Freitag in die Stadt, da wird auch Zeit für einen Buchladen 
sein. :)
Gruß Jannis

von Guru (Gast)


Lesenswert?

In der Zwischenzeit: http://openbook.galileocomputing.de/c_von_a_bis_z/

Ich selbst mag zwar den Kernighan Ritchie lieber aber selbst die ANSI 
Version ist inzwischen ein wenig angestaubt. 
http://www.amazon.de/Programmieren-C-ANSI-2-C-Reference/dp/3446154973

von Jannis C. (kabelwurm)


Lesenswert?


von Jannis C. (kabelwurm)


Angehängte Dateien:

Lesenswert?

Hallo,
ich hoffe meine neue Skizze ist übersichlicher.
Situationsbeschreibung:
Aus sicht des µC:
Wenn ein Auto in Richtung 1 in die Schleife fährtund den Kontakt 
überfährt wird die Richtung auf besetzt geschaltet. Wenn es die Schleife 
wieder verläst und über den Kontakt fährt wird diese wieder auf Frei 
gesetzt. Das gleiche gilt auch für die andere Richtung.
Wenn nun der Timer überläuft, wird überprüft ob die Schleife Frei ist 
und wenn ja dann schaltet er die Weiche um.
Ich hoffe das erfüllt eure Wünsche. :)
Gruß Jannis

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.