PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : was versteht man unter "Taster im Polling erfassen"!



hegewald
21.01.2014, 18:38
beschäftige mich in Assembler mit Taste entprellen, und lese immer wieder
wieo.g. Taster im Polling erfassen.

Grüße

Rolf

Searcher
21.01.2014, 18:47
Hallo,
der Portpin, an dem der Taster angeschlossen ist, wird zB durch einen Timerinterrupt in (festen) Abständen abgefragt. Die Abstände müssen so kurz sein, daß auch ein kurzer Tastendruck erkannt wird. Siehe auch http://de.wikipedia.org/wiki/Polling_%28Informatik%29

Gruß
Searcher

ihle
21.01.2014, 19:51
Hallo,

kann man durchaus mit einem Timerinterrupt machen, ist wahrscheinlich die elegantere Lösung.
Aber das richtige Polling Verfahren ist wenn der Pin z.B über den Befehl sbic abgefragt wird das würde so aussehen

Start: sbic pind,0 pd0=0?
jmp Start wenn pd0=0 wird der jmp befehl übersprungen.
hier kann man den Taster noch mit einer Zeitschleife ausbremsen.

Die ganz alte Methode wäre das aus maskieren, das würde so aussehen

Start: in r16,pind das Eingansgangslatch an Portd einlesen
andi r16,0x01 jetzt wird pd0 ausmaskiert d.h alle Bits bis auf pd0 werden durch die Undverküpfung gelöscht,
breq start
hier gehts dann weiter


aber wie gesagt das mit dem Timerinterrupt ist die elegantere Lösung, weil das Programm nicht durch die Abfrage ausgebremst wird.
Das Pollingverfahren kann man nicht nur bei Tasterabfragen verwenden sondern auch bei Abtastungen von Signalen.
Der große Nachteil dieses Verfahrens ist, dass der Programmzähler in der Polling-schleife hängt bis die Bedingung erfüllt ist.

mfg ihle

hegewald
22.01.2014, 08:44
danke für Eure Infos!

Hatte mir heute morgen so was ausgedacht:

Haut aber nicht hin, die beiden LEDs an PB0 und PB1 leuchten schwach
sofort nach den Einschalten.




; Projekt-Name: Projekt01 Datum: 22.01.2014

; Datei: Tiny2313-tasteprellen.asm

; AVR: Tiny2313-20PU

.INCLUDE "tn2313def.inc" ; Deklaration für Tiny2313

rjmp reset ; Reseteinsprung
.ORG OVF0addr ; Interrupt-Vektor
rjmp TIMER0_OVF ; Sprung zur ISR

.def akku =r16
.def temp17=r17 ; r17 zum Entprellen

#define sw1 PIND,PD0

reset:

;Timer0 initial.
ldi akku,(1<<CS02)|(1<<CS00)
out TCCR0B,akku ; Prescale = 1024
ldi akku,(1<<TOIE0)
out TIMSK,akku
sei

;Vorbereitung PORTB und PIND
ldi akku,(1<<PB0) | (1<<PB1)
out DDRB,akku ; PB0 + PB1=Output

ldi akku,0x00 ; alle Pins in r16=Low
out DDRD,akku ; Datenricht. PD0-PD6=Input

ldi akku,0x7F ; 0b0111.1111
out PORTD,akku ; PD0 bis PD6=PULLUP

clr akku ; beide LEDs zu Beginn AUS
out PORTB,akku

loop:


sbis sw1 ; überspringe, wenn PD0=HIGH
sbi PORTB,PB0
rcall prellen

sbis sw1 ; überspringe, wenn PD0=HIGH
sbi PORTB,PB1
rcall prellen

sbis sw1 ; überspringe, wenn PD0=HIGH
cbi PORTB,PB0
rcall prellen

sbis sw1 ; überspringe, wenn PD0=HIGH
cbi PORTB,PB1
rcall prellen
rjmp loop

prellen:
ldi temp17,0x02 ; r17 = 02
pause1:
tst temp17
brne pause1
ret

;Interrupt-ISR

TIMER0_OVF:
push r2
in r2,SREG
dec temp17
out SREG,r2
pop r2
reti
.EXIT

ihle
22.01.2014, 19:40
Hallo hegewald,

