Forum: Mikrocontroller und Digitale Elektronik ADC und Timer funktionieren nicht zusammen in Bascom


von Gregor (Gast)


Lesenswert?

Guten Tag an alle:

Mein Problem sieht folgendermaßen aus:

Ich lese bei einem Mega8 Smd einen Spannungswert mit ADC ein. So weit so 
gut, das funktioniert alles und zeigt die Werte am LCD an.

Jetzt wollte ich noch Leds blinken lassen und habe mir den Timer1 so 
programmiert, dass die Led ein paar mal in der Sekunde blinkt.

Ohne den Timer1 funktioniert es wie gesagt einwandfrei. Schalte ich den 
Timer1 ein, so stimmen die Werte ungefähr jede 5te Sekunde nicht und das 
Lcd blendet falsche Werte ein. Meist so ca 300mV daneben. Danach passen 
dir Werte wieder und nach ca 5 Sekunden schmeißt er wieder falsche Werte 
rein.

Der Mega8 läuft mit internem Quarz, also 1MHz. Ich habe ihn aus der 
Verpackung genommen und reingelötet, programmiert und ausprobiert.

Kann mir da einer helfen?

Vielen Dank
Gregor

von Helmut L. (helmi1)


Lesenswert?

>Der Mega8 läuft mit internem Quarz, also 1MHz.

Es gibt keinen internen Quarz !

>Ohne den Timer1 funktioniert es wie gesagt einwandfrei. Schalte ich den
>Timer1 ein, so stimmen die Werte ungefähr jede 5te Sekunde nicht und das
>Lcd blendet falsche Werte ein. Meist so ca 300mV daneben. Danach passen
>dir Werte wieder und nach ca 5 Sekunden schmeißt er wieder falsche Werte
>rein.

Haengen die LEDS an dem selben Port wie die Analog eingaenge ?
Dann koennte es sich um uebersprechen handeln.

Gruss Helmi

von Gregor (Gast)


Lesenswert?

Danke für die Antwort!

Ja, das stimmt, die Leds hängen auf PC5 und PC4, sind zwar ADC Eingänge, 
aber kann man ja als normalen Pin auch nehmen ?!?

Eingelesen werden drei Spannungsquellen auf PC0, PC1 und PC3.

hmmm, aber andere Pins sind "eigentlich" nicht mehr frei, da müsste ich 
was ändern.

Glaubst du, dass es davon wirklich kommt? Dann versuch ich das mal zu 
ändern.

LG
Gregor

von Helmut L. (helmi1)


Lesenswert?

Innerhalb des uC sind die Treibertransistoren fuer die Ausgaenge in der 
gleichen Ecke wie die Analogeingaenge.  Wenn du da jetzt eine LED dran 
haengst fliesst das erstmal ein dicker Strom in dieser Ecke des uC. Das 
kann schon eine verfaelschung der Messwerte zur folge haben.Es kann auch 
sein das dieser Strom an den GND -Anschluessen des uC schon eine 
Spannung abfallen laesst und die ueberlagert sich zur deiner 
Messspannung.
Am besten ist es die LEDs ueber externe Treiber anzusteuern das waere 
fuer den ADC die beste Wahl. In machen Datenblaettern steht auch das man 
wenn man an den ADC-Port digitale Signale anlegt mit Rauschen auf den 
ADC-Kanaelen zu rechnen hat. Einige Prozessorhersteller sehen aus diesen 
Gruenden auch keine Outputs an diesen Ports vor.

Gruss Helmi

von Hannes Lux (Gast)


Lesenswert?

Hast Du alle GND- und Versorgungsanschlüsse richtig beschaltet?
(Alle angeschlossen, jeder seinen Abblock-Kerko, Block-C für AREF)?

...

von Gregor (Gast)


Lesenswert?

Angeschlossen sind alle Versogungspins.

Sprich alle 3xGND auf Masse und 2xVcc,AVCC und AREF mit 3,3V 
Versorgung.Ist ein SMD Mega8.

