Forum: Mikrocontroller und Digitale Elektronik Attiny10 asm test


von Andreas B. (bitverdreher)


Lesenswert?

Hi,
ich habe hier ein kleines Programm, das einfach nur mit einem Taster 
einen Ausgang toggeln soll. Das ist meine erste ASM Übung auf dem 
Tiny10.
Leider tut sich nichts. Die LED am Ausgang (über 1k an PB2) bleibt immer 
an. (Übersetzt mit avra)
1
;-----------------------------------------------------------------------------
2
;* Testprogramm fuer ATtiny10     
3
;*
4
;* PB0 = Ein Taster
5
;* PB1 = x Taster
6
;* PB2 = Gate mosfet
7
8
;-----------------------------------------------------------------------------
9
10
.include "tn10def.inc"  ; Definitionsdatei fuer den Prozessortyp
11
; Reset und Interruptvectoren ;Adr. Beschreibung
12
13
.org 0
14
   rjmp  init  ; 0   Power On Reset
15
.org  INT0addr  ; External Interrupt Request 0
16
   reti
17
.org  PCI0addr  ; Pin Change Interrupt Request 0
18
   reti
19
.org  ICP0addr  ; Timer/Counter0 Input Capture
20
   reti
21
.org  OVF0addr  ; Timer/Counter0 Overflow
22
   rjmp  timer0_Overflow
23
.org  OC0Aaddr  ; Timer/Counter Compare Match A
24
   reti
25
.org  OC0Baddr  ; Timer/Counter Compare Match B
26
   reti
27
.org  ACIaddr   ; Analog Comparator
28
   reti
29
.org  WDTaddr   ; Watchdog Time-out
30
   rjmp  init
31
.org  VLMaddr   ; Vcc Voltage Level Monitor
32
   reti
33
.org  ADCCaddr  ; ADC Conversion Complete
34
   reti
35
36
37
; defines
38
;-----------------------------------------------------------------------------
39
.def  leds              = r16
40
.def  rTEMP             = r17
41
42
.def  save_sreg         = r18
43
.def  iwr0              = r19
44
.def  iwr1              = r20
45
 
46
.def  key_old           = r21
47
.def  key_state         = r22
48
.def  key_press         = r23
49
 
50
 
51
;-----------------------------------------------------------------------------
52
timer0_Overflow:                 ; IRQ Timer0 overflow
53
      in     save_sreg, SREG
54
55
get8key:                         ;/old      state     iwr1      iwr0
56
      mov    iwr0, key_old       ;00110011  10101010            00110011
57
      in     key_old, PORTB      ;11110000
58
      eor    iwr0, key_old       ;                              11000011
59
      com    key_old             ;00001111
60
      mov    iwr1, key_state     ;                    10101010
61
      or     key_state, iwr0     ;          11101011
62
      and    iwr0, key_old       ;                              00000011
63
      eor    key_state, iwr0     ;          11101000
64
      and    iwr1, iwr0          ;                    00000010
65
      or     key_press, iwr1     ;store key press detect
66
;
67
;        insert other timer functions here
68
;
69
      out    SREG, save_sreg
70
      reti
71
72
;-----------------------------------------------------------------------------
73
74
; Start, Power On, Reset
75
init:
76
   ; Stackpointer initialisieren
77
   ldi     rTemp, HIGH(RAMEND)
78
   out     SPH, rTemp
79
   ldi     rTemp, LOW(RAMEND)     
80
   out     SPL, rTemp
81
82
;; Clock source 128kHz
83
   ldi rTEMP, 0xD8
84
   out CCP, rTEMP                ; Configuration Change Protection Register
85
   ldi rTEMP, 0x01
86
   out CLKMSR, rTEMP         
87
88
;; Clock dividier 1
89
   ldi rTEMP, 0xD8
90
   out CCP, rTEMP                ; Configuration Change Protection Register
91
   ldi rTEMP, 0x00
92
   out CLKPSR, rTEMP
93
94
;; Init-Code
95
   ldi rTEMP, 1<<PB2
96
   out DDRB, rTEMP               ; B2 als Ausgang -> Mosfet
97
   ldi rTemp, 1<<PB0 | 1<<PB1
98
   out PORTB, rTEMP              ; Pullup an PB0 und PB1 
99
100
   ldi rTEMP, 1<<CS02 | 1<<CS00  ; divide by 1024 * 256
101
   out TCCR0B, rTEMP 
102
   ldi rTEMP, 1<<TOIE0           ; enable timer interrupt
103
   out TIMSK0, rTEMP
104
105
   clr key_old
106
   clr key_state
107
   clr key_press
108
   ldi leds, 0xFF
109
110
111
112
main: 
113
   cli
114
   eor leds, key_press           ; toggle correspondent LEDs if key pressed
115
   clr key_press                 ; clear, if key press action done
116
   rol leds                      ; PB1 (switch) to PB2 (mosfet)
117
   andi leds, 1<<PB2             ; filtert PortB2 
118
   sei
119
   out PORTB, leds
120
   rjmp main

Hat jemand eine Idee, was hier falsch läuft?

Gruß
Andreas

von Karl H. (kbuchegg)


Lesenswert?

Andreas B. schrieb:

> Das ist meine erste ASM Übung auf dem
> Tiny10.
> Leider tut sich nichts. Die LED am Ausgang (über 1k an PB2) bleibt immer
> an. (Übersetzt mit avra)

> Hat jemand eine Idee, was hier falsch läuft?

Wie wärs wenn du erst mal mit etwas wesentlich einfacherem anfangen 
würdest?
Damit dieser Code das tut, was du beabsichtigst, müssen schon mal viele 
Dinge stimmen. Genau das mündet gerade bei Neulingen, die naturgemäss 
keine Erfahrung haben, regelmässig darin, dass eben nichts funktioniert.

Seine ersten Schritte macht man nicht beim New-York Marathon, sondern 
indem man von der Mama zum Sofa 'balanziert'. Und genau dasselbe gilt 
auch in der Programmierung. Seine ersten Schritte und die ersten 
Erfahrungen sammelt man nicht mit Programmen, bei denen 78 
Detailprobleme korrekt gelöst werden müssen, sondern indem man eine LED 
einschaltet. LED ausschaltet. LED blinken lässt. sontige LED Spielchen. 
Und erst dann kommen erst mal Taster auf die Bildfläche. Wobei man auch 
nicht gleich mit der Erkennung eines Tastendrucks anfängt, sondern zb 
eine LED bei gedrücktem Taster leuchten und bei nicht gedrücktem Taster 
nicht leuchten lässt. Lezteres ist nämlich deutlich einfacher als eine 
Tasten-Flankenerkennung und Entprellung.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Wie wärs wenn du erst mal mit etwas wesentlich einfacherem anfangen
> würdest?

Das hat dann auch den Vorteil, dass man ein so simples Programm hat, 
dass man sich leicht davon überzeugen kann, dass er korrekt ist. Was 
insofern wichtig ist, als man damit dann auch Fehler in der Toolchain 
bzw. in der Hardware detektieren kann. Denn gerade beim allerersten 
Programm steht ja auch noch die spannende Frage im Raum: Funktionieren 
meine Tools überhaupt, die das Programm in den µC übertragen? Läuft der 
µC überhaupt?

Technische Systeme nimmt man schrittweise in Betrieb. Die Idee dahinter 
ist es, möglichst wenig potentielle Fehlermöglichkeiten zu haben. 
Funktionierts nicht, dann hat man daher auch nur wenige Dinge, die man 
überprüfen muss. Je mehr mögliche Fehlerquellen es gibt, desto 
schwieriger ist es auch, auszusortieren welcher Fehler eigentlich das 
Funktionieren verhindert. Systematisches Vorgehen ist das A und O in der 
Technik.

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