deine LEDs betreibst du sie direkt am Pin? wenn ja musst du PB0,1 auf 1 setzten,
weil bei 0 der Pin durchschaltet und deine LEDs leuchten und wenn sie schwach leuchten
ist vielleicht dein Vorwiderstand zu groß? Bei 470 Ohm fließen ca. 7mA der Pin verträgt 20mA im Sink Betrieb.
Du hast den Stackpointer nicht initialisiert, den braucht dein Programmzähler für die Rücksprungadressen.
Wenn ein CALL Befehl ausgeführt wird, zeigt der Stackpointer auf eine Adresse im Ram in dieser wird die
Adresse hinterlegt von der das Unterprogramm aufgerufen wird.
Ist das Unterprogramm abgearbeitet wird der Stackpointer mit dem RET Befehl auf diese Adresse gelegt
und der Counter springt an diese Adresse zurück.

Stackpointer init

ldi akku,high(ramend)
out sph,akku
ldi akku,low(ramend)
out spl,akku

mfg ihle

P.S. ich wünsche dir viel Spass beim Assembler Programmieren, so lernst du die Controller richtig kennen.

hegewald
23.01.2014, 07:47
Hallo Ihle,
danke für Deine Antwort!
Die LEDs liegen über 330 R an GND. Jetzt messe ich mal was an PB0 bzw. PB1
im LOW-Bereich noch ansteht......eigenartig da stehen noch 1,82 Volt an (Versorg. = 5,3V)
dann müssen die LEDS noch glimmen.
Ich habe doch zu Beginn das PORTB auf LOW gesetzt.

clr akku ; beide LEDs zu Beginn AUS
out PORTB,akku

DDRB hab ich zu Beginn auch auf FF gesetzt.

Entferne ich die beiden Pins von den LEDs, steigt die Spannung leicht auf 1,9 Volt an.
Wie gesagt, irgend was stimmt hier auf meinen neu erstellten Programmierbord von Conrad nicht!
Die Steckbrücken sind sehr lapperisch.
Zu Deiner Anmerkung zum Stackpointer hatte ich irgendwo gelesen, daß diese beim Tiny13 bzw. 2313
nicht nötig tut, ich hatte das nie gemacht. Hatte eine umfangreiche Software für einen Drehkran und
Containerkran von Märklin erstellt...und die läuft und läuft.
Aber ich werde es mal in diesen Code einbinden.

Ich lass von mir hören.

Grüße

Rolf

ihle
23.01.2014, 20:54
Hallo,

sieht ein wenig so aus als wäre der AVR überlastet, ich mach das immer so
27314
du kannst natürlich auch einen NPN Transistor nehmen, dann ist bei PB0=0 die LED aus
beim PNP ist die LED bei PB0=0 an. Der Strom den der AVR treiben muss liegt bei ca.280µA
die Strombelastung ist hier so gering, dass es auch bei einer ganzen LED Matrix nicht groß ins
Gewicht fällt.