Dazu habe ich noch zwischen AREF und GND 100nF und zwischen VCC und GND 
auch noch einmal 100nF. Ich denke das sollte passen.

Was bedeutet Block-C für AREF? Ist das eh der 100nF Kondensator?


Kannst du mir bitte ein Beispiel nennen für so einen externen LED 
Treiber, der bei mir passt (3,3V)?

Danke
Gregor

von Helmut L. (helmi1)


Lesenswert?

>Kannst du mir bitte ein Beispiel nennen für so einen externen LED
>Treiber, der bei mir passt (3,3V)?

Im einfachsten Fall einen Transistor.

-------------------+----  +3.3V
                   |
                   A
                  LED
                   K
                   |
                   R1
                   |
                   C
AVR---- R2 ------B    BC547B
                   E
                   |
                  GND


Ein 74HC04 kannst du auch dafür verwenden

Gruss Helmi

von Dennis (Gast)


Lesenswert?

Hast du auch eine kleine Induktivität für den Analogteil vorgesehen, wie 
in der AN beschrieben?

von Peter D. (peda)


Lesenswert?

Gregor wrote:
> Ohne den Timer1 funktioniert es wie gesagt einwandfrei. Schalte ich den
> Timer1 ein, so stimmen die Werte ungefähr jede 5te Sekunde nicht und das
> Lcd blendet falsche Werte ein. Meist so ca 300mV daneben.

Das ist ja extrem viel. Was für einen Vorwiderstand nimmst Du denn für 
die LED?

Du solltest die LED gegen GND schalten (high = an), dann fließt der 
LED-Strom nicht über GND des MC und hebt nicht desssen internes 
GND-Potential an.

Eine Möglichkeit ist auch, die LED immer während der Messung dunkel zu 
tasten. Das dauert nur wenige µs, merkt man also nicht.

Oder nimm den Differenz-Modus des ADC.


Peter

von Peter (Gast)


Lesenswert?

hallo an alle,

ich habe wieder ein bisschen experimentiert:

Ich habe eine Spule mit 10uH zwischen Aref und Avcc angeschlossen. Das 
hat nichts gebracht.

Weiters verwende ich als Vorwiderstand 100 Milliohm für die Leds.


Des weiteren habe ich herausgefunden, dass wenn ich den Timer einschalte 
in Bascom, aber ihm nichts zuweise, also keine Leds die leuchten sollen, 
dann funktioniert es problemlos! Sage ich ihm nun:

Timerroutine:

Isr_von_timer1:
Timer1 = 55000
If Sp0 < 4 Then Toggle Led1 Else Led1 = 0  ....Diesen Satz!
Return

Dann gehts nicht mehr!
Egal, auf welchen Pins die Leds liegen, habe auch schon einen Port 
genommen, wo nicht die ADCs drauf liegen.

Hat bis jetzt alles nichts gebracht!

Meint ihr, ich soll mal einen 8MHZ Quarz anschließen? ODer hat das damit 
nichts zu tun?

LG Gregor

von Peter (Gast)


Lesenswert?

Außerdem habe ich gerade herausgefunden, dass:

wenn ich diese Routine nehme:

Isr_von_timer1:
Timer1 = 55000
Toggle Led1
Toggle Led2
Return


Also die If Befehle weglasse, dann funktioniert es auch!

Ich wollte haben, dass wenn die Spannung unter 4V fällt, dass die Leds 
blinken!

Wieso mag er keinen If Befehl im Timer?

LG
Gregor

von Peter D. (peda)


Lesenswert?

Peter wrote:
> Weiters verwende ich als Vorwiderstand 100 Milliohm für die Leds.

Also Kurzschluß, na dann ist ja alles klar.
Es kann nicht gehen.

Ich nehme immer 1k (für low current LEDs).


Peter

von Peter (Gast)


Lesenswert?