> Clock source 128kHz

>ldi rTEMP, 1<<CS02 | 1<<CS00  ; divide by 1024 * 256

Falls ich mich nicht verrechnet habe, macht das einen Overflowinterrupt 
in 524,30 s.

MfG Spess

von Andreas B. (bitverdreher)


Lesenswert?

Karl Heinz schrieb:

> Wie wärs wenn du erst mal mit etwas wesentlich einfacherem anfangen
> würdest?

Na ja, die Entprellung ist von Peda. Die sollte ja so funktionieren. 
Ansonsten ist das Programm ja nicht allzu kompliziert. Ich mache da wohl 
irgendeinen ziemlich blöden Denkfehler. Mit größeren AVR Controllern in 
C habe ich ja schon einiges erfolgreich programmiert. "Nur" ASM und 
Tiny10 ist neu.
Aber Du hast recht. Ich sollte mal einfach mal den Eingang abfragen und 
danach die LED schalten. Dann kommt vielleicht die Erleuchtung.

Spess: Sorry, der Kommentar war Mist. Der Teiler ist 1024.
Somit sollte bei 128Khz Takt ein Clock von 125Hz ergeben.

Gruß
Andreas

von spess53 (Gast)


Lesenswert?

Hi

>Spess: Sorry, der Kommentar war Mist. Der Teiler ist 1024.
>Somit sollte bei 128Khz Takt ein Clock von 125Hz ergeben.

Nein. Das ist ein 16-Bit-Timer. Der Overflow kommt nach

1024*65536/128000s = *524,272*s. Damit wird ein Tastendruck nach ca. 
2100s festgestellt.

MfG Spess

von Ziegenpeter (Gast)


Lesenswert?

Andreas B. schrieb:
> in     key_old, PORTB

müsste das nicht
1
in     key_old, PINB
heissen

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Hallo!

Andreas B. schrieb:
>    ldi rTemp, 1<<PB0 | 1<<PB1
>    out PORTB, rTEMP              ; Pullup an PB0 und PB1

Diese beiden Zeilen bleiben beim ATtiny10 ohne Wirkung.

Der kleine Floh ist in mancher Hinsicht recht modern: er besitzt ein 
eigenes Register für die Pullups: PUEB. Also:
1
ldi rTemp, 1<<PUEB0 | 1<<PUEB1
2
out PUEB, rTEMP              ; Pullup an PB0 und PB1

Grüße
Markus

von Andreas B. (bitverdreher)


Lesenswert?

spess53 schrieb:
>
> Nein. Das ist ein 16-Bit-Timer. Der Overflow kommt nach
>
Du hast Recht. Irgendwie gehe ich davon aus, daß Timer 0 immer ein 8-Bit 
Timer ist.

Ziegenpeter schrieb:
> müsste das nichtin     key_old, PINB heissen
Aua, da muß ich mich irgendwie vertippt haben.

Markus Weber schrieb:
> Der kleine Floh ist in mancher Hinsicht recht modern: er besitzt ein
> eigenes Register für die Pullups: PUEB. Also:
> ldi rTemp, 1<<PUEB0 | 1<<PUEB1
> out PUEB, rTEMP              ; Pullup an PB0 und PB1
Das war mir völlig neu.

Danke an alle!
Ich werde jetzt doch mal schrittweise drangehen wie Karl-Heinz empfohlen 
hatte. Bei den Tiny10 und ASM gibt es doch mehr Fallen, als ich gedacht 
habe. Das Datenblatt überfliegen, reicht hier offensichtlich nicht. Da 
ist doch einiges anders als bei den großen AVRs.

Gruß
Andreas

von Andreas B. (bitverdreher)


Lesenswert?

Hallo,
für die Nachwelt noch die überarbeitete Version. Ich hatte auch noch 
einige Logikfehler drin.
Es handelt sich hier schlicht um einen entprellten Taster mit Flipflop 
Funktion.
Die ganze Maskiererei ist so nicht unbedingt notwendig. Ich habe es 
trotzdem so gemacht, um Seiteneffekte auszuschließen,falls noch 
Erweiterungen hinzukommen sollten.
Interessant finde ich bei diesem Tiny daß man mit aktivierten Pullup den 
OUT auf 0 setzen kann. Eine schöne Möglichkeit, die Batterie leer zu 
machen. ;-)
1
;-----------------------------------------------------------------------------
2
;* Switcher for ATtiny10     
3
;*
4
;* PB0 = Taster
5
;* PB1 = frei
6
;* PB2 = Gate mosfet
7
;*
8
;*
9
;-----------------------------------------------------------------------------
10
11
.include "tn10def.inc"  ; Definitionsdatei fuer den Prozessortyp
12
; Reset und Interruptvectoren ;Adr. Beschreibung
13
14
.org 0
15
   rjmp  init  ; 0   Power On Reset
16
.org  INT0addr  ; External Interrupt Request 0
17
   reti
18
.org  PCI0addr  ; Pin Change Interrupt Request 0
19
   reti
20
.org  ICP0addr  ; Timer/Counter0 Input Capture
21
   reti
22
.org  OVF0addr  ; Timer/Counter0 Overflow
23
   RETI
24
.org  OC0Aaddr  ; Timer/Counter Compare Match A
25
   rjmp  timer0_Comp_A
26
.org  OC0Baddr  ; Timer/Counter Compare Match B
27
   reti
28
.org  ACIaddr   ; Analog Comparator
29
   reti
30
.org  WDTaddr   ; Watchdog Time-out
31
   rjmp  init
32
.org  VLMaddr   ; Vcc Voltage Level Monitor
33
   reti
34
.org  ADCCaddr  ; ADC Conversion Complete
35
   reti
36
37
38
; defines
39
;-----------------------------------------------------------------------------
40
.def  save_sreg         = r16
41
.def  iwr0              = r17
42
.def  iwr1              = r18
43
 
44
.def  key_old           = r19
45
.def  key_state         = r20
46
.def  key_press         = r21
47
 
48
.def  led2              = r22
49
.def  rTEMP             = r23
50
51
;-----------------------------------------------------------------------------
52
timer0_Comp_A:                   ; IRQ Timer0 compare match A
53
      in     save_sreg, SREG
54
55
get8key:                         ;/old      state     iwr1      iwr0
56
      mov    iwr0, key_old       ;00110011  10101010            00110011
57
      in     key_old, PINB       ;11110000
58
      eor    iwr0, key_old       ;                              11000011
59
      com    key_old             ;00001111
60
      mov    iwr1, key_state     ;                    10101010
61
      or     key_state, iwr0     ;          11101011
62
      and    iwr0, key_old       ;                              00000011
63
      eor    key_state, iwr0     ;          11101000
64
      and    iwr1, iwr0          ;                    00000010
65
      or     key_press, iwr1     ;store key press detect
66
      out    SREG, save_sreg
67
      reti
68
;
69
;-----------------------------------------------------------------------------
70
71
; Start, Power On, Reset
72
init:
73
   ; Stackpointer initialisieren
74
   ldi rTEMP, HIGH(RAMEND)
75
   out SPH, rTEMP
76
   ldi rTEMP, LOW(RAMEND)     
77
   out SPL, rTEMP
78
79
; Clock source 8MHz (128kHz)
80
   ldi rTEMP, 0xD8
81
   out CCP, rTEMP                ; Configuration Change Protection Register
82
   ldi rTEMP, 0x01               ; (0x01)
83
   out CLKMSR, rTEMP         
84
85
;; Clock dividier 1
86
   ldi rTEMP, 0xD8
87
   out CCP, rTEMP                ; Configuration Change Protection Register
88
   ldi rTEMP, 0x00
89
   out CLKPSR, rTEMP
90
91
;; Init-Code
92
   ldi rTEMP, 1<<PB2
