Forum: Mikrocontroller und Digitale Elektronik Zur jeder Zeit der Programmlaufzeit, Tastendruck speichern


von ckrex (Gast)


Lesenswert?

Frohes Neues!

erstmal der code...

main.asm
1
.include "m16def.inc"
2
.include "init_def.inc"
3
4
5
6
INIT:
7
  ldi temp, 0xFF
8
  out DDRC, temp ;define Portc as output
9
  out DDRB, temp ; define PORTB as output
10
11
  ldi temp, 0x00
12
  out DDRD, temp ; define PORTD as input
13
  ldi temp, 0xFF
14
  out PORTD,   temp ;activate pull ups
15
16
  ldi r26, 0xFF  ;
17
  ldi r27, 0xFF  ;for wait
18
19
  ldi cnt, 20 ; load loop counter with 20
20
21
22
MAIN:
23
  rcall YELLOW_LED_ON
24
  
25
  rcall WAIT; wait
26
  rcall YELLOW_LED_OFF
27
  
28
  
29
  rcall lOW_WAIT
30
  ;rcall WAIT
31
  
32
  in temp, PIND; write PIND to temp
33
34
  sbrs temp, 0 ;skip if bit 0 in temp is cleared
35
  ;if there is some input
36
  ;execute LED ON
37
  ;else if there is no input, then do not activate led
38
  rcall RED_LED_ON
39
40
  rjmp MAIN ; jmp to MAIN label
41
42
  
43
44
LOW_WAIT: ;wait only 250 ms
45
  sbiw r27:r26, 1 ; sbiw takes 2 clocks
46
  brne LOW_WAIT    ;branch if not equal ; takes 2 clocks if condition is true
47
  ldi r26, 0xFF  ;set
48
  ldi r27, 0xFF  ;back
49
  ret
50
51
52
53
WAIT:
54
  ldi r26, 0xFF  ;set
55
  ldi r27, 0xFF  ;back
56
  
57
  dec cnt
58
  brne LOOPINNER_WAIT
59
  
60
  ldi cnt, 20 ;restore
61
  ret
62
  
63
  
64
LOOPINNER_WAIT:
65
  sbiw r27:r26, 1 ; sbiw takes 2 clocks
66
  brne LOOPINNER_WAIT    ;branch if not equal ; takes 2 clocks if condition is true
67
  rjmp WAIT
68
69
70
YELLOW_LED_ON:
71
  ldi temp, 0xFF
72
  out PORTB, temp
73
  ret  
74
75
76
YELLOW_LED_OFF:
77
  ldi temp, 0x00
78
  out PORTB, temp
79
  ret  
80
81
82
RED_LED_ON:
83
  ldi temp, 0xFF
84
  out PORTC, temp
85
  ret
init_def.inc
1
#ifndef _INIT_DEF_INC_
2
#define _INIT_DEF_INC_
3
4
.def temp = r16
5
.def cnt = r17
6
7
8
.org 0x0000        ; Adresse im 2er schritt ;Die Interruptvektortabelle beginnt bei 0x0000 
9
rjmp    MIN_INIT      ;1 POWER ON RESET 
10
.org 0x0002
11
reti  ;2 Int0-Interrupt 
12
.org 0x0004
13
reti  ;3 Int1-Interrupt   
14
.org 0x0006
15
reti          ;4 
16
.org 0x0008
17
reti          ;5 
18
.org 0x000a
19
reti          ;6 
20
.org 0x000c
21
reti          ;7 
22
.org 0x000e
23
reti          ;8 
24
.org 0x0010
25
reti          ;9 
26
.org 0x0012
27
reti          ;10 
28
.org 0x0014
29
reti          ;11 
30
.org 0x0016
31
reti          ;12 
32
.org 0x0018
33
reti          ;13 
34
.org 0x001a
35
reti          ;14 
36
.org 0x001c
37
reti          ;15 
38
.org 0x001e
39
reti          ;16 
40
.org 0x0020
41
reti          ;17 
42
.org 0x0022
43
reti          ;18 
44
.org 0x0024
45
reti          ;19 
46
.org 0x0026
47
reti          ;20
48
.org 0x0028
49
reti          ;21
50
51
52
MIN_INIT:            ;RESET Label 
53
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
54
  ldi temp, high(RAMEND)  ;Initialisierung des Stackpointers 
55
  out SPH, temp      ;erst das High - Byte 
56
  ldi temp, low(RAMEND) 
57
  out SPL, temp      ;dann das Low - Byte
58
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
59
60
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; nötig um alle pins an portc zu verwenden
61
62
  in temp,MCUCSR         ; Read MCUCSR
63
  ori      temp,1 << JTD        ; Set jtag disable flag
64
  out      MCUCSR, temp         ; Write MCUCSR
65
  out      MCUCSR, temp        ; and again as per datasheet 
