www.mikrocontroller.net

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


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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/A...
http://www2.picfront.org/picture/BN9hqzzrXd/img/AT...
http://www2.picfront.org/picture/HxMQLPb6/img/ATM8...

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:
WAIT:
  rjmp  WAIT
EXT_INT0:    ; bei Switch0
  ldi    temp, 1
  out    TCCR0, temp ; starte Timer0 mit prescale=1
  cbi    PORTB, PB0
  reti
TMR0_Int:    ; TIMER0 Overflow
  out    TCNT0, timer0  ; setze Startwert für Timer0
  dec    count1      ; dekrementiere count
  breq  COUNTOF

  sbis  PORTB, 0    ; pruefe ob PB0 high
    
  rjmp  SetHigh      ; wenn PB0 = 0, setze PB0
  rjmp  SetLow      ; wenn PB0 !=0, loesche PB0

SetLow:
  cbi    PORTB, PB0    ; loesche PB0
  reti

SetHigh:
  sbi    PORTB, PB0    ; setze PB0
  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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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ß.

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: hans (Gast)
Datum:

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

gruß hans

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.