93
   out DDRB, rTEMP               ; B2 als Ausgang -> Mosfet
94
95
   ldi rTEMP, 1<<PUEB0
96
   out PUEB, rTEMP               ; Pullup an PB0
97
98
   ldi rTEMP, 1<<CS00 | 1<<WGM02 ; clock divide by 1 + CTC mode A
99
   out TCCR0B, rTEMP 
100
101
   ldi rTEMP, 0x80
102
   out OCR0AH, rTEMP 
103
   ldi rTEMP, 0xFF 
104
   out OCR0AL, rTEMP             ; load timer with 0x80FF
105
106
   ldi rTEMP, 1<<OCIE0A          ; enable timer compare A interrupt 
107
   out TIMSK0, rTEMP
108
109
   clr key_old
110
   clr key_state
111
   clr key_press
112
113
main: 
114
   cli
115
   ldi rTEMP, 0x01               ; mask PB0
116
   and rTEMP, key_press          ; toggle correspondent LEDs if key pressed
117
   clr key_press                 ; clear, if key press action done
118
   lsl rTEMP                      
119
   lsl rTEMP                     ; shift PB0 (switch) to PB2 position
120
   andi rTEMP, 1<<PB2            ; mask PB2 position
121
   eor rTEMP, led2               ; switch PB2 status              
122
   andi rTemp, 1<<PB2            ; mask PB2 position
123
   mov led2, rTEMP               ; store PB2 status 
124
   out PORTB, rTEMP
125
   sei
126
   rjmp main

Gruß
Andreas

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Danke für das Update! :-)

Andreas B. schrieb:
> Interessant finde ich bei diesem Tiny daß man mit aktivierten Pullup den
> OUT auf 0 setzen kann. Eine schöne Möglichkeit, die Batterie leer zu
> machen. ;-)

Geht das wirklich? Also, ist der Pullup dann wirklich auch dann aktiv, 
wenn das Pin auf Ausgang geschaltet ist? Ich hab das nie getestet, wär 
aber irgendwie lustig. :-) Der zusätzliche Stromverbrauch hält sich 
allerdings in Grenzen, dürften zwischen 100 und 200 µA je Pin sein.

Sinn des PUEB-Registers ist eigentlich, das Umschalten von Eingang mit 
Pullup und Ausgang 0 V in einem Takt zu ermöglichen. Das geht mit der 
älteren Architektur nämlich nicht.

von (prx) A. K. (prx)


Lesenswert?

Markus Weber schrieb:
> Geht das wirklich? Also, ist der Pullup dann wirklich auch dann aktiv,
> wenn das Pin auf Ausgang geschaltet ist?

Auch der ATtiny841 hat diese neue Portstruktur mit separater 
Pullup-Steuerung. Klar, braucht Strom wenn man das am Ausgang macht. 
Aber das tut auch ein externes Signal, dass einen mit Pullup versehenen 
Eingang runterzieht.

Ist halt einfach nur anders als gewohnt und macht Anpassungen bei 
Portierung erforderlich.

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

Markus Weber schrieb:
> Geht das wirklich? Also, ist der Pullup dann wirklich auch dann aktiv,
> wenn das Pin auf Ausgang geschaltet ist?

Ich habe es nicht getestet, aber im Datenblatt wird davor gewarnt. (not 
recommended). Steht auf Seite 42 (jetzt im Ernst. ;-)
Wenn man 10k für den Pullup rechnet, sollten es eher 300 µA sein.

Gruß
Andreas

von (prx) A. K. (prx)


Lesenswert?

Andreas B. schrieb:
> Wenn man 10k für den Pullup rechnet, sollten es eher 300 µA sein.

20-50K.

> aber im Datenblatt wird davor gewarnt

Würde das nicht so sehr als Warnung denn als Hinweis betrachten. Kostet 
halt Strom, aber das wars auch.

: Bearbeitet durch User
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.