ups, sorry! Ich bin BLÖD!

Nicht 100 milliohm, sondern 100 OHM!


Sollte man die nicht folgendermaßen ausrechnen?

R=(3,3V - 2V)/0,02   ???

Wieso nimmst du 1k?

Vielen Dank
Gregor

von Paul Baumann (Gast)


Lesenswert?

Wenn Du nicht uralte LED benutzt, mußt Du auch keine 20mA fließen 
lassen,
um etwas zu sehen. Hast Du die LED, wie Peter riet, gegen +Ub 
geschaltet?

Was auch besser wäre: In der ISR nur einen Merker zu setzen, den dann
in der Hauptschleife mit der Spannungsbedingung (Sp0<4) zu verknüpfen 
und
anschließend wieder rückzusetzen. Aus der ISR sollte man so schnell wie 
möglich wieder verschwinden.

MfG Paul

von Peter (Gast)


Lesenswert?

Zuerst, danke dass ihr die Zeit habt, mir zu helfen. Das hilft ungemein 
weiter!

Also die Leds sind mit Minus an Masse und mit Plus über Vorwiderstand an 
die Ports des Mega8 angeschlossen. Die Platine ist aber schon geätzt, da 
kann ich nicht wirklich was ändern....


Ich ( Bin aber leider eher unwissend in diesem Bereich ) bin der 
Meinung, dass es mit der ISR zu tun hat, weil wenn ich den If Befehl 
raus nehme und einfach Toggle LED1 schreibe, dann blinkt die schön und 
die Werte passen exakt und springen nicht.


