keine konstante Frequenz am ATMega8 Ausgang

Gast #1179285
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
#1179294
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ß.
#1179321
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
Gast #1179479
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
#1179509
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren