Kommen dann auf dem LCD wirre Zeichen oder wie macht sich das bemerkbar das der AVR hängt?
Hallo Leute habe ein probleme,
wenn ich fusing benutze dann hängt mein AVR Mega 16 nach einigen sekunden.
kann mir jemand weiterhelfen?
Hier der Code in Bascom
Dim Tempd As Word
Dim Tempa As Single
Dim Tempround As Single
.
.
.
.
Onadc:
Waitms 500
Cls
Tempd = Getadc(1)
Tempa = Tempd - 94
Tempa = Tempa * 0.05
Locate 1 , 1
Lcd "temp digit = " ; Tempd
Lowerline
Lcd "Pression = " ; Getadc(1)
Locate 4 , 1
Print Tempa
Lcd Fusing(tempa , "###.&&")
Return
Danke
Kommen dann auf dem LCD wirre Zeichen oder wie macht sich das bemerkbar das der AVR hängt?
Nein die Anzeige bleibt einfach hängen.
Habe inzwischen einen test ohne Interupt onADC gemacht da klappt es.
Liegt das am Interupt ???
Kann einer das vieleicht auf seinem Mc nachvollziehen ????
Danke für die Hilfe
2 mal Getadc innerhalb einer ISR sind suboptimal. du mußt den wert einmal holen und zwischenspeichern für die darstellung
eine waitms 500 gleich vorn in der ISR ist auch nicht üblich.
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Danke
Werde das mal ändern.
Aber warum funst das nicht mit fusing.
Denn wenn ich fusing nicht benutze läuft alles prima.
gerwin
Single und dann noch in Verbindung mit Fusing braucht einfach viel Zeit. Erschwerend kommt hinzu, daß Du, wie von Picknick erwänhnt, noch ein recht abenteuerliches Wait in der ISR hast. Der Takt"mehrverbrauch" durch Fusing ist da der berühmte Tropfen, der das Faß zum überlaufen bringt.Zitat von samba971
Warum ist denn nun das Wait so überflüssig?
Nun, der Interupt wird ja erst dann ausgelöst, wenn die Wandlung fertig ist. Ein vorsorgliches Warten ist also völlig unnötig.
Generell ist es sinnvoll, ISRs so knapp wie möglich zu halten. Die Ausgabe sollte z.B. im Hauptprogramm erfolgen, in der ISR könntest Du dann schlicht ein Word benutzen. Das Word wird dann, je nachdem was Dir besser gefällt , in eine Singlevariable oder einen String umgewandelt, den Du dann via Format ausgeben könntest.
Grüße
Henrik
Hallo Henrik
Danke für die Erklärung, jetzt ist alles klar wie Klossbrühe.
Habe alles umgeschrieben und jetzt klappt es auch mit meinem Mc.
Nochmals Danke an alle.
Gruss
Gerwin
Habe aber jetzt ein neues problem....
Wenn ich dieses im Simulateur laufen lasse ist alles ok.
Doch auf dem Mc wenn ich eine Spannungsänderung am pin pa2
habe ändern sich beide Werte im terminal (resultpress + resulttemp)
am pin pao (ADC0) kann ich ändern wie ich will keine änderung am terminal ????????????????????
Habe ich ein probleme mit dem ISR
Kann ich nur einen Chanel zur zeit auslesen ???
Hier der Code
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 9600
'$sim
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Config Lcdmode = Port
Config Adc = Single , Prescaler = Auto , Reference = Avcc
On Adc Adc_isr Nosave
Enable Adc
Enable Interrupts
Dim Dval_1 As Word
Dim Dval_2 As Word
Dim Resulttemp As Single
Dim Resultpress As Single
Declare Sub Calcultemp(resulttemp As Single , Dval_1 As Word)
Declare Sub Calculpress(resultpress As Single , Dval_2 As Word)
Do
Cls
Start Adc
Idle
Stop Adc
Call Calcultemp(resulttemp , Dval_1)
'print UART valeur
Print "11 " ; Fusing(resulttemp , "##.# ")
Locate 1 , 1
Lcd "Temperature =" ; Fusing(resulttemp , "##.# ")
Call Calculpress(resultpress , Dval_2)
Print "22 " ; Fusing(resultpress , "##.#")
Locate 2 , 1
Lcd " Pression =" ; Fusing(resultpress , "##.#")
Waitms 500
Loop
End
Adc_isr:
Dval_1 = Getadc(0)
Dval_2 = Getadc(2)
Return
Sub Calcultemp(resulttemp As Single , Dval_1 As Word)
Resulttemp = Dval_1 - 141
Resulttemp = Resulttemp * 0.16
End Sub
Sub Calculpress(resultpress As Single , Dval_2 As Word)
Dim X As Single
X = 4000 / 1023
Resultpress = Dval_2 * X
End Sub[/code]
Gruss Gerwin
Ich nehm an, daß dir die Sache mit den Interrupts noch nicht in allen Details klar ist.
Der Ablauf beim adc-lesen ist folgender (schematisch):
1 Einstellen der Kanalnummer
2 Start der Messung
3 Warten auf Fertigwerden
4 Lesen des Ergebnisses
Durch den Interrupt kann Punkt 3 entfallen, den die ISR-Routine wird genau nach Fertigwerden der Messung automatisch aufgerufen.
So, wie dein Programm abläuft, kann ich dir nur raten, das Ganze Interrupt-Zeugs zu knicken. Denn ob du "idle" sagst oder gleich direkt auf das Ready-Bit wartest, ist zeitmäßig Jacke wie Hose, aber wesentlich leichter zu beherrschen.
Empfehlung:
Code:Start Adc Do Cls Dval_1 = Getadc(0) Call Calcultemp(resulttemp , Dval_1) 'print UART valeur Print "11 " ; Fusing(resulttemp , "##.# ") Locate 1 , 1 Lcd "Temperature =" ; Fusing(resulttemp , "##.# ") Dval_2 = Getadc(2) Call Calculpress(resultpress , Dval_2) Print "22 " ; Fusing(resultpress , "##.#") Locate 2 , 1 Lcd " Pression =" ; Fusing(resultpress , "##.#") Waitms 500 Loop End
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
hallo hatte damals mal ein program geschrieben für den radencoder.
wollte die langsame getadc von Bascom nicht nutzen. vielleicht kannst du ihn weiterverwenden. wenn du onadc nutzen tust, nimm am besten auch die direkten avr-ansprechregister.
mfg pebisoft
Code:$regfile = "m16def.dat" $crystal = 8000000 $baud = 19200 Dim Adhi As Byte Dim Adlow As Byte Dim Adcergebnis As Word Dim Radzaehler As Byte Dim Toggle_rad As Byte Disable Interrupts Adcsra.aden = 1 Adcsra.adate = 1 Adcsra.adie = 1 Adcsra.adsc = 1 Adcsra.adps0 = 1 Adcsra.adps1 = 1 Adcsra.adps2 = 1 Admux.refs0 = 1 Enable Interrupts Radzaehler = 0 Toggle_rad = 0 On Adc Onadc Do Waitms 1 Print Radzaehler Loop Onadc: Admux.mux0 = 1 !! ist adcport pina1 , ohne mux ist pina0 Adcsra.adsc = 1 !! startet das auslesen Adlow = Adcl Adhi = Adch Adcergebnis = Adhi * 256 Adcergebnis = Adcergebnis + Adlow If Adcergebnis > 400 And Toggle_rad = 1 Then Incr Radzaehler Toggle_rad = 0 End If If Adcergebnis < 100 And Toggle_rad = 0 Then Incr Radzaehler Toggle_rad = 1 End If Return End
Lesezeichen