@Paul: Kannst du mir vielleicht kurz erklären, wie das geht im Bascom, 
von der ISR raus, kurz ins Hauptprogramm, und dann wieder zurück?
Oder einen Befehl? Auch in Bascom bin ich leider nicht der Bringer ;o(

Danke
Gregor

von MWS (Gast)


Lesenswert?

Würd' halt mal ein wenig Code posten, dann muss hier keiner raten. Und 
kurz rein und raus heist, es ist schlecht wenn man alle 50mS einen 
Interrupt aufruft, der dann 100mS Verarbeitungszeit hat.

von Peter D. (peda)


Lesenswert?

Peter wrote:
> Also die Leds sind mit Minus an Masse und mit Plus über Vorwiderstand an
> die Ports des Mega8 angeschlossen.

Dann ist es richtig rum.

Aber wenn VCC als Referenz dient, muß auf externe Referenz gesetzt 
werden und VREF extern mit VCC verbunden werden. Sonst verringert der 
Abfall über den VCC-Pin Deine Referenz.


Ob nun der Strombedarf der LED Schuld ist oder Deine Software, kannst Du 
ganz leicht prüfen:
Laß die LED in der Software drin, aber klemme sie ab.


Peter

von Peter (Gast)


Lesenswert?

Alles klar, hier der Code:

$regfile = "m8def.dat"
$crystal = 1000000
$baud = 9600
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.1 , Db6 = Portb.0 , 
Db7 = Portd.7 , E = Portd.6 , Rs = Portd.5
Config Lcd = 16 * 2
Waitms 100
Cursor Off

Config Portd = Output
Config Portb = Output
Config Portc.4 = Output
Led1 Alias Portc.4
Config Portc.5 = Output
Led2 Alias Portc.5

Config Timer1 = Timer , Prescale = 8
Enable Timer1
On Timer1 Isr_von_timer1
Enable Interrupts
Timer0 = 55000

Config Adc = Single , Prescaler = Auto
Start Adc

Dim Ad0 As Word
Dim Ad1 As Word
Dim Ad2 As Word
Dim St0 As Single
Dim St1 As Single
Dim St2 As Single
Dim Vref As Single
Dim Sp0 As Single
Dim Spa0 As String * 10
Dim Sp1 As Single
Dim Spa As Single
Dim Spa1 As String * 10
Dim Spa2 As String * 10
Dim Min0 As Single
Min0 = 10
Dim Min1 As Single
Min1 = 10
Dim Minimum0 As String * 10
Dim Minimum1 As String * 10

Do

St0 = 3.2116 
'spannungsteiler faktor
St1 = 3.212 
'spannungsteiler faktor
St2 = 3.2216
Vref = 3.28 / 1024

Ad0 = Getadc(0)
Sp0 = Ad0 * Vref
Sp0 = Sp0 * St0
Spa0 = Fusing(sp0 , "#.##")

Ad1 = Getadc(1)
Sp1 = Ad1 * Vref
Sp1 = Sp1 * St1
Spa1 = Fusing(sp1 , "#.##")

Ad2 = Getadc(3)
Spa = Ad2 * Vref
Spa = Spa * St2
Spa2 = Fusing(spa , "#.##")

If Sp0 > 1 Then
Locate 1 , 1
Lcd "1:    V"
Locate 1 , 3
Lcd Spa0
Else
Locate 1 , 1
Lcd "1:KAA"
End If

If Sp1 > 1 Then
Locate 1 , 9
Lcd "2:    V"
Locate 1 , 11
Lcd Spa1
Else
Locate 1 ,
Lcd "2:KAA"
End If

Locate 2 , 1
Lcd "Ausgang:     V"
Locate 2 , 10
Lcd Spa2

Waitms 500
Cls
Loop
End


Isr_von_timer1:
Timer1 = 55000

'Toggle Led1
'Toggle Led2

If Sp0 < 4 Then Toggle Led1 Else Led1 = 0
If Sp1 < 4 Then Toggle Led2 Else Led2 = 0

Return

von Paul Baumann (Gast)


Angehängte Dateien:

Lesenswert?

Versuche mal diese Version. Ich fand noch 2 Fehler. Eventuell war es das
schon.

MfG Paul

von Peter (Gast)


Lesenswert?

Danke Paul für deinen Einsatz,

doch leider auch keine Verbesserung.

Was mir auffällt ist, dass es ca. 6Sekunden dauert, bis ZWEI Fehler 
kommen.

Also sechs Sekunden lang zeigt er das richtige an, danach kommt ein 
Fehler, sagen wir zwischen 300 bis 1000mV daneben, danach kommt ganz 
eine anderen Zahl, sagen wir 13673743 oder so....

Leds habe ich abmontiert, brachte keine Verbesserung. Also liegt es 
nicht an denen.


puhhh....Mir fällt nichts mehr ein.

Noch kurz zu dem Statement:
Aber wenn VCC als Referenz dient, muß auf externe Referenz gesetzt
werden und VREF extern mit VCC verbunden werden. Sonst verringert der
Abfall über den VCC-Pin Deine Referenz.

Bei mir dient die Versorgungsspannung (3,3V) für die Referenz.
Was heißt: Muss auf externe Referenz gesetzt werden? Ist das Hardware 
oder Software?
2xVCC und AREF und AVCC sind miteinander verbunden.


Liegt es vielleicht an den Spannungsteilern? Die sind 1K und 2,2K....

von MWS (Gast)


Lesenswert?

Also,

hab's kurz compiliert und hab' mir auch gedacht, daß das Umstellen der 
If/Then Funktion in der ISR nichts bringt, hatte keinen Fehler beim 
Compilieren bekommen.

Die ISR ist m.E. langsam genug, so daß da drin nix zeitkritisches 
passiert, aber hier ein paar Vorschläge:

1) M.E. musst Du nicht den Timer in der ISR immer neu setzen, das kann 
raus

2) Keine Fließkommarechnungen in einer ISR, Du vergleichst einen Single 
Wert < 4
Fließkomma ist langsam. Vorschlag: Mach den Vergleich in der 
Hauptschleife und setze ein "Blinkflag", daß Du dann in der ISR 
auswertest.