Zum Stackpointer: Der ATiny13 hat ja gar kein RAM da wird alles über die Hardware gemacht
beim ATiny2313 wäre es meiner Meinung nach empfehlenswert den Stackpointer
zu Initialisieren, ich hab mal nichts gegensätzliches gefunden.
Ich hab noch nie ohne Stackpointer programmiert, ich weiß auch nicht ob
der Stackpointer automatisch angelegt wird wenn man es nicht manuell macht oder nicht.
Das liegt wahrscheinlich an meinem Ausbilder in der Schule Stackpointer vergessen 2 Noten schlechter.:(

mfg ihle

P.S. Ich habe ein gutes Buch speziell für AVR "Mikrocomputertechnik mit Controller der ATmel AVR RISK-Familie" vom Oldenburgverlag
ISBN 978-3-486-58016-7
da steht eigentlich alles drin was man als Grundlage braucht.

hegewald
24.01.2014, 06:57
Hallo Ihle,
ich hatte das Steckbrett von Conrad mit seinen zukäuflichen Verbindungs-Steckbrücken in Verdacht...
und so war es auch! Der GND-Pin 10 hatte mal Kontakt mal keinen.
Wie ich schon schrieb, große Sch.
Nun hab ich die Metallstifte an den Enden verzinnt, so daß sie jetzt strammer in den Federkontakten sitzen.
Jetzt sind die Led's auch dunkel.
Das erinnert mich an frühere Zeiten als TTL aufkam. Wenn da der GND fehlte, dann lief garnichts. Dann
kam C-MOS auf dem Markt. Wenn da der GND fehlte arbeiteten die Biester trotzdem nur völlig irrabel.
Diese Serie holte sich den Minus über Umwege rein (z.B. über die Eingänge)
Zum Stackpointer:

ldi akku,LOW(RAMEND) ;Studio4 hat dies ohne Fehler interpretiert
out SPL,akku

ldi akku,HIGH (RAMEND) ;hier zeigte es Error! Beim Mega8 ist das ok.
out SPH,Akku

Zu dem Buch...werde ich mal googeln!
Ich habe 978-3-645-65014-4 von Franzis speziell für den 2313
und von oldenbourg.de 978-3-486-58988-7
ein tolles Buch speziell über den Mega8.

So jetzt geht's weiter.

Grüße

Rolf

ihle
24.01.2014, 07:48
Hallo,

freut mich das es jetzt funktioniert.
Der ATiny2313 braucht nur den SPL, weil nur 128 Byte Ram zur Verfügung stehen
da wäre die letze RAM Adresse 0x80, bei ATmega8 ist die letzte RAM Adresse 0x045F.
Ich muss zugeben ich hab noch nie was mit dem 2313 gemacht ich nehme eigentlich nur
ATmega16 oder aufwärts, die kann ich mit dem JTAGMKII debuggen.

mfg ihle

hegewald
24.01.2014, 08:55
So jetzt läufts astrein!
Hier nochmal der überarbeitete Cod (ohne Stackp.)


; Projekt-Name: Projekt01 Datum: 24.01.2014

; Datei: Tiny2313-tasteprellen.asm

; AVR: Tiny2313-20PU

.INCLUDE "tn2313def.inc" ; Deklaration für Tiny2313

rjmp reset ; Reseteinsprung
.ORG OVF0addr ; Interrupt-Vektor
rjmp TIMER0_OVF ; Sprung zur ISR

.def akku =r16
.def temp17=r17 ; r17 zum Entprellen

#define sw1 PIND,PD0

reset:

;Timer0 initial.
ldi akku,(1<<CS02)
out TCCR0B,akku ; Prescale = 256
ldi akku,(1<<TOIE0)
out TIMSK,akku
sei

;Vorbereitung PORTB und PIND
ldi akku,(1<<PB0)|(1<<PB1)
out DDRB,akku ; PB0 + PB1=Output

clr akku ; alle Pins in r16=Low
out DDRD,akku ; Datenricht. PD0-PD6=Input

ldi akku,0x7F ; 0b0111.1111
out PORTD,akku ; PD0 bis PD6=PULLUP

ldi akku,0x00 ; beide LEDs zu Beginn AUS
out PORTB,akku

loop:
halt1:
sbic sw1 ; überspringe, wenn sw1=0
rjmp halt1
sbi PORTB,PB0 ; PB0=EIN
rcall prellen
;-----------------------------------------------------
halt2:
sbic sw1
rjmp halt2
sbi PORTB,PB1 ; PB1=EIN
rcall prellen
;-----------------------------------------------------
halt3:
sbic sw1
rjmp halt3
cbi PORTB,PB0 ; PB0=AUS
rcall prellen
;-----------------------------------------------------
halt4:
sbic sw1
rjmp halt4
cbi PORTB,PB1 ; PB1=AUS
rcall prellen
;-----------------------------------------------------
rjmp loop

prellen:
ldi temp17,0x0F
pause1:
tst temp17 ; teste r17 auf LOW, LOW<<Z-Bit=1
brne pause1 ; Verzweig. nach pause1,wenn Z=0
ret

TIMER0_OVF:
push r2 ; Kopie r2 auf Stack, danach SP-1
in r2,SREG ; Inhalt vom SREG nach r2
dec temp17 ; r17 - 1
out SREG,r2 ; Inhalt vom r2 nach SREG
pop r2 ; SP+1, danach vom Stack in r2 laden
reti
.EXIT