66
67
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68
69
#endif
Wie man im Programm erkennen kann wird eine gelbe Led ca 5 Sekunden 
eingeschaltet (1mhz µController), dann wird für ca 0,25 Sekunden 
gewartet. Anschließend wird geprüft ob der nullte pin von portD auf 
Masse gezogen wurde. Ist dies der Fall, dann wird die rote Led 
angeschaltet. Wenn man den nullten pin von portd mit Masse verbindet 
während die Überprüfung des Portregisters PIND nicht abgefragt wird und 
man dann die Verbindung zur Masse unterbricht, dann wird nicht 
gespeichert, dass der pin währenddessen jemals mit Masse verbunden war. 
Nun zu meiner Frage: Hat der µController eine Art Puffer der speichern 
kann, dass der pin zu jeder zeit des Programms mit Masse verbunden war? 
Theoretisch könnte man das irgendwie hardwaremäßig mit einem 
selbsthalterelai realisieren, dies möchte/kann ich aber nicht.

Gruß

von Achwas (Gast)


Lesenswert?

Erzähl doch lieber kurz und nachvollziehbar, was das Programm so
alles machen soll - und was es nicht macht.

Sich in den Code ohne Beschreibung einzulesen, macht selten Spaß.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Noch Restalkohol im Blut vom Silvester Feiern?

von Max D. (max_d)


Lesenswert?

Das macht man normalerweise indem man öfter abtastet.
Der User braucht ja eine gewisse Zeit um den Knopf wieder loszulassen 
und in dieser Zeit muss man mindestens einmal nachsehen.
Bei sehr speziellen Lösungen kann man das auch per Interrupt lösen.

von Jörg E. (jackfritt)


Lesenswert?

Ohne Wait arbeiten?
Z.b. Timer verwenden der in der ISR ständig eine Variable hochzählt und 
den Portpin abfragt. Die Variable nutzt du als Zeitwert für deine LED 
ein und Ausschaltvorgänge.
Schau mal bei Peter Danneggers entprellroutinen, da is auch ne asm 
Version und ich meine mit Timer.

von ckrex (Gast)


Lesenswert?

Das Programm das dort zu sehen ist, wurde nur zu Testzwecken erstellt um 
eine Lösung für mein oben gennantes Problem zu finden. Ursprünglich bin 
ich dabei eine Ampelschaltung zu programmieren.

>Das macht man normalerweise indem man öfter abtastet.


Achja? Ich meine das ist z.B. bei der Bibliothek ncurses-dev nicht der 
Fall. Ich kann mich aber auch irren. Da konnte man nämlich in einer 
Schleife hängen die z.B. nur wartet. Während der Computer diese Schleife 
ausführte und der User auf der Tastatur eine Taste drückte, dann wurde 
der Tastendruck gespeichert und bei der nächten Auswertung des 
"Tastaturpuffers" wurde der Tastendruck von dem Computer registriert.
UND das ganze mit nur einer Abfrage. Das möchte ich auch am liebsten für 
den µController realisieren.

>Das macht man normalerweise indem man öfter abtastet.
>Der User braucht ja eine gewisse Zeit um den Knopf wieder loszulassen
>und in dieser Zeit muss man mindestens einmal nachsehen.

Wäre möglich, aber nicht ideal.
Außerdem würde dafür einfach viel Rechenzeit bei drauf gehen wenn ich 
immer diesen Pin abfrage.


>Bei sehr speziellen Lösungen kann man das auch per Interrupt lösen.
Ich möchte es nicht mit einem interrupt lösen. Das hab ich wohl 
vergessen in meine ersten Post zu erwähnen.


>Noch Restalkohol im Blut vom Silvester Feiern?

Nein. Und selber? :)

Gruß

von Noch einer (Gast)


Lesenswert?

>Ich möchte es nicht mit einem interrupt lösen.

Ich eigentlich auch nicht. Mit Interrupts wird es aber einfacher als 
ohne.

In deinem Beispiel müsstest du ja in der Warteschleife den Taster 
abfragen. Ampel mit einem Taster ginge vielleicht noch. Sobald du 
Programme schreibst, die 5 Dinge gleichzeitig machen, wird das Programm 
zu unübersichtlich - du findest die Fehler nicht mehr.

von Jörg E. (jackfritt)


Lesenswert?

Was meinst du denn wieviel Rechenzeit in deiner Wait Routine draufgeht?

von Peter D. (peda)


Lesenswert?

ckrex schrieb:
> Nun zu meiner Frage: Hat der µController eine Art Puffer der speichern
> kann, dass der pin zu jeder zeit des Programms mit Masse verbunden war?

Der Trick an einem MC ist, er macht nur genau das, was man programmiert 
hat und er macht es genau und nur dann, wenn der entsprechende Code 
ausgeführt wird.
Anders gesagt, von alleine macht er garnichts, Du must es programmieren.

Z.B. einen Ereignispuffer, indem man einen Timerinterrupt aufsetzt, der 
zyklisch auf das Ereignis abfragt und den Erfolg in einer Variablen 
ablegt.

von ckrex (Gast)


Lesenswert?

>Ampel mit einem Taster ginge vielleicht noch. Sobald du
>Programme schreibst, die 5 Dinge gleichzeitig machen, wird das Programm
>zu unübersichtlich - du findest die Fehler nicht mehr.

Der Wille ist ALLES! Und der Glaube.
Insgesamt habe ich 2 Taster und 2 reed kontakte die quasi eine 
induktionschleife darstellen sollen. Also insgesamt 4 Schalter.

Ich werde das ganze nun anders implementiren als gedacht.
Nämlich über mehrfaches Abfragen des Eingangsports.
Der Thread kann von mir aus geschlossen werden ;)

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.