PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD , Timer0 und komische Zeichen ??!!



Roberto
13.08.2005, 21:13
Hallo

Habe hier ein sehr komisches Problem :-(



$regfile = "m8def.dat"
$crystal = 10000000


'---Config für LCD -----------------
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portb.0 , Db7 = Portb.5 , Rs = Portb.4 , E = Portb.3
Config Lcdbus = 4
Config Lcdmode = Port


'----- Config Timer0 für Regelung ------
Config Timer0 = Timer , Prescale = 8


'---Sonstiges------------------------
Dim A As Integer

Dim Pwm As Long
Dim Soll As Long
Dim Ist As Long

Dim Istwert As Single
Dim Sollwert As Single
Dim Integrator As Single
Dim Lastistwert As Single
Dim P As Single
Dim I As Single
Dim D As Single
Dim Delta As Single
Dim Ausgang As Single
Dim Pw As Word
Dim Wert As Word
Dim Kp As Integer
Dim Kd As Integer
Dim Ki As Integer
Dim Zeit As Single
Dim Invertiert As Word
Dim Istwert_bit As Word


On Timer0 Auswerten
Enable Timer0
Enable Interrupts

Soll = 0
Ist = 0


Pwm = 128


Cls

'================================================= =======================
'========= Hauptprogramm ================================================
'================================================= =======================
Do
Cls


Soll = 0

Locate 1 , 1
Lcd "Ist" ; Ist

Locate 2 , 1
Lcd "Soll=" ; Soll


Loop



End

Auswerten:

Sollwert = Soll
Istwert = Ist
Delta = Sollwert - Istwert
P = Delta * Kp
D = Lastistwert - Istwert
D = D / Zeit
D = D * Kd
I = Delta * Zeit
I = I * Ki
Ausgang = D
Ausgang = Ausgang + P
Ausgang = Ausgang + I
Lastistwert = Istwert
Pwm = Ausgang + 128

If Pwm < 2 Then Pwm = 2
If Pwm > 253 Then Pwm = 253

Compare1a = Pwm
Timer0 = 0
Return


Das Programm ist eine verkürzte Version vom Original aber der Fehler tritt hier noch auf !

Es soll mit Timer0 eine Routine bearbeitet werden und nebenbei der Wert auf dem LCD ausgegeben werden.

Aber irgendwie kommen für "Soll" und "Ist" immer so komische Zahlen auf das LCD.
Zum Glück tritt der gleiche Fehler auch im Simulator von Bascom auf, nur komme ich nicht dahinter, wie die falschen Zahlen auf das LCD kommen ??

Probiert mal bitte das Programm am Simulator.
(V 1.11.7.9.)
Nach ein wenig Zeit, seht ihr was ich meine..
Das steht dann z.B, für IST 152000000
oder für Soll 880000000

Die Werte selber (ist und Soll) stimmen im Simulator ( sind also =0)

Weis jemand an was das liegt ?

Auch mit einem höheren Prescaler beim Timer, bleibt es noch so..

Irgendwie muss da mit der ansteuerung vom LCD zusamenhängen?!
Irgendwo ein Bit, das nicht so tut wie es soll ???!

Marco78
13.08.2005, 22:15
Vielleicht ist es ja schon das Problem, das die Alte Zahl nicht gelöscht wird auf dem LCD.
Wenn man 1000000 ausgegeben wurde und danach 88 steht auf dem LCD 8800000.

Und ich glaube Config LCD = Port geht auch nicht, da die Datenleitungen ja nicht alle einen Port beanspruchen. Probier es mal spaßeshalber mit Config LCD = Pin. Und das mit den Zahlen muss du selbst wissen. Da der Rest des Programms fehlt, fehlt auch die Erkenntnis wie Groß die Zaheln werden könnten.
Aber wenn es einmal eine 10 war und bei nächsten man eine 1, steht eine 10 auf dem LCD. Oder wenn es beim nächsten mal eine 2 ist, steht da 20.
Also entweder jedes mal CLS, was aber zuviel Programmzeit braucht oder ein paar Leerzeichen schreiben und den Cursor mit Locate wieder an die richtige Stelle bringen.

PicNick
14.08.2005, 13:39
Probier mal, mit größerem Prescale die LCD-Routinen gleich auch in der ISR zu machen.
Nachdem du ihn ohnehin ja viele floats rechnen läßt, kommt's darauf wohl nicht mehr an.
Da ich vermute, daß sich ISR und normal Loop in die Quere kommen, wär es einen Versuch wert.

EDIT: In dieser Kurzversion werden "Soll" und "Ist" gar nicht verändert.
Er müßt da ja immer 0 zeigen.

Roberto
14.08.2005, 15:55
Hallo :-)
Danke für die Antworten :-)



Und ich glaube Config LCD = Port geht auch nicht, da die Datenleitungen ja nicht alle einen Port beanspruchen. Probier es mal spaßeshalber mit Config LCD = Pin.

Habe mal
Config Lcdbus = 4
Config Lcdmode = Port
rausgenommen, aber ändert sich nicht viel..




Da ich vermute, daß sich ISR und normal Loop in die Quere kommen, wär es einen Versuch wert.

Wenn ich den Timmer0 abschalte und alles normal laufen lasse, tritt das nicht auf.
(Aber das will ich ja nicht ;-) )
Der Timmer0 soll eine PID berechnung starten und die soll von der Zeit her immer gleich sein.

