Moin,
ich möchte gern zwei Werte an eine Funktion übergeben (7-Segment,
dreistellig). Das Merkwürdige ist, dass es mit 8-Bit Variablen
funktioniert. Bei 16-Bit gehts nicht mehr und die Anzeige zeigt Unsinn
bzw. gar nichts an. Auch scheint der Controller überlastet zu sein.
in 7-Seg.c
1
voidDisplay_Data(uint16_tZiffer,uint16_tPoint)
2
{
3
Punktwahl=Point;
4
Einer=Ziffern_Table[Ziffer%10];
5
Zehner=Ziffern_Table[(Ziffer/10)%10];
6
Hunderter=Ziffern_Table[Ziffer/100];
7
}
die Übergabe sieht so aus (in main.c):
1
Display_Data(Values[Parameter],Kanal);
Alle Variablen sind 16-Bit.
Wenn ich nun in der obing Funktion, "Ziffer" per Hand auf einen Wert
setze ist alles ok.
Warum klappt die Übergabe nicht? Hier noch der Prototyp (7-Seg.c):
1
voidDisplay_Data(uint16_t,uint16_t);
und die Globalisierung ind der 7-Seg.h welche in main.c includet wird:
1
externvoidDisplay_Data(uint16_t,uint16_t);
Irgendwas hab ich wohl übersehen, finde es aber nicht.
Welche Version der Entwicklungsumgebung (Compiler)?
Die Division ist die teuerste Operation des Controllers. Einen
Interrupt-Handler damit vollzustopfen ist nicht ratsam.
NB: count%2048 ergibt bei uint8_t nicht viel Sinn.
A. K. schrieb:> Welche Version der Entwicklungsumgebung (Compiler)?AVR Studio 4.18 SP3 / Win AVR (GCC)
> count%2048 ergibt bei uint8_t nicht viel Sinn.
Jo, stimmt, Count = 16-Bit.
Rolf Magnus schrieb:> Stellst du denn sicher, daß dein übergebener Wert kleiner als 1000> bleibt?
Noch nicht, aber wenn ich das mit einer 8-Bit Variable mache, bekomme
ich bei 255 einen Überlauf, wenn ich die Eingangsgröße (Spannung)
erhöhe.
Bei 16-Bit geht gar nichts und irgendwo hält er sich übermäßig lange
auf, da der Multiplex etwas zu haken beginnt.
Selbst wenn ich in der ADC-ISR nur
Von der Struktur her: Die Hauptschleife nur fürs Debouncing zu verwenden
und dafür das eigentliche Hauptprogramm in den 1ms-Interrupt zu
verlagern erscheint mir etwas eigenwillig.
Knut schrieb:> Noch nicht, aber wenn ich das mit einer 8-Bit Variable mache, bekomme> ich bei 255 einen Überlauf, wenn ich die Eingangsgröße (Spannung)> erhöhe.
Wenn du den Parameter 16-bittig machst, aber nicht sicherstellst, dass
er innerhalb von 0..999 bleibt, dann riskierst du Schrott in den
Hundertern.
> Selbst wenn ich in der ADC-ISR nur
Die knackigen Divisionen sind nicht die im ADC-Interrupt (weil
Zweierpotenz), sondern die in der Dezimalkonvertierung.
Knut schrieb:> AVR Studio 4.18 SP3 / Win AVR (GCC)
Die Version vom WinAVR wär interessanter. Da gabs vor Jahren mal eine,
die nicht richtig multiplizieren und dividieren wollte.
Ich verwende die Version 20100110.
A. K. schrieb:> Wenn du den Parameter 16-bittig machst, aber nicht sicherstellst, dass> er innerhalb von 0..999 bleibt, dann riskierst du Schrott in den> Hundertern.
Richtig, aber ich ändere nichts außer dem Datentyp der Übergabefunktion
und schon gehts nicht mehr?
> Die knackigen Divisionen sind nicht die im ADC-Interrupt (weil> Zweierpotenz), sondern die in der Dezimalkonvertierung.
Auch wenn ich in der Display_Data Ziffer auf 999 begrenze geht es nicht.
Setze ich Ziffer jedoch auch eine Zahl zwischen 0...999 gehts.
Knut
Tja, scheinbar gab es Probleme mit der Berechnung :-(.
Ich habe nun die Berechnung der Digits in die main.c verlagert und
übergebe nun die fertig berechneten Digits, funktioniert.
Offensichtlich macht der Kompiler da Blödsinn...
Knut
Knut schrieb:> Offensichtlich macht der Kompiler da Blödsinn...
Der Compiler macht - in diesem Fall zumindest - genau was man ihm sagt.
Blödsinnig ist es, eine ISR, die bei 1 MHz Clock alleine schon 850 µs
dauert, im 1 ms-Takt aufzurufen.
gestresster uC schrieb:> Blödsinnig ist es, eine ISR, die bei 1 MHz Clock alleine schon 850 µs> dauert, im 1 ms-Takt aufzurufen.
Das mag sein. Hat jemand noch Verbesserungsvorschläge (Form, Stil,
Syntax)?
Gruß Knut
Dazu müsste man erst mal wissen, was das Ganze überhaupt sein soll und
worum es da geht.
Dein ganzes Programm kommt mir unnötig und übermässig kompliziert vor.
Die Logik dahinter ist so dermassen über das komplette Programm
verstreut und verschmiert, dass es gar nicht so einfach ist, da etwas
sinnvolles dazu zu sagen.
Alleine schon die Tastenauswertung würde mich wanhsinnig machen :-)
Karl Heinz Buchegger schrieb:> Dazu müsste man erst mal wissen, was das Ganze überhaupt sein soll und> worum es da geht.
Gern:
Es handelt sich um 3 Schwellwertschalter mit 3 Relaisausgängen, 4
Tastern, 3 7-Segment-Anzeigen. Einstellbar sollen nun die
Schaltschwellen sein.
Das ganze hat 2 Messbereiche (70/500V) sowie ein Menü das auf der
Anzeige zu sehen sein soll. Mit den Tastern soll durcsh Menü navigiert
werden.
Menü hat natürlich allen Schnick-Schnack (Ziffern Blinken wenn angewält
usw., ist in dieser Version aber noch nicht implementiert.
Was gibt es gegen meine Tasterabfrage? Einfacher gehts doch nun nicht
mehr. Drücken, Entprellen und gut.
Gruß Knut
Knut schrieb:> Was gibt es gegen meine Tasterabfrage? Einfacher gehts doch nun nicht> mehr. Drücken, Entprellen und gut.
Schau dir die PeDa Entprellung an.
Im Vergleich dazu ist deine einfach nur Müll. Auch (oder gerade
speziell) was die Verarbeitung von Tastendrücken angeht.
Wenn ich sowas schon sehe
1
if((!(PINB&(1<<DOWN)))&&(Debounce_down==0))
2
{
3
Debounce_down=200;
(verzeih den Ausdruck), dann wird mir schlecht.
Alles viel zu kompliziert und mit viel zu viel Hintergdunwissen zu
benutzen.
Ich hab die Entprellung nur föüchtig überflogen. Macht er das mit
delays?
Wenn ja, dann sehe ich nocht was an seiner Version besser sein soll...
Aber wie gesagt, immer her mit der Kritik, ich will ja lernen
Ok, er macht es nicht mit delays...
Aber wo ist das Problem in einem Timer eine Variable zu decrementieren
(im Hintergrund). Was passiert mit seiner Routine wenn man die Taste
gedrückt hält? Gilt dann nur ein Anschlag? Währe auch doof...
Will aber Peter nicht runtermachen, er ist echt gut.
Knut