Hallo,
nachdem ich das Prinzip aus meinem ersten Beitrag begriffen habe, wollte
ich die Schaltung erweitern.
Ziel:
Taste 1 an PORTA Bit 0 gedrückt LED soll leuchten, auch wenn danach die
Taste losgelassen wird.
Taste 2 an PORTA Bit 1 gedrückt LED soll wieder ausgehen.
Im Prinzip ist das ein Flip-Flop.
Was geht, was geht nicht:
Sofort nach dem Flashen geht die LED an. Wird die Taste 2 gedrückt geht
sie aus, aber nur solange die Taste 2 gedrückt wird, dann geht sie
wieder an.
Mein Code:
1
#include<avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 1000000UL // Takt CPU wird gesetzt
5
#endif
6
7
#include<util/delay.h>
8
9
uint8_tl1=0;
10
uint8_tl2=0;
11
12
intmain(void)
13
{
14
DDRA=0xff;// Port A, alles auf Ausgang
15
DDRA&=~((1<<DDA0)|(1<<DDA1));// bis auf die Tastereingaenge
16
PORTA=0xff;// Port A alle Pullups an
17
18
19
while(1){
20
21
_delay_ms(0.5);// Verzögerung
22
23
if(PINA&(1<<PINA0)){
24
l1=1;
25
l2=0;
26
}
27
if(PINA&(1<<PINA1)){
28
l2=1;
29
l1=0;
30
}
31
32
if(l1==1){
33
PORTA|=(1<<PA3);// LED an
34
l2=0;
35
}
36
if(l2==1){
37
l1=0;
38
PORTA&=~(1<<PA3);// LED aus
39
}
40
41
42
}
43
}
Wo stehe ich denn da wieder auf dem Schlauch?
Ich habe keine else-Zweige verwendet, weil ich von meinem Verständnis
her keine Notwendigkeit sah.
Dietmar P. schrieb:> Wo stehe ich denn da wieder auf dem Schlauch?
Du hast dir mit deinen "vielen" Variablen selbst den Blick aufs
Wesentliche verstellt.
Hinweis:
Ein Portpin behält seinen Status so lange, bis er geändert wird.
Du brauchst keine einzige zusätzliche Variable.
Die Hauptschleife besteht aus 4 Zeilen
Alternativ:
Gib deinen Variablen 'vernünftige' Namen und nicht ll1, ll2, i1, i2, x,
y und was man sonst noch so alles sieht.
Bei
if (l1==1){
muss man nachdenken, nachschauen, was da die Bedeutung ist.
Bei
if( ledErrorOn == TRUE )
braucht man nicht raten. Da steht schon im Code, was an dieser Stelle
warum passieren soll. Man verwirrt sich dann viel weniger leicht selber.
ZU deinem aktuellen Programm
> Taste 1 an PORTA Bit 0 gedrückt
Wenn eine Taste gedrückt ist, wie ist dann der Zustand des
entsprechenden Port-Bits? Ist der 1 oder 0?
Wie sind deine LED angeschlossen?
Muss man eine 1 oder eine 0 an den Ausgang schreiben um die LED
einzuschalten?
Hallo Karl Heinz,
wieder einmal danke für die Unterstützung. Programmiert habe ich schon
in anderen Sprachen, aber C hat es in sich.
Zu den Frage:
Taster schließen auf 0.
LED leuchtet bei 0.
Habe ich so gemacht, weil meistens die Ausgänge des µC bei 0 etwas tun.
Gruß
Dietmar
Dietmar P. schrieb:> Hallo Karl Heinz,>> wieder einmal danke für die Unterstützung. Programmiert habe ich schon> in anderen Sprachen, aber C hat es in sich.>> Zu den Frage:>> Taster schließen auf 0.> LED leuchtet bei 0.>> Habe ich so gemacht, weil meistens die Ausgänge des µC bei 0 etwas tun.
Ja ist ok.
Muss man nur wissen.
Wenn dein Taster aber bei Betätigung auf 0 schließt, was kann dann an
1
if(PINA&(1<<PINA0)){
2
machwaswennderTasterbetätigtwurde
nicht stimmen?
( In C ist jeder Ausdruck ungleich 0 auch gleichzeitig ein Ausdruck, der
als logisch wahr gilt. Mit dem & setzt du alle Bits ausser PINA0 gezielt
auf 0. Also bleibt nur noch das Bit PINA0 übrig. Ist es 0, dann ist auch
der ganze Ausdruck und hat damit den Wahrheitswert Falsch. Ist das Bit
auf 1, dann belibt etws übrig, was nicht 0 ist und damit den
Wahaheitswert Wahr hat.)
Nachtrag:
Mein Code verkürzt:
if (PINA & (1 << PINA0)){
PORTA |= ( 1 << PA3 ); // LED an
}
if (PINA & (1 << PINA1)){
PORTA &= ~( 1 << PA3 ); // LED aus
}
Erhalte aber das gleiche Ergebnis.
Wenn dein Taster aber bei Betätigung auf 0 schließt, was kann dann an
1
if(PINA&(1<<PINA0)){
2
machwaswennderTasterbetätigtwurde
nicht stimmen?
In C ist jeder Ausdruck auch gleichzeitig ein Ausdruck, der als
logischer Wahrheitswert fungieren kann. 0 ist dabei der Wahrheitswert
falsch, alles ungleich 0 ist der Wahrheitswert wahr. Mit dem & setzt du
alle Bits ausser PINA0 gezielt auf 0. Also bleibt nur noch das Bit PINA0
übrig. Ist es 0, dann ist auch der ganze Ausdruck 0 und hat damit den
Wahrheitswert Falsch. Ist das Bit auf 1, dann belibt etwas übrig, was
nicht 0 ist und damit den Wahrheitswert Wahr hat.
Dein Taster ist im Grundzustand nicht gedrückt, daher hat das Bit an
PINA0 den Wert 1, und damit ist
PINA & (1 << PINA0)
logisch wahr, wenn die Taste NICHT gedrückt ist.
Karl heinz Buchegger schrieb:> Dein Taster ist im Grundzustand nicht gedrückt, daher hat das Bit an> PINA0 den Wert 1, und damit ist>> PINA & (1 << PINA0)>> logisch wahr, wenn die Taste NICHT gedrückt ist.
Und damit sollte dein Programm so aussehen
1
#ifndef F_CPU
2
#define F_CPU 1000000UL // Takt CPU wird gesetzt
3
#endif
4
5
#include<avr/io.h>
6
#include<util/delay.h>
7
8
intmain(void)
9
{
10
DDRA=0xff;// Port A, alles auf Ausgang
11
DDRA&=~((1<<DDA0)|(1<<DDA1));// bis auf die Tastereingaenge
Hallo Karl Heinz,
super, danke.
Deine Lösung ist so gut verständlich.
Gruß
Dietmar
Nachtrag:
Könnte es sein, dass in der letzten Zeile nach &= die Tilde ~ fehlt?
Dietmar P. schrieb:> Hallo Karl Heinz,>> super, danke.>> Deine Lösung ist so gut verständlich.>> Gruß> Dietmar>> Nachtrag:>> Könnte es sein, dass in der letzten Zeile nach &= die Tilde ~ fehlt?
Gut aufgepasst.
Ich seh schon, du erkennst die stehenden C-Phrasen zum Bit setzen und
löschen selbst dann, wenn ich Fehler mache :-)
Ja, aber noch mit einiger Unsicherheit.
Es ist toll, dass es solch ein Forum gibt. Ohne das Forum hätte ich wohl
schon längst aufgegeben.
Ich werde mich mit Sicherheit während meines Projektes "Alarmanlage"
noch melden.
Bereits erledigt:
Hard- + Software für Anzeige Status von Leitungen über Mux/Demux auf
einem Tableau mit LED's.
In Arbeit:
- Leitungsauswertung für Alarm.
- Verwendung LCD-Display für Leitungsstatus.
Da kommt noch das Thema Tabellenverarbeitung auf mich zu.
Gruß
Dietmar
Karl heinz Buchegger schrieb:> Ich seh schon, du erkennst die stehenden C-Phrasen zum Bit setzen und> löschen selbst dann, wenn ich Fehler mache :-)
Karl heinz du machst keine Fehler, du willst nur testen ob er aufpasst.
Gruss Helmi
Hallo Karl Heinz,
ja, gerne.
Angefangen habe ich mal mit etwas Assembler auf dem Großrechner, ist
aber nur noch wenig vorhanden, dann sehr viel beruflich COBOL mit
Datenbanken.
Auf dem PC war / ist das Basic und APL. APL gibt es offenbar nicht mehr,
wurde von IBM getrieben. APL ist eine Programmiersprache, die eigentlich
nur aus Zeichen aus der Mathematik besteht, ist unheimlich
leistungsfähig für
Tabellenverarbeitung und sehr schnell, aber der Einstieg ist wohl ebenso
mühsam, wie jetzt für mich in C.
Mit Tools für rel. Datenbaken wie dBase bzw. heute Open-Office Base
beschäftige ich mich auch.
Eigentlich wollte ich mit Bascom für die µC's anfangen, habe aber hier
im Forum den Eindruck gewonnen, dass C besser sei.
Nun ja und nun quäle ich mich halt in C wegen der µC, ist kpl. Neuland
für mich.
Dietmar P. schrieb:> Assembler auf dem Großrechner, COBOL, APL
Oh. APL kenn ich noch. Hab ich auf der Uni gehabt :-)
Warum ich frage:
Der Hintergedanke ist, dass man dir eventuell weiterhelfen kann, wenn
man auf dir bereits Bekanntes zurückgreift. Aber da ist nichts dabei,
was man brauchen könnte. Deine bekannten Sprachen sind ziemlich weit von
C entfernt, und mein COBOL ist schon sehr rostig :-)
> Nun ja und nun quäle ich mich halt in C wegen der µC, ist kpl. Neuland> für mich.
Mein Tip:
Hol dir einen Kernighan&Ritchie und arbeite den (zumindest die erste
Hälfte) auf dem PC durch. Du hast deutlich mehr davon, wenn du die
Grundlagen systematisch durchgehst. Und auf dem PC lernt es sich
leichter, weil du eine bessere Entwicklungsumgebung hast. So Dinge wie
'Ausgabe auf die Konsole' funktionieren dort ganz einfach und damit hast
du ein mächtiges Werkzeug um dir zb Zwischenergebnisse oder
'strategische Ausgaben zu Debugzwecken' zu machen. Ganz abgesehen davon,
dass du einen viel besseren Debugger hast.
Erst dann, wenn du mit Arrays, Strings, Strukturen, Pointern, nicht mehr
auf Kriegsfuss stehst, macht es Sinn die spezifischen Dingen zur
µC-Programmierung dazuzunehmen und vom PC auf einen AVR zu wechseln. Du
betreibst sonst einen Mehrfrontenkrieg, der unnötig mühsam ist.
Und ja: Kauf dir Literatur! C ist voll kleiner Fallen die sich einem mit
der Methode 'Try&Error' nicht erschliessen.
Ja, ich denke das wird der richtige Weg sein.
Hab schon mal gegoogelt wegen Kernighan&Ritchie, werde es mir besorgen.
Wenn man das empfehlen kann, ist es ok. Hatte mir schon Bücher
angesehen, aber da war nichts dabei was mich wirklich angesprochen hat.
Mit "Try & Error" habe ich doch schon viele Stunden zu gebracht.
Hallo zusammen,
hat jemand von euch die überarbeite Version des Programms mal
ausprobiert?
Hat diese bei euch funktioniert.
Bei mir funktioniert da leider gar nichts, ich kann aber einen Fehler an
der Hardware ausschließen, da ich diese bereits für für andere Programme
verwendet habe.
Bei dieser überarbeiteten Version habe ich nur die Eingangs- und
Ausgangspins nach meinen Anforderungen verändert.
Leider geht die LED weder an noch aus.
Kann mir vielleicht jemand sagen, woran das liegt?
Vielen Dank schon mal im Vorraus.
Achja ich besitze einen ATTiny 84V.
Jakob K. schrieb:> Bei dieser überarbeiteten Version habe ich nur die Eingangs- und> Ausgangspins nach meinen Anforderungen verändert.
Wie sieht dein Programm aus?
Wie sieht deine Schaltung aus?
> Leider geht die LED weder an noch aus.
Hört sich banal an, aber hast du schon mal versucht, die LED ohne Taster
einzuschalten?
Hallo,
wie schon gesagt habe die LED schon für andere Schaltungen verwendet
Ich kann Sie sogar schon blinken lassen, das hat einwandfrei
funktioniert
Und die Schalterpins habe ich auch durchgemessen bei geöffneten wie
geschlossenem Schalter, die Spannungen passen soweit.
Ich werd mal schnell nen Schaltplan zeichnen und hier hochladen, gib mir
ca. 20 min
// Aktivieren der internen Pull-Ups für die Eingänge
10
PORTA=(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5);
11
12
13
14
while(1)
15
{// Endlosschleife
16
if((PINA&(1<<PINA2)==0))
17
PORTA|=(1<<PA0);
18
19
20
if((PINA&(1<<PINA3)==0))
21
PORTA&=~(1<<PA0);
22
23
}
24
return0;
25
}
Der Schaltplan zeigt meine komplette Schaltung.
Diesen benötige ich noch nachdem dieses Programm läuft.
Der Max 232 und die Kondis hierfür habe ich noch nicht verbaut
Die LED ist über den Jumper deaktivierbar
Hallo,
vielen Dank für die schnelle Antwort,
Programm funktioniert jetzt soweit. :-)
Es waren wirklich die falsch gesetzten Klammern! :-(
Ich habe noch eine Frage, wie kann kann ich die LED nur so lang leuchten
lassen, wie der Schalter gedrückt ist?
Vielen Dank für dieses Forum, ohne dieses hätte ich vermutl. schon
längst aufgegeben
Jakob
Jakob K. schrieb:> Ich habe noch eine Frage, wie kann kann ich die LED nur so lang leuchten> lassen, wie der Schalter gedrückt ist?
Indem du innerhalb der SChleife immer wieder das machst
für immer {
wenn Taster gedrückt
dann LED an
else
LED aus
}
genau genommen stimmt es nicht ganz, dass die LED nur so lange leuchtet,
wie die Taste gedrückt ist, aber auf die paar µs kommt es nicht an.
Jakob K. schrieb:> Es waren wirklich die falsch gesetzten Klammern! :-(
Die Hausaufgabe für dich: Warum ist das so?
(Dein Stichwort lautet: Operator Precedence Table bzw. auf Deutsch:
Vorrangregeln der Operatoren)
Jakob K. schrieb:> Ich habe noch eine Frage, wie kann kann ich die LED nur so lang leuchten> lassen, wie der Schalter gedrückt ist?
Dazu braucht man dann folgendes riesen Programm: