Forum: Mikrocontroller und Digitale Elektronik keine konstante Frequenz am ATMega8 Ausgang


von Stefan (Gast)


Lesenswert?

Hi zusammen,
sorry für ungenaue Überschrift, wusste aber nichts besseres.

Ich habe ein STK500 Board mit ATMega8 drauf. Dieser erzeugt mir ein 
40kHz Signal, 20 Perioden lang, welches ich am PB0 abgreife. Als 
Taktgeber dient zZt der interne Oszilator auf 8MHz.
Wenn ich mir nun das Signal mit nem Oscar ansehe, fällt mir auf, dass es 
nicht immer "gleich" ist.
"Gestartet wird der Ping über einen Schalter am STK500, welcher auf den 
EXT_INT0 geht."
Die 40kHz stimmen und meistens ist es ok, manchmal sieht es allerdings 
wie wie hier:
http://www2.picfront.org/picture/kO9L3gsYUKs/img/ATM8_Takt01m.JPG
http://www2.picfront.org/picture/BN9hqzzrXd/img/ATM8_Takt02m.JPG
http://www2.picfront.org/picture/HxMQLPb6/img/ATM8_Takt03m.JPG

Das tritt absolut willkürlich auf (jedes mal, jedes 3mal, 10mal 
garnicht, dann 3mal hintereinander,....) und auch die Periode ist nicht 
immer die selbe (1,3,4,8,....)
Und mit diesem Signal kann ich dann so ziemlich gar nichts anfangen :(

mein Code dazu sieht (verkürzt) so aus:
1
WAIT:
2
  rjmp  WAIT
3
EXT_INT0:    ; bei Switch0
4
  ldi    temp, 1
5
  out    TCCR0, temp ; starte Timer0 mit prescale=1
6
  cbi    PORTB, PB0
7
  reti
8
TMR0_Int:    ; TIMER0 Overflow
9
  out    TCNT0, timer0  ; setze Startwert für Timer0
10
  dec    count1      ; dekrementiere count
11
  breq  COUNTOF
12
13
  sbis  PORTB, 0    ; pruefe ob PB0 high
14
    
15
  rjmp  SetHigh      ; wenn PB0 = 0, setze PB0
16
  rjmp  SetLow      ; wenn PB0 !=0, loesche PB0
17
18
SetLow:
19
  cbi    PORTB, PB0    ; loesche PB0
20
  reti
21
22
SetHigh:
23
  sbi    PORTB, PB0    ; setze PB0
24
  reti

Ach ja: Es ist auch egal ob ich den Ausgang offen oder belastet habe. 
Ich bekomme das selbe Problem

Kann sich jemand erklären, woran das liegen könnte?
Bin irgendwie am verzweifeln...

Danke
Stefan

von Johannes M. (johnny-m)


Lesenswert?

Muss es unbedingt PB0 sein? Nimm Timer 2 (der hat ne Compare-Einheit) 
und OC2 als Ausgang und generier das Signal in Hardware (Timer im 
CTC-Betrieb, Portpin toggeln). Oder nimm einen ATMega88, der hat auch an 
Timer 0 eine Compare-Einheit.

Abgesehen davon ist es sehr ungeschickt, nur so ein Codeschnipselchen zu 
schicken. Traditionell ist die Wahrscheinlichkeit, dass der eigentliche 
Fehler im nicht gezeigten Teil liegt, sehr groß.

von Johannes M. (johnny-m)


Lesenswert?

Stefan wrote:
>   dec    count1      ; dekrementiere count
>   breq  COUNTOF
BTW: Wo brancht der denn überhaupt hin? Eine Marke COUNTOF sehe ich 
nirgends...

von hans (Gast)


Lesenswert?

Der Fehler ist sichtbar: Der Taster prellt, EXT_INT0 und damit
das Timer setzen/starten wiederholt sich.

gruß hans

von Johannes M. (johnny-m)


Lesenswert?

hans wrote:
> Der Fehler ist sichtbar: Der Taster prellt, EXT_INT0 und damit
> das Timer setzen/starten wiederholt sich.
Wäre auch meine Vermutung. Eine Entprellung sehe ich da nirgends. 
Außerdem ist das Auswerten von mechanischen Kontakten mit externen 
Interrupts sowieso meist unsinnig.

von MWS (Gast)


Lesenswert?

Findest Du leicht raus, indem Du das ganze oszillografierte Signal 
anzeigst. Wenn's nach dem Fehler noch 20 Perioden sind, ist's klar, der 
int0 hat nochmal zugeschlagen.

von Michael U. (amiga)


Lesenswert?

Hallo,

zum Codeschnipsel wurde ja schon was gesagt.

Trotzdem: wie entprellst Du den Taster bzw. verhinderst, daß ein 2. oder 
3. auftretender Externer IRQ den Port nicht beliebig wieder auf L setzt?
Danach sieht es mir nämlichn aus. Ext INT wird erkannt, Impulse gehen 
los, irgenwo dazwischen prellt der Taster und erzeugt einen weiteren 
Impuls, der PB 0 auf L setzt.

Wenn schon auf diese Art, dann den Ext INT in seiner IRQ sofort 
ausschalten, am Ende der Impulsfolge evtl. dort noch anstehende IRQs 
löschen und dann erst wieder freigeben.

Gruß aus Berlin
Michael

von Stefan (Gast)


Lesenswert?

Ok, vielen Dank für die vielen und schnellen Antworten!

Lag wohl wirklich am "nicht entprellen"! Hatte da auch schon mal dran 
gedacht, aber warum auch immer, die Spur nicht weiter verfolgt.

....eine Entsprellung hätte die natürlich auch gleich aufm STK500 
mitliefern können....

Ich deaktiviere jetzt in "EXT_INT0:" die externen interrupts und setze 
sie erst nach Durchlauf des kompletten Programms auf enable.

>am Ende der Impulsfolge evtl. dort noch anstehende IRQs löschen
>und dann erst wieder freigeben.
Das ist wohl nicht nötig, da der Interrupt durch eine Flanke ausgelößt 
wird.

Den Taster benutze ich auch nur zu Versuchszwecken. Später wird dort 
dieser durch ein externes Signal ersetzt.

Bin momentan eh dabei, das Ganze auf Timer2 mit compare mode umzubauen. 
Da ich blutiger Anfänger bin, hatte ich mich etwas vor dem doch relativ 
komplexen Timer2 etwas gescheut.

Wie gesagt: Danke euch allen!
Stefan

von Johannes M. (johnny-m)


Lesenswert?

Stefan wrote:
>>am Ende der Impulsfolge evtl. dort noch anstehende IRQs löschen
>>und dann erst wieder freigeben.
> Das ist wohl nicht nötig, da der Interrupt durch eine Flanke ausgelößt
> wird.
Doch, genau das ist nötig! Wenn Du das Interrupt Flag nicht löschst, 
bevor Du den Interrupt wieder freigibst, dann wird der Handler sofort 
wieder aufgerufen. Das Flag ist dann schließlich noch von der ersten 
Prellflanke gesetzt!

von Stefan (Gast)


Lesenswert?

Ok, mir war zwar nicht klar, dass das Interrupt Flag gesetzt werden 
kann, wenn der externe Int. deaktiviert ist, aber ich werds zu Vorsicht 
mal tun...

Danke euch. Mit Timer2 und compare Funktion läufts nun auch problemlos. 
Spart ja einiges an Code....

von Johannes M. (johnny-m)


Lesenswert?

Stefan wrote:
> Ok, mir war zwar nicht klar, dass das Interrupt Flag gesetzt werden
> kann, wenn der externe Int. deaktiviert ist,
Wie soll man denn sonst bitteschön Polling machen können? Die Flags 
werden immer gesetzt, wenn das betreffende Hardware-Ereignis auftritt.

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.