Guten Tag.
Muss ein Projekt mit 6 Stück 7-Segment-Anzeiger erledigen.
Und zwar eine Uhr mit Sekunden, Minuten und Stundenanzeiger.
Außerdem sind die paraller auf PORTB geschaltet und werden
durch PORTA gesteuert. Also ich habe nur 2 PORTs zur verfügung.
Keine Tasten sind erforderlich. Das Problem ist Interrupt.
Ehrlich gesagt, kenne ich mich damit gar nicht aus.
Hier unten habe ich mein Programm kopiert. Das Programm ist
sehr einfach formuliert, da ich ein Anfanger bin. Ich weiß nur
nicht, was ich in Interrupt packen muss.
Helfen Sie bitte! Aber bitte mit der Erklärung und keine
komplizierte Sachen, weil ich, wie gesagt, ein Anfanger bin.
Danke voraus.
#define F_CPU 20000000
#include <avr\io.h>
#include <util\delay.h>
#include <avr\interrupt.h>
uint8_t zahlen[10]={ 0b11000000,
0b11111001,
0b10100100,
0b10110000,
0b10011001,
0b10010010,
0b10000010,
0b11111000,
0b10000000};
uint8_t counter_Sekunden=0;
uint8_t counter_Minuten=0;
uint8_t counter_Stunden=0;
int main(void){
DDRA=0xff;
DDRB=0xff;
while(1){
PORTA=zahlen[counter_Sekunden];
PORTB=zahlen[counter_Minuten];
counter_Sekunden++;
_delay_ms(1000);
if(counter_Sekunden==60){
counter_Sekunden=0;
counter_Minuten++;
if(counter_Minuten==60){
counter_Minuten=0;
counter_Stunden++;
}
if(counter_Stunden==24){
counter_Stunden=0;
counter_Minuten=0;
counter_Sekunden=0;
}
}
}
}
Röwschan schrieb:> Helfen Sie bitte!
Du solltest noch etwas über Multiplexen lesen, sonst reichen deine
beiden Ports nicht für sechs 7-Segment Anzeigen.
>Du solltest noch etwas über Multiplexen lesen, sonst reichen deine>beiden Ports nicht für sechs 7-Segment Anzeigen.
und den Artikel
http://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC
Denn mit "_delay_ms(1000)" wirst du bei ner Uhr nicht glücklich werden.
Gruß Matthias
hab das in einem Projekt mit 5x 16-Segment so gelöst, dass ich die
Anzeigewerte ... das Bitmuster ... in ein Array geschrieben habe und
dieses in der Timer-ISR nach löschen der leuchtenden Anzeige einfach auf
die Ports schreibe und dann die nächste Anzeige aktiviere.
Das Array wird in der Mainloop einfach überschrieben wenn ne
Aktualisierung ansteht.
Fhutdhb Ufzjjuz schrieb:> hab das in einem Projekt mit 5x 16-Segment so gelöst, dass ich die> Anzeigewerte ... das Bitmuster ... in ein Array geschrieben habe und> dieses in der Timer-ISR nach löschen der leuchtenden Anzeige einfach auf> die Ports schreibe und dann die nächste Anzeige aktiviere.> Das Array wird in der Mainloop einfach überschrieben wenn ne> Aktualisierung ansteht.
Warum sollte man das auch großartig anders machen?
Vielleicht noch zwischen zwei Puffern umschalten, damit keine wirren
Informationen angezeigt werden.
Sprich: Ein Puffer wird angezeigt und der andere geändert.
Soll nun der geänderte angezeigt werden, so ändert man den Startindex
und gut.
Hi Röwschan,
die wesentlichen Stichworte wurden oben ja schon erwähnt. Hier
http://www.ulrichradig.de/home/index.php/projekte/Power-Supply-PS1
kannst Du sehen, wie es fertig aussehen kann, den ADC als Datenquelle
musst Du Dir einfach wegdenken. Ich habe das zu einem Display umgebaut,
das via TWI seine Daten bekommt.
Gruß
Hermann-Josef
Hi,
da hast Du Dir aber für einen Anfänger gleich eine harte Nuß ausgesucht.
Ich versuche Dir mal praktisch zu helfen. Als erste brauchst Du die
7-Segmentanzeigen mit gemeinsamer Anode, dann benötigst Du einen Quarz
mit einer Frequenz von 3,6864 MHz, die bekommst Du fast überall. Als
Prozessor ist sicherlich ATmega8 ideal, kannst aber auch andere nehmen.
Vorwiderstände für die Segmentanzeige nicht vergessen!
Der Quellcode habe ich aus einem Projekt von mir für Deine Bedürfnisse
abgewandelt. Habe ihn recht ausführlich kommentiert.
Hab den Code so noch nicht ausprobiert, soll Dir auch nur als
Orientierung helfen.
Viel Erfolg
ISR(TIMER2_COMP_vect)// int Signal (SIG_OUTPUT_COMPARE2)
2
{
3
...
4
5
//-------------- Hier wird die 7-Segmentanzeige aktualisiert -----------------
6
7
// Sekunden Segment wird geschrieben
8
9
...
10
11
// Minuten Segment wird geschrieben
12
13
...
14
15
// Stunden Segment wird geschrieben
16
17
...
18
}
Schon falsch.
Das ist genau die Methode, wie man es nicht macht.
In einem ISR Aufruf wird immer nur 1 Anzeigenstelle bedient. Die
leuchtet dann bis zum nächsten ISR Aufruf, bei der dann die nächste
Stelle drann kommt. Immer reihum. Bei jedem ISR Aufruf wird die
vorhergehende Stelle abgeschaltet und die nächste eingeschaltet.
Bei dir leuchten die Anzeigen nur während der Zeit, die du benötigst um
das Muster für die jeweiligen Stellen zu bestimmen(*). Und das auch nur
mit der Frequenz in der die ISR aufgerufen wird. Macht man es richtig,
dann leuchtet jede Anzeigenstelle die komplette Zeit von 'ihrem' ISR
Aufruf bis zum nächsten durch und ist daher wesentlich heller.
(*) Eigentlich noch nicht mal das.
>> lauten
Nö.
Grundregel: Wenn du dividiern willst, dann dividiere auch (oder in
deinem Fall dann eben die Modulo Operation - den Rest bei einer
Division). Gibt es eine Möglichkeit eine DIvision durch andere
Operationen zu ersetzen, dann lass das den Compiler machen. Der macht
das zuverlässig und macht nicht die Fehler die du machst.
Aber warum so kompliziert mit DIvision?
count++;
if( count == 6 )
count = 0;
ist eine perfekt einfache Methode, wie man einen Zähler bauen kann, der
laufend von 0 bis 5 durchzählt.
auch falsch. Die letzte Segmentleitung, die eingeschaltet war, wenn
dieser Code zur Ausführung kommt, war der für die Stunden-Einer. Machs
nicht so kompliziert: Schalt einfach am Port B immer ALLE
Segmentleitungen ab und gut ists.
Und die Sache mit dem SegFill solltest du auch noch mal überdenken. Es
gibt keinen Grund jedesmal in der ISR die Segmentmuster zu bestimmen.
Die ändern sich nur jede Sekunde, es ist daher nicht notwendig sie
jedesmal neu zu bestimmten. Der Multiplexcode zeigt im Idealfall einfach
nur ein Segmentmuster an. Wo auch immer dieses herkommt - das gehört
nicht wirklich in die ISR, dass sich dieses Muster aus irgendwelchen
Zahlen ergibt.
Der Multiplexteil in der ISR kann so einfach sein wie
1
ISR(TIMER2_COMP_vect)// int Signal (SIG_OUTPUT_COMPARE2)
Röwschan schrieb:> Muss ein Projekt mit 6 Stück 7-Segment-Anzeiger erledigen.Andreas schrieb:> da hast Du Dir aber für einen Anfänger gleich eine harte Nuß ausgesucht.
Bei "muss" kann von "aussuchen" wohl nicht die Rede sein.
Ist dir klar, warum
> i = count & 5
keine Zahlen 0, 1, 2, 3, 4, 5 generiert und du den Rest einer Division
nur dann durch & erhalten kannst, wenn der Dividend von der Form (2 hoch
n) - 1 ist?
Wenn nicht, reden wir darüber was count & 5 tatsächlich ergibt.
Ich habe in meinem Projekt nur 2 Segmente benutzt und habe genau
1
i=count&1// 0,1,0,1,0,1
benutzt.
Okay, ich habe es so noch nicht probiert.
Sollte aber auch nur eine Richtung sein, damit sich Röwschan
orientierten kann.
Nun, vieleicht kann er ja aus den anderen Codezeilen der Lösung etwas
näher kommen.
Andreas schrieb:> Ich habe in meinem Projekt nur 2 Segmente benutzt und habe genau>>>
1
>i=count&1// 0,1,0,1,0,1
2
>
>> benutzt.
DAs ist eine andere Sache.
1 IST so eine Zahl, mit der das geht.
Die anderen sind: 1, 3, 7, 15, 31, .... eben alle Zahlen der Form
(2 hoch n) - 1
für n gleich 0, ergibt das eben 1
1 3
2 7
3 15
(es sind alle Zahlen, die um 1 kleiner sind als eine 2-er Potenz, bei
denen also die Bitdarstellung der Zahlen nur aus lauter 1-en besteht)
Aber: Diese 'Tricks' kennen die Compilerbauer alle. Und noch ein paar
mehr. Mit solchen 'cleveren' Tricks schiesst du dir höchstens ein
Eigentor. So wie hier.
Okay, bin vieleicht kein Superhirn.
Meine Intension war auch nur pragmatisch zu helfen, es wird leider immer
wieder auf irgendwelche „ist doch kein Problem“ oder „schau doch mal da
nach“ Seiten hingewiesen, von den Chaoten mal ganz abgesehen, die
scheinbar eine destruktive Einstellung haben, oder einfach nur ohne
nachzudenken sich ein Spaß daraus machen. Einen praktischen Nutzen kann
leider niemand daraus ziehen.
Was ich gut finde ist die konstruktive Kritik von Dir, die auch dem
Fragesteller hilft.
Weiter so…
Andreas schrieb:> Okay, bin vieleicht kein Superhirn.
Das hat doch damit nichts zu tun.
Du interpretierst du jetzt etwas hinein, was nicht beabsichtigt war.
> Meine Intension war auch nur pragmatisch zu helfen, es wird leider immer> wieder auf irgendwelche „ist doch kein Problem“ oder „schau doch mal da> nach“ Seiten hingewiesen
Nicht ganz.
Die Intention ist, dass der Fragesteller erst mal selber ran soll.
Rundumschlag-Fragen sind nicht wirklich geeignet um hier in Form eines
Beitrags beantwortet zu werden. Da dieselben Fragen immer wieder
auftauchen, haben sich Leute hingesetzt und dazu einen längeren Beitrag
geschrieben in dem die wesentlichen Punkte erläutert werden. Wenn dann
noch konkrete Fragen offen bleiben, kann er sie gerne stellen und die
werden dann auch konkret beantwortet.
> Was ich gut finde ist die konstruktive Kritik von Dir
Darum gings mir auch. Ich will dich ja nicht 'niedermachen' sondern du
sollst ja aus dem Thread was mitnehmen. Ich bin jetzt 25 Jahre im
Geschäft und lerne immer noch.
Ich weiß, daß sich eine Menge Leute eine Menge Mühe machen um anderen
die Materie verständlich zu vermitteln, was ich auch sehr schätze.
Auch ich habe viel davon Profitiert. Darum habe ich auch im Rahmen
meiner Möglichkeiten versucht anderen zu helfen u.a. mit diesem Beitrag
Beitrag "Parameter aller Atmel Mikrokontroller"
Aber um auf den Punkt zu kommen, habe ich verstanden was Du mir
vermittels und werde den Mut nicht verlieren, mit einer gewissen
Empathie, anderen einem Weg aufzuzeigen.
So, jetzt wollen wir uns aber wieder der eigentlichen Anforderung
widmen...
Vielen Dank für eure Interesse und eure Antworten.
Leider verstehe ich immer noch nicht, wofür man Interrupts braucht
oder genauer gesagt, wie dieses System mit 6x7-Segmentanzeiger
funktioniert. Also welche PINs man laufen lässt und welche stoppt
oder wie man das auch mit Interrupts nennt usw.. Was ich nur inzwischen
verstanden habe ist das Ein -und Ausschalten eines Segmentenanzeigers
oder mehreren Anzegers (z.B. 00-00-0 für Std, Min, Sek, während
die Einerstelle des Sekundenanzeigers bis 9 läuft) mehrmals pro Sekunde
oder ms (weiß ich nicht genau :-/), was auch die Augen von Menschen
als "still" sehen, bzw. erkennen. Wie z.B. 00-00, als dauerhaft
leuchtende.
Vor diesem Projekt hatte ich noch ein Projekt mit 4x4-Tastenmatrix.
Und das habe ich schon fertig. Die Funktionsweise dieses Systems konnte
man verstehen, indem man die Matrixtabelle mit Spalten und Zeilen
sah. Aber dieses mal, muss ich zugeben, weiß ich nicht, wie ich
vorgehen muss. Denn man muss zuerst wissen, was man machen muss und
wie das System funktioniert, bevor man programmiert. Denn jeder hat
eigene
Art und Style zu programmieren. Also mir würde es zuerst reichen, wenn
ihr mir bitte das System erklären würdet. Außerdem habe ich nur zwei
Wandstecker je 10 PINs und je PORTA und PORTB. Keine Transistoren usw.
sind erforderlich. Und nur die Widerstände vor den 7-Segmentenanzeigern
sind vorhanden, was auch normal ist.
Nochmal Danke voraus! :-)
Röwschan schrieb:> Leider verstehe ich immer noch nicht, wofür man Interrupts braucht> oder genauer gesagt, wie dieses System mit 6x7-Segmentanzeiger> funktioniert.
Das sind 2 Fragen.
Zur ersten: Den Timer-Interrupt brauchst du, damit du unabhängig vom
eigentlichen Programmlauf so etwas wie einen Basistakt im Programm hast.
Qusai ein Mechanismus der unbhängig von deinem restlichen Programm alle
x Zeiteinheiten ausgeführt wird. Was immer dann auch dieses x ist.
Zur zweiten: Mit diesem Mechanismus hast du dann die Basis, damit die
Anzeige unabhängig vom restlchen Programm laufend angezeigt wird. Sobald
dieser Timer-Interrupt Mechanismus läuft, brauchst du dich um die
Anzeige nicht mehr weiter kümmern. Dein Hauptprogramm beschreibt einfach
6 Variablen mit dem jeweils anzuzeigenden Muster und ist davon befreit
sich weiter darum zu kümmern. Die Muster (die in deinem Fall so gewählt
sind, dass sich Zahlen ergeben), werden 'magisch' auf die 7-Seg Anzeigen
gezaubert. Für dein Hauptprogramm SIND die 6 Variablen dann ab so fort
die Anzeigen. Was immer ihnen zugewiesen wird, wird auch angezeigt.
> Vor diesem Projekt hatte ich noch ein Projekt mit 4x4-Tastenmatrix.
Auch ein gutes Projekt, welches man mit Timer-Interrupts angeht.
> Art und Style zu programmieren. Also mir würde es zuerst reichen, wenn> ihr mir bitte das System erklären würdet.
Du machst den 2-ten SChritt vor dem ersten. Zuallererst musst du dich
mit Timer und den zugegörigen Interrupts bzw. den daraus sich ergebenden
Möglichkeiten auseinandersetzen. SOlange deine Programme auf _delay_ms
basieren hat das keinen Zweck, da weiterzumachen. _delay_ms ist zwar
einfach, ist aber eine Sackgasse. Das reicht für die allereinfachsten
Programme, aber ist nicht tragfähig um damit vernünftige reale Projekte
durchzuführen.
Oder um es klar zu sagen: Wenn deine Aufgabenstellung im Dunstkreis von
"alle y Zeiteinheiten ist etwas zu machen" sich bewegt, dann lautet die
korrete Antwort "Timer" und nicht "verbringe die Zeit dazwischen mit
Warten". Du hast 2 'Aktionen' die alle y Zeiteinheiten ausgeführt werden
müssen:
* die nächste Stelle deiner Anzeige reihum anzeigen (einschalten)
* die systeminterne Uhr weiterstellen
Nochmal:
FAQ: Timer> Denn jeder hat eigene Art und Style zu programmieren.
Kann man natürlich machen. Trotzdem gibt es Dinge, die so und nicht
anders funktionieren. Du kannst noch so sehr auf deiner eigenen Technik
beharren, auch du wirst es nicht schaffen, mit Ohrenwackeln anstatt
Armzügen schwimmen zu lernen.
Timer sind viel einfacher als du glaubst. Du 'fürchtest' dich völlig zu
Unrecht davor.
Also:
Du brauchst einen Timer Interrupt. Dann wird im Programm alle ich sage
mal 10 Millisekunden eine "Funktion" ausgeführt. In dieser Funktion tust
du folgendes:
1. Anzeige 1 Strom geben (d.h. gemeinsame Anode bzw Kathode an + bzw -
legen *Ein Transistor ist Pflicht!*)
2. An die LEDs der Anzeige per Port deine Zahl ausgeben
3. Anzeige 1 abschalten
4. Das selbe mit allen anderen Anzeigen machen
Allerdings muss ich zustimmen, du solltest erstmal kleiner anfangen und
nicht fragen bis sich einer erbarmt und dir ein fertiges Projekt postet
(was nicht geschehen wird)
Christian F. schrieb:> Ein Transistor ist Pflicht!
Leider darf ich keine Transistoren benutzen. :-(
Und nochmal eine Frage. Ich setze in die Timerschleife die
binäre Muster für die Anzeige "0" und lasse diese Schleife
laufen. Das mache ich mit den 5 Anzegern bis zur Einerstelle
des Sekundenanzeigers. Wie steuere ich dann diesen Anzeiger
bis 9? Denn alle Anzeigern sind elektrisch paraller an
PORTB verbunden und werden von PINA0 bis PINA3 gesteuert.
Danke voraus!
Röwschan schrieb:> Christian F. schrieb:>> Ein Transistor ist Pflicht!>> Leider darf ich keine Transistoren benutzen. :-(>> Und nochmal eine Frage. Ich setze in die Timerschleife die> binäre Muster für die Anzeige "0" und lasse diese Schleife> laufen.
Und nochmal: DIeses Konzept ist eine Sackgasse.
Lies es von meinen Lippen, äh Tastendrücken ab
S A C K G A S S E
> Denn alle Anzeigern sind elektrisch paraller an> PORTB verbunden und werden von PINA0 bis PINA3 gesteuert.
An PORTB das anzuzeigende Muster für die erste Stelle einstellen und mit
PA0 die anzeige einsschalten.
Nach x Zeiteinheiten
Mittels PA0 die Einerstelle wieder abschalten.
An PORTB das anzuzeigende Muster dür die nächste Stelle einstelleun und
diese Stelle mit PA1 einschalten.
Wiederrum nach x Zeiteinheiten
Mittels PA1 die Anzeige wieder abschalten und mit PORTB das Muster der
nächsten Stelle einstellen. Dieses Muster mittels PA2 auf der
zuständigen Anzeige anzeigen.
danach dasselbe mit der 4.ten Stelle und PA3
dann gehts wieder von vorne los
Muster für die erste Stelle und mit PA0 anzeigen.
usw. usw.
und damit dieser Mechanismus von alleine durchläuft, legt man ihn in
einen Timerinterrupt.
Und damit das auch eindeutig klar ist. Bei x reden wir nicht von 1
Sekunde sondern eher von 1 Millisekunde. Für das reine Multiplexen ist
das reltiv wurscht ob wir da jetzt von 1 MIllisekunde oder 2.8743
Millisekunden reden. Aber für deine noch zu bauende Uhr ist das nicht
mehr egal.
Und jetzt lies endlich den Link!
> Wie steuere ich dann diesen Anzeiger bis 9?
Hast du eine 2 stellige Zahl, zb 45, was ergibt dann Zahl / 10?
Und was ergibt Zahl % 10 ?
45 / 10 = 4
45 % 10 = 5
hmm. wie hängen jetzt die Rechenergebnisse mit der Ausgangszahl 45
zusammen?
Entschuldigung,
ich hatte eine Fehler. Korrigiere mich: PA0 bis PA5 steuern jeweils
einen Anzeiger.
Sind das sechs verschiedene Timers? Und wenn ich nur äusere fünf
Anzegern dauerhat auf 0 setzen will (PA0 - PA4) und die erste
Einerstelle jede Sekunde von (ab Anfang) von 0 bis 9 laufen
lassen will, muss die einem anderen Timer gehören?
Röwschan schrieb:> Sind das sechs verschiedene Timers?
nein.
Röwschan schrieb:> Und wenn ich nur äusere fünf> Anzegern dauerhat auf 0 setzen will
Was das für eine Sprache sein?
Röwschan schrieb:> die erste Einerstelle jede Sekunde von (ab Anfang) von 0 bis 9 laufen> lassen will, muss die einem anderen Timer gehören?
Einem Timer "gehört" doch nichts. Ansonsten siehe oben.
Wustest du eigentlich, dass es Zettelsammlungen, so genannte
"Datenblätter" zu den Mikrocontrollern gibt? Da steh dann auch drin,
wieviele <Zitat>"Timers"</Zitat> ein µC hat.
Karl Heinz Buchegger schrieb:> Nicht in deinem µC.>> Du brauchst ein C-Buch
Das war ein Witz. Deswegen der Smiley. Ganz nebenbei könnte die Variable
ja auch vom Typ float sein (Aber mir ist schon klar, dass int gemeint
ist).
Christian
P.S.: Ich habe wirklich kein C Buch...
Christian F. schrieb:> Karl Heinz Buchegger schrieb:>> Nicht in deinem µC.>>>> Du brauchst ein C-Buch>> Das war ein Witz. Deswegen der Smiley.
Entschuldigung, den hab ich nicht gesehen.
(Komm gerade von einem Nickerchen)
Röwschan schrieb:> Sind das sechs verschiedene Timers?
Nein. Einer.
Stell es dir so vor:
Du (alleine) hältst nacheinander für jede Stelle eine Tafel hoch. Wenn
du das schnell genug machst, merkt keiner, dass du immer nur 1
hochhältst. Für einen Beobachter sieht es so aus, als ob du alle 6
gleichzeitig hochhältst.
(Und für deinen µC ist das kein Problem, 1000 mal in der Sekunde 'die
Tafeln' zu wechseln)
> Und wenn ich nur äusere fünf> Anzegern dauerhat auf 0 setzen
spielt keine Rolle.
Läuft der Mechanismus erst mal, dann sieht es so aus als ob alle 6
Anzeigen gleichzeitig leuchten. Egal was sie anzeigen.
Ich kappiere das immer noch nicht. :-((
Habe versucht etwa 5 Stunden zu verstehen, komme trotzdem nicht klar.
Also die Anzeiger 00-00-00 ist ein bisschen klar geworden.
Aber wie komme ich dann auf 00-00-01, 00-00-02 usw.. Brauche ich
nur ISR oder auch int main(void) mit while? Und wenn, dann wie?
Wenn ISR unabhängig von dem Rest des Programms "still" läuft
und am PORTB immer die entsprechende Muster von 0 bis 9
geschrieben werden, dann haben wir 00-00-00, 11-11-11, 22-22-22 usw.
Bin ganz durcheinander. Schreiben Sie bitte zumindest ein
Programmbeispiel,
wie es aussehen konnte, zumindest nur mit 00 bis 59...
Hi
>Leider darf ich keine Transistoren benutzen. :-(
Also, da denke ich, wird der Controller seine reine Freude haben. Ok,
vielleicht nimmst du 7 Segmentanzeigen, die deutlich weniger als 10 mA
Strom brauchen, aber beim multiplexen mußt du schon ein wenig Strom auf
die Anzeige pulsen, damit sie schön lesbar sind. Da bis zu 7 Segmente
angesteuert werden können und der gemeinsame die gesamte Stromlast auch
tragen muß, kann es durchaus sein, das so ein Pin der es eigentlich nur
gut meint, richtig fett überlastet wird. Wenn du keine Transistoren
nehmen darfst, dann setze wenigstens einen Treiberbaustein ein.
Zur Funktionalität der Interrupts:
Timer-Interrupt wird so eingestellt, das er jede Millisekunde eine ISR
(Interrupt Sevice Routine) aufruft. Das ist im Prinzip ein
Unterprogramm.
Dort erledigst du folgendes:
den gemeinsamen ausschalten , Anzeige ist nun dunkel
neues Bitmuster auf die Segmente schalten, Anzeige ist immer noch dunkel
den gemeinsamen zuschalten, Anzeige zeigt neue Zahl. Ich kann kein C,
aber in Assembler benutze ich ein Byte, und schiebe eine "1" durch für
die Anzeige. Parallel dazu läuft ein Zähler (0-5) mit und adressiert die
Matrixausgabe für die 7 Segmente. Die Matrixausgabe wird im normalen
Programm aus einer Matrix für die Ziffern 0-9 und dem Anzeigewert
gebildet.
Adresse Matrix + Zahl -> Matrixausgabe
Merk dir einfach: trenne Zahlenbildung und Ziffernanzeige. Der
Interrupthandler greift nur auf dan Anzeigepuffer, das Programm setzt
den Anzeigepuffer
Gruß oldmax
Ich bräuchte mal ein kleines Programmbeispiel für nur zwei Anzeigern und
zwar Einer -und Zehnerstelle des Sekundenanzeigers. Und bitte etwas
Simples mit den Erklärungen...
Ich bin euch echt dankbar und akzeptiere alles, was ihr hier schreibt.
Aber ihr solltet auch meine Lage verstehen. Ich bin Anfänger und ich
kenne mich nicht mit allen Befehlen aus. Ich würde das alles sehr
langsam mit Details lernen, aber leider mus ich mein Projekt in der
Schule in zwei Wochen fertig haben. Wie geschrieben, darf ich keine
andere Bauteile benutzen. Nur die 7-Segmentanzeiger und die Widerstände
für PINs. Mehr nicht. Und das scheint für mich eine Menge Arbeit zu
sein. Doch will ich nicht aufgeben und frage aus diesem Grund euch nach,
da ihr mehr Erfahrung habt.
Vielen Dank voraus!
:-)
Christian F. schrieb:> Ein Transistor ist Pflicht!
Wieso das?
Das ist einzig eine Frage der geforderten Helligkeit und
Anzeigeeigenschaften. Prinzipiell läßt sich eine Anzeige auch ohne
zusätzliche Treiber aufbauen.
Werner A. schrieb:> Christian F. schrieb:>> Ein Transistor ist Pflicht!>> Wieso das?
Ok, ich hätte schreiben sollen:
Ein Transistor ist in 99,99999% der Fälle notwendig.
@Röwschan
Ich versteh Deine ganze Aufregung nicht.
Ist es eine Hausaufgabe ?
- Dann solltest Du das Gelernte anwenden.
- Oder den lern stoff intensiv durchgehen.
Ist es ein privates Projekt von Dir?
- Dann solltest Du noch mehr Grundlagen lernen.
- In den Postings steht schon so viel drin, was Du lernen könntest.
- Aber nicht tust. Drum kommen immer Deine gleichen Fragen.
Oder suchst Du jemand der Dir die Arbeit abnimmt? Weil Du nix lernen
willst. Kommt hier nicht so gut an. Bei fast keinem.
spontan schrieb:> Ich versteh Deine ganze Aufregung nicht.
Das Problem ist, wir haben nicht alle Befehle in sich gelernt. Oder man
kann auch sagen, zu wenig. Wir sind ja im Beruflichen Gymnasium und
müssen auf die Befehle selber kommen. Besonders mit Interrupts hatten
wir noch nie zu tun. Außerdem sind die Unterlagen (Mikrocontroller,
C-Unterlagen usw.) nur im E-Technik Raum und wir dürfen die nur in der
Schule benutzen. Zu Hause hat man nur Atmel Studio zur Verfügugn und
dann weiß man nicht, ob das geschriebene Programm korrekt sei. Also
Hardware sollte man sich kaufen, wer möchte, was auch sehr teuer ist.
Die andere Sache ist, wenn man die Befehle lernt, ist es immer besser,
wenn man die an verschiedenen Beispielen testet, was wir auch nicht in
der Schule machen. Da muss ich ehrlich sein. Aus diesen Gründen bitte
ich euch mir Paar Beispiele zu schicken und erklären. Ich will ja nur
klar kommen, damit ich den Rest selber erledigen kann. Ich will nicht,
dass ihr alles für mich macht. Um Gottes Willen!
Vielen Dank voraus!
Röwschan schrieb:> Außerdem sind die Unterlagen (Mikrocontroller,> C-Unterlagen usw.) nur im E-Technik Raum und wir dürfen die nur in der> Schule benutzen. Zu Hause hat man nur Atmel Studio zur Verfügugn
Du hast das ganze Internet zur Verfügung.
http://blackstrom.derschwarz.de/avr/avr_uhr/index.shtml
Röwschan schrieb:> Zu Hause hat man nur Atmel Studio zur Verfügugn und> dann weiß man nicht, ob das geschriebene Programm korrekt sei.
Mit dem Simulator in AVR Studio kann man den Programmablauf prima
simulieren und sich ansehen, ob die Signale richtig an den Ports
ausgegeben werden. Damit sieht man mehr, als mit echter Hardware.
Hi
>Also,Hardware sollte man sich kaufen, wer möchte, was auch sehr teuer ist.
Na ja, teuer ist ein weiter Begriff. Wenn du dich für das Thema
interessierst, und deshalb besuchst du vermutlich auch das Gymnasium,
sollten dir 1€ /Anzeige, 1 € für Widerstände,3-4 € für einen Controller,
10€ für ein Steckbrett und ca. 40€ für ein Programmiergerät nicht zu
teuer sein. Klar, dabei wird es nicht bleiben, aber für ne gute Note
denk ich, wird der Papa schon mal etwas in die Tasche greifen und dich
unterstützen. Ansonsten, es ist bereits viel gesagt, aber die Befehle
wird dir keiner vorkauen. Da mußt du schon einmal in das entsprechende
Tutorial blicken und lesen, was da steht. In Assembler weiß ich, ist der
Timer gut erklärt. Ich geh davon aus, das im "C" Tuorial ebenfalls
Beispiele stehen, zumal der Timer der Dreh und Angelpunkt
zeitgesteuerter Programme ist und eine Uhr gehört zweifelsfrei dazu.
Gruß oldmax
Röwschan schrieb:> der Schule machen. Da muss ich ehrlich sein. Aus diesen Gründen bitte> ich euch mir Paar Beispiele zu schicken und erklären.
Ich hab dir einen Link gegeben, in dem anhand von Beispielen die Sache
mit den Timern erklärt ist. Andreas hat dir ein Beispiel geschrieben.
Was willst du denn noch?
> Die andere Sache ist, wenn man die Befehle lernt, ist es immer> besser, wenn man die an verschiedenen Beispielen testet
Was hindert dich daran, ein hundsordinäres C Tutorial im Web zu suchen?
Ausserdem ist das ziemlicher Quatsch. Das funktioniert vielleicht am
Anfang, ändert sich aber sehr schnell in die Richtung: Es geht darum
Techniken zu erlernen, Verfahrensweise, typische Vorgehensweisen. Es ist
wie beim Schachspiel. Die ersten beiden Stunden lernst du die
verschiedenen Zugmöglichkeiten, die nächsten 2 Jahre typische
Spielsituationen und wie man sie löst, die nächsten 20 Jahre studierst
du Partien anderer.
Programmieren ist mehr als nur Befehle lernen. Viel mehr. Die Befehle
sind die Grundlagen, schon wahr. Aber sie sind überschaubar wenige.
Nein.
Studiere die Beispiele (insbesondere den Link) und leg deine UHR bzw.
7-Segment erst mal zur Seite.
Im Link ist genau, Schritt für Schritt erläutert, wie man einen Timer in
Betrieb nimmt, und wie man die dazu notwendigen Berechnungen macht.
Du versuchst 5 Schritte auf einmal zu machen und das kann nur in die
Hose gehen. Fang mit dem an, mit dem Alle anfangen: Lass eine LED
mittels Timer blinken. Das hat sich bewährt.
Das kann ruhig auch eine LED von denen aus einer 7-Seg Anzeige sein.
Spielt keine Rolle. Hauptsache sie blinkt erst mal timergesteuert.
Dann lässt du abwechselnd 2 LED blinken und machst die Blinkfrequenz
schneller und schneller. Was beobachtest du? Du beobachtest, dass du
irgendwann das wechselseitige Blinken der LED nicht mehr
auseinanderhalten kannst - obwohl die LED wechselseitig blinken sieht es
für dich so aus, als ob beide durchleuchten würden. Damit hast du den
ersten Schritt zum Multiplex gemacht.
Karl Heinz Buchegger schrieb:> Es ist wie beim Schachspiel.
Man kann ja nicht alle Sachen vergleichen. Außerdem haben einige Sachen
etwas mit dem Talent zu tun, wo man, beispielsweise, ein geborener
Schachspieler ist usw..
Röwschan schrieb:> Karl Heinz Buchegger schrieb:>> Es ist wie beim Schachspiel.>> Man kann ja nicht alle Sachen vergleichen.
Doch, kann man. Zumindest in diesem Fall.
> Außerdem haben einige Sachen> etwas mit dem Talent zu tun, wo man, beispielsweise, ein geborener> Schachspieler ist usw..
Talent macht den Unterschied zwischen einem Standardspieler und einem
Grossmeister. Aber Standardspieler kann jeder werden. Er muss nur üben,
lesen und lernen.
Auch wenn ich das mit den LEDs verstehen werde, ist es immer noch nicht
nachvollziehbar, wie die erste 00-00-01 (also 5) als dauerhaft
leuchtende gesehen werden und dann (00-00-1x) noch 1 dazu. Danach wird
das zu 2,3,4,5.
In welcher Reihenfolge schalte ich die ein -und aus und wie? Die LEDs
können nur leuchten. Aber hier muss man die Zahlen haben.
Röwschan schrieb:> Auch wenn ich das mit den LEDs verstehen werde, ist es immer noch nicht> nachvollziehbar, wie die erste 00-00-01 (also 5) als dauerhaft> leuchtende gesehen werden und dann (00-00-1x) noch 1 dazu. Danach wird> das zu 2,3,4,5.> In welcher Reihenfolge schalte ich die ein -und aus und wie? Die LEDs> können nur leuchten. Aber hier muss man die Zahlen haben.
Du schaltest EINE KOMPLETTE Anzeige, also alle für DIESE STELLE
benötigten LED (bzw. der Zahl die an dieser Stelle angezeigt werden
soll) ein. Und beim nächsten Interrupt kommt die nächste Stelle drann.
Und danach die 3-te. usw. usw.
Aber erst mal brauchst du einen laufenden Timer, der regelmässig
Interrupts auslöst und daher regelmässig den Aufruf einer Funktion (die
ISR) auslöst.
Solange du den Teil nicht hast, ist alles andere sinnlos.
Ich hab allerdings auch das Gefühl, dein Denken geht in die völlig
falsche Richtung.
Nochmal: Es ist völlig wurscht, was die 7-Segment Anzeigen anzeigen
sollen. Das spielt keine Rolle. Da sind 4 Anzeigen
1
... ... ... ...
2
. . . . . . . .
3
. . . . . . . .
4
... ... ... ...
5
. . . . . . . .
6
. . . . . . . .
7
... ... ... ...
und im Timerinterrupt wird die erste Stelle mit den jeweils richtigen
LED aktiviert:
1
... ... ... ###
2
. . . . . . . #
3
. . . . . . . #
4
... ... ... ###
5
. . . . . . # .
6
. . . . . . # .
7
... ... ... ###
ein paar Millisekunden später, wird im nächsten Timerinterrupt diese
Stelle wieder abgeschaltet und die nächste Stelle mit den jeweils
richtigen LED aktiviert
1
... ... ### ...
2
. . . . . # . .
3
. . . . . # . .
4
... ... ### ...
5
. . . . . # . .
6
. . . . . # . .
7
... ... ### ...
Und wieder kurze Zeit später kommt die nächste Stelle drann
1
... ### ... ...
2
. . # # . . . .
3
. . # # . . . .
4
... ... ... ...
5
. . # # . . . .
6
. . # # . . . .
7
... ### ... ...
Und noch mal ein wenig später die letzte verbleibende
1
### ... ... ...
2
# # . . . . . .
3
# # . . . . . .
4
### ... ... ...
5
. # . . . . . .
6
. # . . . . . .
7
### ... ... ...
dann bist du mit einem Durchgang durch und das Anzeigespiel geht wieder
von vorne los. Die erste Stelle
1
... ... ... ###
2
. . . . . . . #
3
. . . . . . . #
4
... ... ... ###
5
. . . . . . # .
6
. . . . . . # .
7
... ... ... ###
usw. usw.
Macht man das langsam genug, dann sieht man ganz deutlich, wie immer nur
1 Stelle leuchtet, gefolgt von der nächsten. Erhöht man die
'Blinkfrequenz' dann blinken die einzelnen Stellen immer schneller, so
lange bis ein Mensch das Blinken nicht mehr wahrnehmen kann. Für ihn
steht dann
9 0 3 2
auf der Anzeige.
Und wenn du dann im Hauptprogramm das Muster für die erste Stelle
entsprechend änderst, dann liest ein Mensch dann eben nicht mehr
9 0 3 2
sondern
9 0 3 3
Das ist völlig losgelöst von irgendeiner Uhr, ja da müssen noch nicht
einmal Zahlen angezeigt werden. Bei der Anzeigefunktion hat man einfach
nur ein bestimmtes Muster von leuchtenden LEDs für jede Stelle. Und die
werden reihum angezeigt. Wo diese Muster herkommen ist für die
Anzeigefunktion unerheblich und eine andere Geschichte.
Das haben Sie sehr gut erklärt. Danke schön! Sie hatten auch Recht, dass
ich in einer falschen Richtung dachte. Nur eine kleine Frage:
Brauche ich dann nachher int main oder reicht es, wenn ich das mit Timer
und zwar in genauern Sekunden die LEDs mit den entscprechenden Mustern
aktiviere?
Röwschan schrieb:> Das haben Sie sehr gut erklärt. Danke schön! Sie hatten auch Recht, dass> ich in einer falschen Richtung dachte. Nur eine kleine Frage:> Brauche ich dann nachher int main
Du brauchst IMMER ein main(). Dort beginnt die Programmausführung. So
ein Timer konfiguriert sich ja nicht selbst!
Studier doch mal die Beispiele in der
FAQ: Timer
Da gibt es nun doch wirklich ein ganz simples Banalbeispiel, welches
einen Timer konfiguriert und in der Interruptroutine eine LED zum
blinken bringt. Ich seh wirklich keinen Grund das alles hier nochmal neu
durchzukauen nur weil du den Link nicht lesen willst bzw. den Prosatext
mit dem angegebenen C-Beispiel nicht in Übereinstimmung bringen willst.
Hi
Versuch dir mal folgendes vorzustellen....
Nach deiner Geburt hast du Laufen, Sprechen, Lesen und Schreiben
gelernt.
++++++++ Initialisierung +++++++++++++.
Nun verrichtest du jeden Tag verschiedene Arbeiten
++++++++ Loop, Main oder irgend ein anderer Schleifenname ++++++
Dein telefon klingelt ---> INTERRUPT
Du unterbrichst deine Arbeiten, merkst dir aber, was du zuletzt getan
hast und bedienst das Telefon
****** Interrupt Service Routine (ISR) ********
Ist das Gespräch zu Ende, setzt du deine alte Arbeit wieder fort.
Die ISR ist eine eigene Routine und wird nicht in der Programmschleife
aufgerufen. Aber sie benötigt Zeit, daher ist dort nur das notwendigste
unterzubringen. Wenn du eine ISR jede Millisekunde aufrufst und das
Programm braucht mehr als eine mSek. dann funktioniert das nicht mehr
richtig. Wenn du also am Telefon zu lange Quatscht, dann werden
nachfolgende Anrufe unter Umständen nicht bearbeitet.
Vielleicht hilft dir dieses kleine Beispiel beim Verständnis um den
Interrupt. Das ist nix besonderes....
Gruß oldmax
Fhutdhb Ufzjjuz schrieb:> hab das in einem Projekt mit 5x 16-Segment so gelöst, dass ich dieAnzeigewerte
... das Bitmuster ... in ein Array geschrieben habe unddieses in der Timer-ISR
nach löschen der leuchtenden Anzeige einfach aufdie Ports schreibe und dann die
nächste Anzeige aktiviere.Das Array wird in der Mainloop einfach überschrieben
wenn neAktualisierung ansteht.
Kannst du mir ein Beispiel zu dem geben welches auf mein Beispiel passen
würde ? Mir ist besser geholfen wenn ich etwas sehen kann.
MFG röwschan