www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem beim Entprellen/Timer0


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Mein Assemblercode, der eine 7-Semgente-Anzeige pro Tastendruck um 1 
erhöht funktioniert soweit gut.
Als ich dann den Timer0 einbaute, um den Taster zu entprellen, 
funktionierte gar nichts mehr.
Hat jemand eine Idee woran das liegen kann?

Code ist im Anhang

Gruss

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Code ist im Anhang

Aber gut versteckt.

MfG Spess

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry das mit dem Anhang hat nicht geklappt.
Hier der Code
;Ansteuern der Segmente und des Tasters
;PB0-PB7 sind für die Segmente (Ausgang) und PD2 ist für den Taster (Eingang) bestimmt.

.INCLUDE   "m32def.inc"     ;Deklaration für ATmega32
.DEF     status = r16    ;Variable, die überprüft, ob die Initialisierung schon einmal durchgeführt wurde
.DEF    zaehler = r17    ;Zählregister
.DEF    vergl_reg = r18    ;Register für den Vergleich
.DEF    universal_reg = r19  ;Register für Init.,Masken,...
.DEF    ms_zaehler = r20  ;Zählt die Zeit für die Entprellung des Tasters
.DEF    status_timer0 = r21  ;wenn timer0 Zeit gezählt         hat,nächster überspringen
.DEF    wartezeit = r22    ;Zeit zum Entprellen des Tasters
.ORG    0x000
rjmp initialisierung   ;Nach Reset muss Initialisierung durchgeführt werden
.ORG    INT0addr 
rjmp interrupt0 
.ORG    OVF0addr
rjmp timer0_interrup      
       
;Interrupt initialisieren
    initialisierung:
      ldi wartezeit,0x04        ;Wartezeit = 1 sek.
      ldi zaehler,0x00        ;Zähler auf 0 setzten
      ldi  universal_reg,0x3F      ;0 Anzeigen
      out PORTA,universal_reg
      ldi universal_reg,LOW(RAMEND)  ;Stapel anlegen
      out SPL,universal_reg
      ldi  universal_reg,HIGH(RAMEND)
      out SPH,universal_reg
      in   universal_reg,MCUCR      ;altes Steuerregister
      cbr  universal_reg,1 << ISC00  ;lösche Bit bei ISC00
      sbr  universal_reg,1 << ISC01  ;sezte Bit bei ISC01
      out  MCUCR,universal_reg      ;Bei einer fallenden Flanke wird im INT0 ein Interrupt ausgelöst
      in  universal_reg,GICR      ;altes Freigaberegister
    sbr universal_reg,1 << INT0  ;setze Bit bei INT0
    out GICR,universal_reg    ;Interrupt feigegeben
   sei        ;alle Interrupts global frei

;allg. Initialisierung
          
                                        

      ldi  zaehler,0x00        ;Zähler für Vergleich, Anfangswert 0
          
      ldi wartezeit,0xFF

      ldi universal_reg,0xFF              
      out DDRA,universal_reg      ;Port A als Ausgang

      ldi universal_reg,0x00
      out DDRD,universal_reg      ;Port D als Eingang 

      ldi universal_reg,0x04
      out PORTD,universal_reg      ;INT0/PD2 Pull-up aktiviert

      ldi universal_reg,0x01
      out TIMSK,universal_reg      ;Timer/Counter0 Overflow Interrupt Enable

      ldi universal_reg,0x05
      out TCCR0,universal_reg      ;Disable Force Mode, select Normal Mode, no Compare Match Output
                      ;Select Prescaler 1024 (CS02..00 = 101)
      ldi universal_reg,0x70
      out TCNT0,universal_reg      ;Preloader = 111, jetzt startet der timer0
;"main"

    main: 
          jmp main                ;Endlosscheife
  
    timer0_interrup:
          push universal_reg
          in   universal_reg,SREG
          push universal_reg
          
          inc   ms_zaehler
          
          pop  universal_reg
          out  SREG,universal_reg
          pop  universal_reg

          reti


    warten:    
          push universal_reg
          in   universal_reg,SREG
          push universal_reg

          cpse wartezeit,ms_zaehler
          jmp  warten
          
                    
          pop  universal_reg
          out  SREG,universal_reg
          pop  universal_reg


          ret           
          
            