3) Du hast ein langes Delay in der Hauptschleife, synchronisiere doch 
gleich alles mit dem Interrupt. Damit kann man vermeiden, daß sich 
Wandlung und Ausgabe in die Quere kommen:

Dim ISR_Sync as Bit
...
>>In die ISR:
...
ISR_Sync = 1
...
>>In die Hauptschleife zum Beginn:
...
ISR_Sync = 0
While (ISR_Sync = 0)
Wend
>> Hier könnte noch ein KLEINES Delay rein, damit würde man dem Port Zeit geben 
zur Ruhe zu kommen, einfach ausprobieren.
...

Ggf. Timer1-Wert anpassen, sollte meiner Rechnung nach aber mit 2.3 Hz 
aufgerufen werden und so passen.

von MWS (Gast)


Lesenswert?

Noooch was:

Config Adc = Single , Prescaler = Auto

ohne weitere Parameter nimmt bei VRef mit VCC verbunden die 
Versorgungsspannung als Referenz. Musst aber aufpassen, ob Deine 
Versorgungsspanmnung stabil ist, jede Schwankungen durch Belastung 
verfälscht den gewandelten Wert. Ich nehme gerne die interne Referenz, 
dann ist zwar der Maximalwert am ADC Pin bei 2.56V erreicht, aber da Du 
scheinbar Spannungsteiler verwendest, kann man das anpassen. Bei 
Verwendung interner Ref den ARef Pin von VCC lösen ! Und mit einem 
passenden Kondensator zur Rauschminderung nach Masse versehen, siehe 
Mega8 Datenblatt.

Dann:

Config Adc = Single , Prescaler = Auto, Reference = Internal

von Gregor (Gast)


Lesenswert?

Hallo,

ich möchte noch alle ganz herzlich danken, die mir geholfen habe, bzw. 
versucht haben zu helfen :o)


Ich habe es endlich geschafft.

Ich habe einen 8mhz quarz eingebaut mit zwei 22pf Kondensatoren. Fuse 
bits umgestellt und nun klappt alles, so wie es soll.

ich weis zwar nicht, ob das die elleganteste Lösung ist, aber 
funktionieren tut es!

Vielen Dank
Gregor

von MWS (Gast)


Lesenswert?

Aber bitte doch ;-)

Du hattest dann ein Timingproblem, da hat etwas zu lange gedauert.

Das wäre aber auch mit Umstellen der Fuse auf internen 8MHz Clock 
gegangen :-)

von Gregor (Gast)


Lesenswert?

Der Mega8 hat einen internen 8Mhz Clock?

Sicher?

von MWS (Gast)


Lesenswert?

Datenblatt Mega8 Seite 30

Table 9. Internal Calibrated RC Oscillator Operating Modes
CKSEL3..0 Nominal Frequency (MHz)
0001(1) 1.0
0010 2.0
0011 4.0
0100 8.0

Note: 1. The device is shipped with this option selected.

von Paul Baumann (Gast)


Lesenswert?

Schickst Du den jetzt funktionierenden Code bitte mal?

MfG Paul

von Gregor (Gast)


Lesenswert?

@MWS: Danke, das wusste ich nicht. Muss ich mal schauen, wie man das 
ganze einschaltet und so....

@Paul: Ich habe am Code nichts geändert. Der Code ist der selbe, wie ein 
paar Posts vorher. nur natürlich 8 Mhz eingestellt.

Lg
Gregor

von Hannes Lux (Gast)


Lesenswert?

Tja, bei 8MHz Takt relativieren sich die 128 Takte Onanie 
(Registersicherung) dir BASCOM in jeder ISR ungefragt macht...

...

von MWS (Gast)


Lesenswert?

Gerne,

Umstellung der Fuses für interne 8 MHz im Programmer Dialog von Bascom. 
Du hast ja bereits auf ext. Oszillator umgestellt, genau da müssten auch 
die Option: internal RC 8 MHz Osc (oder so ist ähnlich) zu finden sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.