Forum: Mikrocontroller und Digitale Elektronik Schalt-, Tast Funktion mit ATMega8 (ASM)


von hjb49 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, ich bin Umsteiger von MicroChip PICxxxx zu Atmel.
ich habe folgendes Problem:

     ATMega8 mit 16 MHz Takt (Quarz)

     ich möchte eine Routine (ASM) benutzen, die softwaremäßig mit einem
     Taster einen Schalter, Taster simuliert.

     Sourcecode siehe Anhang.

     Das Programm soll beim 1. Tastendruck eine LED einschalten und beim
     2. Tastendruck wieder ausschalten.

     Das Programm funktioniert jedoch nicht so wie ich es will.
     1. Tastendruck: LED ein, solange Taste gedrückt bleibt.
     loslassen: LED aus (sollte "ein" sein bis zum 2. Tastendruck)

von Hannes L. (hannes)


Angehängte Dateien:

Lesenswert?

Schau Dir mal in dem uralten Beispiel im Anhang an, wie der Laser ein- 
und aus geschaltet wird. Die Routine ist direkt hinter der 
Tastenentprellung. Ich habe das ganze Programm angehängt, damit Du noch 
diesen oder jenen AVR-spezifischen Tip finden kannst. ;-)

Nicht falsch verstehen, ich will Dich nicht belehren, ich kann dafür 
nicht mit PICs umgehen... ;-)

...

von hjb49 (Gast)


Lesenswert?

Hallo Hannes,
erstmal schönen Dank für die prompte Beantwortung.
Ich habe deinen Source Code erstmal grob überflogen, genaue Analyse muß 
ich noch nachvollziehen.

Bezüglich Belehrung: ich lasse mich gerne belehren (man kann nicht alles 
wissen, manchmal steckt auch ein Denkfehler hinter den eigenen 
Vorstellungen, denen man auch nach xfacher Überprüfung nicht findet)

Mein Problem ist aber warum nach dem 1. Drücken der Taste, das 2. 
Drücken nicht erkannt wird:

;----------------
;--- Test keypress
; ---||||____________||||----------------||||_________||||-----
;                        PD1 ein                          PD1 aus
;     Prellen         Prellen
;    Taste gedrückt  Taste losgelassen

loop3:
    ldi    r16, 0x00    ; PORTB Eingang
    out    DDRB, r16

    ldi    r16, 0xFF    ; PORTD Ausgang
    out    DDRD, r16

    ldi    r16, 0xFF    ; PORTD alle LEDs On
    out    PORTD, r16

    cbi    PORTD,1

loop31:              ; 1. mal gedrückt
    sbic  PINB,0
    rjmp  loop31

    sbi    PORTD,1
    rcall  delay      ; Taste gedrückt

loop311:
    sbis  PINB,0
    rjmp  loop311

    rcall  delay      ; Taste losgelassen


loop312:            ; 2. mal gedrückt
    sbic  PINB,0
    rjmp  loop312

    rcall  delay      ; Taste gedrückt


loop313:
    sbis  PINB,0
    rjmp  loop313

    rcall  delay      ; Taste losgelassen

    cbi    PORTD,1

    rjmp  loop31

von Hannes L. (hannes)


Lesenswert?

Dein Konzept gefällt mir nicht. Du hast keine Entprellung der Tasten 
und Du vertrödelst Rechenzeit in Warteschleifen. Dieser Programmierstil 
führt in eine Sackgasse.

Um Tasten sauber einzulesen und zu entprellen, nutzt man einen 
Timer-Interrupt und ruft die Entprellroutine im Abstand von 4 bus 25 ms 
zyklisch auf. Die Routine entprellt gleichzeitig bis zu 8 Taster oder 
Schalter (8 Bit Breite der Register) und stellt für jeden 
Taster/Schalter ein Zustandsbit (tas, bzw. Key_state) und ein Flag für 
erneuten Tastendruck (tfl, bzw. Key_press) bereit. Und das alles mit nur 
12 Takten alle 20 Millisekunden für 8 Tasten gleichzeitig... Wer dies 
nicht nutzt, dem ist nicht zu helfen...

Schau Dir das Beispielprogramm noch mal genauer an. Es ist so klein und 
überschaubar, dass ich sogar auf Mainloop-Jobs verzichtet habe und die 
ganze Funktionalität in die Timer-ISR gelegt habe, die vom Timer alle 10 
Millisekunden aufgerufen wird (für die Kritiker: Ja, es geht noch 
besser, heute nutze ich die Timer auch eleganter und effizienter).

...

von hjb49 (Gast)


Lesenswert?

@Hannes
Es ist mir völlig klar, das das Programm nicht optimal ist (ist bei 
einem Neueinsteiger, der sich erstmal mit der Materie beschäftigt auch 
normal!)

Diese Routine soll auch nur dazu dienen, per Software-Breakpoint das 
Programm an bestimmten, nicht kritischen Punkten, anzuhalten um 
Portzustände auszulesen und dann per Tastendruck weiterlaufen zu lassen. 
Da spielt verbratene Rechenzeit keine Rolle.

Meine Hauptfrage war auch, warum der 2. Tastendruck (ab loop312) nicht 
erkannt wird! Es scheint so, als ob dieser Programmteil einfach 
übersprungen wird.

von hjb49 (Gast)


Lesenswert?

Ich habe das Problem gelöst.
Ich hatte den Stack-Pointer nicht initialisiert!

(war bei PICxxxx auch nicht notwendig!)

von Hannes L. (hannes)


Lesenswert?

Das wollte ich Dir jetzt schreiben, ich habe Dein Programm nämlich am 
anderen Rechner getestet und das auch festgestellt. ;-)

...

von Hannes L. (hannes)


Lesenswert?

> (war bei PICxxxx auch nicht notwendig!)

Ist bei einigen anderen AVRs auch nicht nötig...

...

von Matthias (Gast)


Lesenswert?

>Ich habe das Problem gelöst.
>Ich hatte den Stack-Pointer nicht initialisiert!

Wer hat das nicht schonmal vergessen ;-)

Ach ja, wenn Du mal auf das RAM zugreifen willst, dann
bitte nicht ab Adresse 0x00 sondern erst ab 0x0060 oder 0x0100
(bzw. siehe Datenblatt des jeweiligen Controllers).
Warum siehts Du dann im Datenblatt :-)

>(war bei PICxxxx auch nicht notwendig!)

Dafür hat man beim PIC seine Freude mit anderen Kleinigkeiten
(z.B. PCLATH vor einem "goto" manuell setzen, etc.)

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.