;"interrupt0"

    interrupt0:
        ldi ms_zaehler,0x00    ;ms_zähler auf 0 sezten
        call warten
                        
  ;->varible hochzählen
                      ;Zeitschritte zählen
        inc zaehler        ;Zähler: Register r17 + 1          

        ldi vergl_reg,0x0A    ;wenn Zähler 10 -> overflow -> Zähler wieder auf 0 setzen
      cp  zaehler,vergl_reg      
      breq overflow
        
  ;->Vergleich
          
      ldi vergl_reg,0x00    ;lade Zahlenwert in Register
      cp zaehler,vergl_reg  ;Registervergleich wenn gleich (r17 - Zahl) Z=1
      breq set0        ;wenn Z=1 Sprung nach "set_"    
        
          ldi vergl_reg,0x01
          cp zaehler,vergl_reg
          breq set1
          
          ldi vergl_reg,0x02
          cp zaehler,vergl_reg
          breq set2
        
          ldi vergl_reg,0x03
          cp zaehler,vergl_reg
          breq set3
        
          ldi vergl_reg,0x04
          cp zaehler,vergl_reg
          breq set4
        
          ldi vergl_reg,0x05
          cp zaehler,vergl_reg
          breq set5
        
          ldi vergl_reg,0x06
          cp zaehler,vergl_reg
          breq set6
          
          ldi vergl_reg,0x07
          cp zaehler,vergl_reg
          breq set7
          
          ldi vergl_reg,0x08
          cp zaehler,vergl_reg
          breq set8
          
          ldi vergl_reg,0x09
          cp zaehler,vergl_reg
          breq set9
  
  ;->Sprung nach "main"
          reti 

;Wenn Zähler =10 -> auf -1 setzten
    overflow:  ldi zaehler,-0x01
        jmp interrupt0
          
;"set_"
;->Maske für PORTA ausgeben
;->Sprung nach "interrupt0"    
    set0:     
          ldi universal_reg,0x3F
            out PORTA,universal_reg
          reti

    set1:     
          ldi universal_reg,0x06
            out PORTA,universal_reg
          reti


    set2:     
          ldi universal_reg,0x6D
            out PORTA,universal_reg
          reti


    set3:     
          ldi universal_reg,0x4F
            out PORTA,universal_reg
          reti


    set4:     
          ldi universal_reg,0x56
            out PORTA,universal_reg
          reti


    set5:     
          ldi universal_reg,0x5B
            out PORTA,universal_reg
          reti


    set6:     
          ldi universal_reg,0x7B
            out PORTA,universal_reg
          reti


    set7:     
          ldi universal_reg,0x0E
            out PORTA,universal_reg
          reti


    set8:     
          ldi universal_reg,0x7F
            out PORTA,universal_reg
          reti
          
    set9:     
          ldi universal_reg,0x5F
            out PORTA,universal_reg
          reti
  
    
    


Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>    warten:
>          push universal_reg
>          in   universal_reg,SREG
>          push universal_reg>

>          cpse wartezeit,ms_zaehler
>          jmp  warten

Nette Methode den Stack vollzubekommen.

>    overflow:  ldi zaehler,-0x01
>        jmp interrupt0

Ähnlicher Unsinn.

Zu deinen Programm kann ich dir nur raten: Gründlich überdenken und neu 
anfangen.
Nur ein paar Tips:
- Interruptroutinen so lang wie nötig und so kurz wie möglich.
- Warteschleifen haben in ISRs nichts zu suche.
- in den Interrupts Flags setzen, die in 'main' abgefragt werden und 
dann
  in Abhängigkeit die entsprechenden Routinen abarbeiten.
....

MfG Spess

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Im Anhang mal ein kleines Beispiel zur Gestaltung deiner Ausgaberoutine.
Ersetzt alles zwischen:

> ;->Vergleich
> ldi vergl_reg,0x00    ;lade Zahlenwert in Register

und

> set9:
>   ldi universal_reg,0x5F
>     out PORTA,universal_reg
>   reti

Allerdings als Unterprogramm und nicht als ISR.

MfG Spess

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo  spess53

danke!

Gruss

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.