Wie ist das eigentlich mit dem verschachteln der Interupts ?
Habe ja dann noch zwei Interrupts an Int0 und Int1
(nicht in diesem Code)

Darf der Timer0 Interrupt eigendlich den LCD befehl unterbrechen.
Schreibt der Lcd-Befehl nachher dann normal das LCD fertig, oder kommt das LCD dann durcheinander ?

Marco78
14.08.2005, 16:37
Habe mal
Config Lcdbus = 4
Config Lcdmode = Port
rausgenommen, aber ändert sich nicht viel..

Rausnehmen bringt nicht viel. Wenn es nicht im Code steht, werden die Einstellungen genommen, die im Compiler stehen. Wenn dort auch Port steht bis du da wo du vorher warst ;)
Deshalb sagte ich ja, es nochmal überprüfen und ggf gegen Pin austauschen.

Und das die Ziffern der alten Zahlen stehen bleiben können ist so gewollt und erwünscht? Ich kann meine Bemerkung ja mal in eine direkte Frage umwandelt.
Was für Zahlen sind denn zu erwarten?

PicNick
14.08.2005, 18:01
@Roberto: Heißt das, ohne Timer-Routine funktioniert das LCD-Zeugs tadellos ? Dann können wird auch das Config mal vergessen, dann paßt das.
Mach einen Test:
In der Timer routine schreibst du einfach nur irgendeinen fixen Wert in Soll und Ist und dann sofort return, laß mal die rechnerei
Auswerten:
Soll = 34
Ist = 28
return
Dann sollten diese Werte ja zu sehen sein ?

Roberto
15.08.2005, 08:07
Hallo

Habe jetzt das LCD Sicherheitshalber auf portC gehängt.
Ist aber noch das gleiche.

Dann habe ich am obigen Code alles gelöscht, wo der Effekt trotzdem noch auftritt.
Und siehe da... irgendwie muss das wohl an den zuweisungen liegen ?!




$regfile = "m8def.dat"
$crystal = 10000000


'---Config für LCD -----------------
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , Rs = Portc.1 , E = Portc.0
Config Lcdbus = 4
Config Lcdmode = Port


'----- Config Timer0 für Regelung ------
Config Timer0 = Timer , Prescale = 8


'---Sonstiges------------------------
Dim A As Integer

Dim Pwm As Long
Dim Soll As Long
Dim Ist As Long
Dim Ausgang As Single


On Timer0 Auswerten
Enable Timer0
Enable Interrupts

Soll = 0
Ist = 0
Pwm = 0
Ausgang = 0

Cls

'================================================= =======================
'========= Hauptprogramm ================================================
'================================================= =======================
Do
Cls


Locate 1 , 1
Lcd "Ist" ; Ist

Locate 2 , 1
Lcd "Soll=" ; Soll

Waitms 50
Loop



End


'--------------------------------
Auswerten:

Pwm = Ausgang + 128 ' hier muss der Hund begraben sein

Timer0 = 0

Return


Hier dürften sich "PWM" und "Ausgang" nicht vertragen ?
Also Long und Single

Der Code ist so 1370 Byte lang und wenn ich die Zeile mit dem
Pwm= Ausgang+128
rausnehme ist der Code nur mehr 910 Byte lang ...

Muss man Single und Long vorher auf einen Nenner bringen ?
Und warum wirkt sich das dann auf das LCD aus ??? komisch...

Ps.:
Habe jetzt alles auf Word geändert.
Funktioniert jetzt :-)

Marco78
15.08.2005, 20:00
Ich kann dir nicht ganz folgen, kann dich aber vielleicht in deiner Vermutung bestätigen.
Bestimmte Funktionen erfordern bestimmte Variablentypen.
Es kann sein das die Addition von Long und Single sich nicht verträgt. Anscheind ist es auch so da es mit Wird zu funktionieren scheind.

15.08.2005, 20:58
Hallo Marco78

Es kann jeder leicht am Simulator nachprobieren.
(bin gespannt ob ihr das auch seht?)

Obwohl der Wert der Variable passt (Simulator) aber auf dem LCD
(auch am Simulator LCD) kommen nur komische Zahlen.
(obwohl der Text ja passt)

Gibt es da eigentlich Reglen, wenn man unterschiedliche Variablentypen miteinander verrechnet ?
Oder kann/muss man die Variablen irgendwie vorher umwandeln ?

hans_k
16.08.2005, 22:54
Hallo Marco78

Ich hatte das selbe Problem mit der Lcd - Ausgabe und Single-Verarbetung in einer Interrupt-Routine.
Aus der Bascomhilfe geht folgendes hervor:
R12 – R15 are not saved. When you use floating point math in the ISR(not recommended) you must save and restore R12-R15 yourself in the ISR.
My_Isr:
Push R12 ‘ save registers
Push R13
Push R14
Push R15
Single = single + 1 ‘ we use FP
Pop R15 ‘ restore registers
Pop R14
Pop R13
Pop R12
RETURN

Das einfügen dieser Zeilen am Anfang und Ende der Interruptroutine beseitigen dein Problem

Gruß Hans

PicNick
17.08.2005, 08:47
Geh', Hans, kannst du mir einen Tip geben, daß ich das im Help nicht erst suchen muß.
Mich wundert das, der Bascom sichert bei ISR ALLE Register von links nach rechts + SREG (logo).
Jetzt möcht ich nachsehen, was da genau gemeint ist.