Forum: Mikrocontroller und Digitale Elektronik AVR Assembler Probleme mit Power Down Code


von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Guten Abend,
Es tut mir echt Leid euch schon wieder mit dem Thema Interrupts zu 
nerven, aber ich komme irgendwie nicht weiter und vielleicht erkennt 
jemand von euch ja auf Anhieb einen offensichtlichen Fehler. Also:
Dies ist mein Assembler Code um den ATtiny13A in den Power Down Modus zu 
bringen und per Low Level an INT0 wieder "aufzuwecken":
1
.org 0x0000         rjmp   RESET          ; Reset Handler
2
.org 0x0001         rjmp   EXT_INT0       ; IRQ0 Handler
3
.org 0x0002         rjmp   PCINT0         ; PCINT0 Handler
4
.org 0x0003         rjmp   TIM0_OVF       ; Timer0 Overflow Handler
5
.org 0x0004         rjmp   EE_RDY         ; EEPROM Ready Handler
6
.org 0x0005         rjmp   ANA_COMP       ; Analog Comparator Handler
7
.org 0x0006         rjmp   TIM0_COMPA     ; Timer0 CompareA Handler
8
.org 0x0007         rjmp   TIM0_COMPB     ; Timer0 CompareB Handler
9
.org 0x0008         rjmp   WATCHDOG       ; Watchdog Interrupt Handler
10
.org 0x0009         rjmp   ADC_R          ; ADC Conversion Handler
11
12
13
  
14
.org 0x000A
15
  ldi r16, 0xF0
16
  out DDRB, r16
17
  ldi r16, 0x0F
18
  out PORTB, r16
19
20
  ldi r16, 0b01000000
21
  out GIMSK, r16
22
  sei
23
  ldi r16, 0b01110000
24
  out MCUCR, r16
25
    sleep
26
27
28
EXT_INT0:
29
  ldi r16, 0xF0
30
  out DDRB, r16
31
  ldi r16, 0x0F
32
  out PORTB, r16
33
        sbi PINB, 4
34
ende:
35
        rjmp ende
Aber anstatt in den Power Down Modus zu kommen arbeitet der ATtiny das 
Programm einfach weiter ab. Ich habe schon einen externen Pull Up 
Widerstand an INT0 angeschlossen, aber das Ergebniss ist das Gleiche. 
Vielleicht habe ich irgendwas bei der Initialisierung vergessen? Vielen 
Dank schonmal

von Karl M. (Gast)


Lesenswert?

Hallo ,

Ja Fehler entdeckt du hast kein Hauptprogramm, und eine Interrupt 
Routine hast du auch nicht.

Frage Dich bitte,0 warum es ein RET und ein RETI gibt.

von Carl D. (jcw2)


Lesenswert?

Wo befindet sich das RETI?
Wo ist überhaupt der meiste Teil des Codes?
Wer soll sich an die Magic Numbers der Registerinhalte erinnern?
Gibt es so was wie Kommentare?

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Danke für die schnellen Antworten, der Code ist eigentlich länger ich 
dachte bloß ich erspare euch Sucharbeit wenn ich den kürze ^^
Aber ok, hier ist der ganze Code:
1
#define AnzahlSekunden (10)
2
#define AnzahlMinuten (0)
3
#define AnzahlStunden (0)
4
5
6
7
.org 0x0000         rjmp   RESET          ; Reset Handler
8
.org 0x0001         rjmp   EXT_INT0       ; IRQ0 Handler
9
.org 0x0002         rjmp   PCINT0         ; PCINT0 Handler
10
.org 0x0003         rjmp   TIM0_OVF       ; Timer0 Overflow Handler
11
.org 0x0004         rjmp   EE_RDY         ; EEPROM Ready Handler
12
.org 0x0005         rjmp   ANA_COMP       ; Analog Comparator Handler
13
.org 0x0006         rjmp   TIM0_COMPA     ; Timer0 CompareA Handler
14
.org 0x0007         rjmp   TIM0_COMPB     ; Timer0 CompareB Handler
15
.org 0x0008         rjmp   WATCHDOG       ; Watchdog Interrupt Handler
16
.org 0x0009         rjmp   ADC_R          ; ADC Conversion Handler
17
18
19
  
20
.org 0x000A
21
  ldi r16, 0xF0
22
  out DDRB, r16
23
  ldi r16, 0x0F
24
  out PORTB, r16
25
26
  ldi r16, 0b01000000
27
  out GIMSK, r16
28
  sei
29
  ldi r16, 0b01110000
30
  out MCUCR, r16
31
    sleep
32
33
34
EXT_INT0:
35
  ldi r16, 0xF0
36
  out DDRB, r16
37
  ldi r16, 0x0F
38
  out PORTB, r16
39
40
41
    ldi r16, 0x00
42
  ldi r17, 0x00
43
  ldi r18, 0x00
44
  ldi r19, 0x00
45
  ldi r20, 0x00
46
47
48
start:
49
  cpi r16, 0xFB
50
  breq weiter1
51
  nop
52
  nop
53
  nop
54
  nop
55
  nop
56
  nop
57
  nop
58
  nop
59
  nop
60
  nop
61
  nop
62
  nop
63
  nop
64
  nop
65
  nop
66
  inc r16
67
  rjmp start
68
69
70
weiter1:
71
  ldi r16, 0x01
72
  cpi r17, 0xF0
73
  breq weiter2
74
  nop
75
  nop
76
  nop
77
  nop
78
  nop
79
  nop
80
  nop
81
  nop
82
  nop
83
  nop
84
  nop
85
  inc r17
86
  rjmp start
87
88
89
weiter2:
90
  ldi r17, 0x00
91
  cpi r18, AnzahlSekunden
92
  breq weiter3
93
  nop
94
  nop
95
  nop
96
  nop
97
  nop
98
  nop
99
  nop
100
  inc r18
101
  rjmp start
102
103
104
weiter3:
105
  ldi r18, 0x3C
106
  cpi r19, AnzahlMinuten
107
  breq weiter4
108
  nop
109
  nop
110
  nop
111
  inc r19
112
  rjmp start
113
114
115
weiter4:
116
  ldi r19, 0x3C
117
  cpi r20, AnzahlStunden
118
  breq zeitende
119
  inc r20
120
  rjmp start
121
122
123
zeitende:
124
  sbi PINB, 4
125
126
127
ende:
128
  rjmp ende

von Ozvald K. (Gast)


Lesenswert?

...wenn das Dein ganzer Code ist, dann ist er falsch. Wo ist dein Reset 
Handler?

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Achso, zu der Idee mit dem reti Befehl:
muss ich dann nicht auch den Stack Pointer am Anfang initialisieren?
Und geht das nicht mit einem einfachen rjmp, wenn das Programm sowieso 
immer an der gleichen Stelle anfangen soll?
Außerdem war mein Problem doch das der Microcontroller gar nicht in den 
Power Down Modus kommt, und nicht das er nicht aus der Interruptroutine 
rauskommt.

@Ozvald K.:
Stimmt, danke für den Hinweis, habe den jetzt auf das Label "start:" 
springen lassen.

: Bearbeitet durch User
Beitrag #5942812 wurde vom Autor gelöscht.
von Ozvald K. (Gast)


Lesenswert?

Wackelkopf S. schrieb:
> .org 0x000A
>   ldi r16, 0xF0
>   out DDRB, r16
>   ldi r16, 0x0F
>   out PORTB, r16
>
>   ldi r16, 0b01000000
>   out GIMSK, r16
>   sei
>   ldi r16, 0b01110000
>   out MCUCR, r16
>     sleep

..und das wird nie ausgeführt

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

@Ozvald k. Wieso nicht? Es steht doch am Anfang des Programms

von Karl M. (Gast)


Lesenswert?

Wackelkopf S. schrieb:
> Ozvald k. Wieso nicht? Es steht doch am Anfang des Programms

nöö,

der µC springt den Resetvektor an und Verweigt dann nach RESET.

Es war schon richtig, das ist kein korrektes Programm!

Schreibe es richtig, mit Stack und auch allen vorhandenen Vektoren.

Dann verstehst Du evtl. wie es zu funktionieren hat!

von Herr M. (herrmueller)


Lesenswert?

Du musst doch jede Menge Fehlermeldungen vom Assembler bekommen, weil es 
die ganzen Interrupt Sprunziele nicht gibt - ausser EXT_INT0.

Die sollte man nicht einfach ignorieren und sich dann wundern, dass nix 
geht.

von Karl M. (Gast)


Lesenswert?

Siehe:
http://ww1.microchip.com/downloads/en/DeviceDoc/doc8126.pdf

S.45ff "9. Interrupts"

Insbesondere unter "9.1 Interrupt Vectors" die Beschreibung der 
Vektoren.

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Meinst du so?
1
#define AnzahlSekunden (10)
2
#define AnzahlMinuten (0)
3
#define AnzahlStunden (0)
4
5
6
7
.org 0x0000         rjmp   RESET          ; Reset Handler
8
.org 0x0001         rjmp   EXT_INT0       ; IRQ0 Handler
9
.org 0x0002         rjmp   RESET          ; PCINT0 Handler
10
.org 0x0003         rjmp   RESET          ; Timer0 Overflow Handler
11
.org 0x0004         rjmp   RESET          ; EEPROM Ready Handler
12
.org 0x0005         rjmp   RESET          ; Analog Comparator Handler
13
.org 0x0006         rjmp   RESET          ; Timer0 CompareA Handler
14
.org 0x0007         rjmp   RESET          ; Timer0 CompareB Handler
15
.org 0x0008         rjmp   RESET          ; Watchdog Interrupt Handler
16
.org 0x0009         rjmp   RESET          ; ADC Conversion Handler
17
18
19
  
20
RESET:
21
  ldi r16, 0xF0
22
  out DDRB, r16
23
  ldi r16, 0x0F
24
  out PORTB, r16
25
26
  ldi r16, 0b01000000
27
  out GIMSK, r16
28
  sei
29
  ldi r16, 0b01110000
30
  out MCUCR, r16
31
    sleep
32
33
34
EXT_INT0:
35
  ldi r16, 0xF0
36
  out DDRB, r16
37
  ldi r16, 0x0F
38
  out PORTB, r16
39
40
41
    ldi r16, 0x00
42
  ldi r17, 0x00
43
  ldi r18, 0x00
44
  ldi r19, 0x00
45
  ldi r20, 0x00
46
47
48
start:
49
  cpi r16, 0xFB
50
  breq weiter1
51
  nop
52
  nop
53
  nop
54
  nop
55
  nop
56
  nop
57
  nop
58
  nop
59
  nop
60
  nop
61
  nop
62
  nop
63
  nop
64
  nop
65
  nop
66
  inc r16
67
  rjmp start
68
69
70
weiter1:
71
  ldi r16, 0x01
72
  cpi r17, 0xF0
73
  breq weiter2
74
  nop
75
  nop
76
  nop
77
  nop
78
  nop
79
  nop
80
  nop
81
  nop
82
  nop
83
  nop
84
  nop
85
  inc r17
86
  rjmp start
87
88
89
weiter2:
90
  ldi r17, 0x00
91
  cpi r18, AnzahlSekunden
92
  breq weiter3
93
  nop
94
  nop
95
  nop
96
  nop
97
  nop
98
  nop
99
  nop
100
  inc r18
101
  rjmp start
102
103
104
weiter3:
105
  ldi r18, 0x3C
106
  cpi r19, AnzahlMinuten
107
  breq weiter4
108
  nop
109
  nop
110
  nop
111
  inc r19
112
  rjmp start
113
114
115
weiter4:
116
  ldi r19, 0x3C
117
  cpi r20, AnzahlStunden
118
  breq zeitende
119
  inc r20
120
  rjmp start
121
122
123
zeitende:
124
  sbi PINB, 4
125
126
127
ende:
128
  rjmp ende

von Carl D. (jcw2)


Lesenswert?

Wackelkopf S. schrieb:
> Achso, zu der Idee mit dem reti Befehl:
> muss ich dann nicht auch den Stack Pointer am Anfang initialisieren?

In weißer Voraussicht initialisieren die AVR's die Stackpointer auf das 
Ende des RAM. Es geht also ohne. Allerdings nur beim HW-Reset, nicht 
wenn nur nach 0x0000 gesprungen wird.

: Bearbeitet durch User
von Ozvald K. (Gast)


Lesenswert?

Wackelkopf S. schrieb:
> Es steht doch am Anfang des Programms

Dir fehlen offensichtlich Grundkenntnisse. Beim Einschalten führt der µC 
den ersten Befehl an der Adresse 0 aus. Dort hast du jetzt "springe auf 
Start Label". Einen Sprung auf deine Initialisierungsroutine ab 000A 
hast du nirgendwo.

von Ozvald K. (Gast)


Lesenswert?

ok, ich war langsam

von Karl M. (Gast)


Lesenswert?

Wackelkopf S. schrieb:
> out MCUCR, r16
>     sleep
... ?

> EXT_INT0:
>   ldi r16, 0xF0
>   out DDRB, r16
>   ldi r16, 0x0F
>   out PORTB, r16
>
>     ldi r16, 0x00
>   ldi r17, 0x00
>   ldi r18, 0x00
>   ldi r19, 0x00
>   ldi r20, 0x00
... ?

Ist nicht wirklich RICHTIG, warum liest Du die Dinge nicht durch?

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Ich muss dich enttäuschen, aber selbst im obrigen Code wird der 
Microcontroller nicht in den Power Down Modus versetzt, obwohl alle 
Interruptvektoren auf Reset zeigen...
(außer natürlich der INT0 ^^)

@Karl M. sorry, habe deine Antwort erst jetzt gesehen, ändert aber 
nichts daran das es immer noch nicht funktioniert ^^
Habe inzwischen ein reti davorgesetzt, aber genau da liegt der Punkt: Es 
geht mir nicht darum das der Microcontroller nicht aus der 
Interruptroutine wieder rauskommt, es geht mir darum das er nicht in den 
Power Save Modus reinwill und dabei hilft der reti Befehl gar nicht.

: Bearbeitet durch User
von H.Joachim S. (crazyhorse)


Lesenswert?

Warum bitte programmierst du in Assembler?
Wenn du das tust, MUSST du den Prozessor kennen und genau wissen wie er 
funktioniert, d.h. dort musst du anfangen und nicht irgendwelche Befehle 
aneinanderreihen...
Nimm Arduino, dann brauchst du dich um sowas nicht kümmern. Verstehst 
dann zwar immer noch nicht wie es funktioniert, aber es funktioniert 
halbwegs.

PS:
-eine Anreihung von vielen nops macht nur ganz selten Sinn
-label-Namen sollten was sinnvolles aussagen

: Bearbeitet durch User
von Wackelkopf S. (dangleheadturtle)


Lesenswert?

@H.Joachim S. Genau deshalb programmiere ich Assembler: Es ist viel 
präziser als Arduino und damit lernt man viel mehr über die 
Microcontroller als mit jeder anderen Programmiersprache

PS: Warum Antwortest du nicht auf die ursprüngliche Frage, anstatt vom 
Thema abzuweichen? Du scheinst dich ja recht gut auszukennen

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

Ich glaube der TO möchte den 13er einschlafen lassen, um auf den INT0 zu 
warten. Dazu braucht es eigentlich nur ein RETI im IntVector, und der 
13er würde nach der "minimal kurzen" ISR weiterlaufen in den 
Zeitvernichtungsteil. Eine bestimmte Zeit (Stunden) warten könnte man 
natürlich auch mit weniger Stromverbrauch hinbekommen. Aber davor steht 
erst mal die Aufgabe den AVR-Grundlagenartikel bezüglich Interrupts und 
Timer durchzuarbeiten.

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Und auch du konntest mir die ursprüngliche Frage nicht beantworten...
Aber ja, tatsächlich stehe ich noch recht am Anfang und würde mich über 
ein wenig Unterstützung sehr freuen...

von H.Joachim S. (crazyhorse)


Lesenswert?

Was ist denn für dich präziser? Dss du die Anzahl der nops selber 
abzählen kannst?
Du kannst nicht blind drauflos programmieren, wenn du nicht nichtmal 
weißt, wie und wo so ein leicht durchschaubares  Kerlchen wie der AVR 
startet, wie eine ISR auszusehen hat und wie der stack arbeitet.

Das alles musst du wissen, wenn du in Assembler programmieren willst.
Ohne dir zu nahe treten zu wollen - wo bitte hast du denn ein Problem 
bei dem PillePalle mit Arduino gehabt?

von Ozvald K. (Gast)


Lesenswert?

Wackelkopf S. schrieb:
> immer noch nicht funktioniert

Habe nicht gesagt dass der Rest deines Programms gut ist. :-)
Um mit Interrupts zu arbeiten muss man den Stack initialisieren. (aber 
nicht nur deswegen, CALL, POP, PUSH...) In der Interrupt Routine selbst 
muss man den Status Flag Register "retten" wenn man dort auch Befehle 
ausführt die die Flags ändern können. Bevor man die Int. Routine 
verlässt, muss man ihn wiederherstellen. (PUSH, POP)

Positioniere außerdem die Interrupt Routine ganz am Anfang oder ganz am 
Ende des Codes, sie darf nicht Bestandteil des Hauptprogramms sein, und 
beende sie mit RETI (Stack Pointer Initialisierung vorausgesetzt)

von H.Joachim S. (crazyhorse)


Lesenswert?

Wackelkopf S. schrieb:
> Warum Antwortest du nicht auf die ursprüngliche Frage, anstatt vom
> Thema abzuweichen?

Weil es keinen Sinn macht, dir zu erklären an der wievielten Ampel in 
Berlin du abbiegen sollst, weil du im Moment nicht nach Berlin findest.
Will sagen: beiss dich nicht an Kleinigkeiten fest, bevor du das 
Grundprinzip verstanden hast.

Nicht bös gemeint, wird schon. Fang aber an der richtigen STelle an.

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

@Ozvald K. Danke : )
Das ist konstruktive Kritik mit der ich etwas anfangen kann. Werde ich 
morgen auf jeden Fall ausprobieren.

von Herr M. (herrmueller)


Lesenswert?

Auch ich kann deine ursprüngliche Frage nicht beantworten...

Falls du willst, dass der Prozessor nach dem Interrupt noch weitermachen 
soll, musst du auch noch das Statusregister sichern.
Ausserdem solltest du Interrupts auch zulassen.

Woher weisst du eigentlich, dass der Controller nicht in den Sleep geht?
Warum sperrst du die Pullup Widerstände und versuchst sie dann doch zu 
setzen?

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

@H.Joachim S. Ich mochte Arduino nicht weil man nur bestimmte 
Interruptquellen nutzen kann und nicht genau weiß was der Controller 
tut.

: Bearbeitet durch User
von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Herr M. schrieb:
> Woher weisst du eigentlich, dass der Controller nicht in den Sleep geht?

Ich resette den Controller und messe Die Zeit bis die LED leuchtet. Das 
sind genau 10 Sekunden. Würde der Controller in den Power Down gehen 
dürfte die LED erst leuchten nachdem ich die Drahtbrücke an INT0 mit GND 
verbunden habe und dann noch 10 Sekunden abgelaufen sind.

von Carl D. (jcw2)


Lesenswert?

Wackelkopf S. schrieb:
> @H.Joachim S. Ich mochte Arduino nicht weil man nur bestimmte
> Interruptquellen nutzen kann und nicht genau weiß was der Controller
> tut.

Tu dir aber bitte den Gefallen vorne anzufangen. Und arbeite erst mal 
ein Tutorial durch, notfalls auch in Assembler. Da kannst du lernen, wie 
Interrupts und Timer funktionieren. Erwäge auch statt den Tiny13 
eventuell einen mega328 verbaut auf einem Arduino-Nano-Clone für ein 
paar €, der hat einen ISP Stecker und hat trotzdem noch ein paar Pins 
frei. Auch den kann man in Assembler programmieren. Der Sinn der Artikel 
in diesem Forum ist übrigens, dies nicht jedem neu erklären zu müssen. 
Bitte Versuch es mal. Wenn dann Fragen hochkommen und du dich auf 
Übungen im Tutorial beziehen kannst, dann wird man dir das sicher 
anrechnen.

von doofy (Gast)


Lesenswert?

Man, man, man, warum asm???

Schreib dein Programm in C, jage es ohne Optimierung durch den Compiler 
und schau was raus kommt.

Man, man, man, ...

von Wackelkopf S. (dangleheadturtle)


Lesenswert?

@Carl D.
Ich verstehe es total wenn ihr davon genervt seid Anfängern alles 
vorbuchstabieren zu müssen, aber ich möchte doch auch mal selbst 
Programme schreiben. Man sollte doch eben

H.Joachim S. schrieb:
> nicht irgendwelche Befehle aneinanderreihen.

Sondern selbst mitdenken und daraus eigene Ideen gewinnen.

Carl D. schrieb:
> Erwäge auch statt den Tiny13 eventuell einen mega328 verbaut auf einem
> Arduino-Nano-Clone für ein paar €

Reicht da nicht auch ein AVRISP Clon mit ISP Anschluss und einem 
verbauten ATmega328? Wollte bloss auch mal andere Controller 
programmieren ^^

von Herr M. (herrmueller)


Lesenswert?

Dadurch, dass du alle Pullup Widerstände gesperrt hast und den INT0 
Interrupt auf low Level gesetzt hast, vermute ich, dass der immer 
ausgelöst wird, vor allem, wenn der Eingang in der Luft hängt.

versuch es mal ohne Interrupt
1
.include "tn13def.inc"
2
3
 rjmp RESET 
4
  reti ; Int0-Interrupt               versehentliche Interrrupts
5
  reti ; PcInt0-Interrupt             werden mit reti sofort
6
  reti ; Timer/Counter 0 Overflow     beendet
7
  reti ; EEprom ready
8
  reti ; Analog Commarator
9
  reti ; Timer/Counter Compare Match A
10
  reti ; Timer/Counter Compare Match B
11
  reti ; Watchdog Timeout
12
  reti ; ADC Conversion complete
13
  reti
14
15
Reset:   
16
   ldi R16,low(Ramend) ; Stackpointer initialisieren
17
   out SPL,R16
18
19
   ldi r16,0xF0 ; Bit 0-3 Eingang
20
   out DDRB,r16
21
   ldi r16,0x0F ; Pullup für 0-3 anschalten
22
   out PORTB,r16
23
24
   clr r16 ; oder in r16,MCUCR  ; Control register holen
25
26
   sbr r16, (1<<SE)+(1<<SM1)+(0<<SM1)+(0<<ISC01)+(0<<ISC01) 
27
; Sleep Enable setzen - Powerdown mode - Int0 auf Low Level.
28
; ->Bezeichnungen verwenden, keine Bits. + oder | (oder)
29
30
   out MCUCR,r16  ; Sleep und INT0 low level
31
   sleep
32
33
Wach:    ; hier gehts nach dem Aufwachen weiter

: Bearbeitet durch User
von Wackelkopf S. (dangleheadturtle)


Lesenswert?

Also, ich habe jetzt noch mal ein bisschen mit dem Code rumgespielt, das 
Ergebnis war immer das gleiche. Dann bin ich auf die Idee gekommen das 
die Programmänderungen gar nicht am tiny ankommen, habe ein Programm 
geschrieben welches nichts tut und siehe da: Nach 10 Sekunden leuchtete 
die LED. Dann habe ich die Kommunikationsgeschwindigkeit auf 8kHz 
runtergeschraubt und es noch einmal versucht. Ich bekam folgende 
Fehlermeldung:

Verifying Flash...Failed! address=0x0000 expected=0x13 actual=0x00

Habe die ISP Clock wieder auf default gesetzt und nochmal programmiert:
Jetzt kommt wieder etwas am tiny an!
Das Programm funktioniert so wie ich es gerade habe, falls jemand 
Interesse hat kann ich das aktuelle Programm posten, ansonsten ist das 
Problem jetzt gelöst. Danke an alle die mir geholfen haben! Und an die 
die sagen das mein Programm eine Kathastrophe ist: Keine Sorge, es ist 
noch nicht fertig. Ich werde die nops auf jeden Fall durch einen 
vernünftigen Counter ersetzen und noch einen Abbruchknopf dranbauen.
MFG,
dangleheadturtle

von Peter D. (peda)


Lesenswert?

Carl D. schrieb:
> Tu dir aber bitte den Gefallen vorne anzufangen.

Dem kann ich nur zustimmen. Bringe das Programm erstmal überhaupt zum 
funktionieren. Das Stromsparen fügt man erst ganz zum Schluß hinzu.
Immer ein Schritt nach dem anderen und nicht viele Baustellen 
gleichzeitig.
Ich würde sogar dazu raten, erstmal ohne Interrupts nur mit Polling die 
Funktion zu erstellen. Und wenn das funktioniert, als 2. Schritt mit 
Interrupts.

Und wenn Du willst, daß jemand Dein Programm versteht, dann benutze 
keine magischen Zahlen, sondern die Interruptvektoren und Bitnamen aus 
dem Datenblatt.
Hier mal das Grundprinzip:
1
.include "tn13adef.inc"
2
        rjmp init
3
.org    INT0addr
4
        rjmp int0
5
int0:
6
; interrupt code
7
        reti
8
.org    INT_VECTORS_SIZE
9
init:
10
; init code
11
        ldi r16, 1<<WGM00 | 1<<WGM01 | 1<<COM0A0
12
        out TCCR0A, r16
13
main:
14
; main code
15
        rjmp main

Gerade in Assembler braucht man noch viel mehr Disziplin und Sorgfalt, 
als in Hochsprachen.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Wackelkopf S. schrieb:
> falls jemand
> Interesse hat kann ich das aktuelle Programm posten, ansonsten ist das
> Problem jetzt gelöst.

Es sollte DEIN Interesse sein, das aktuelle Programm zu posten, damit DU 
was lernst. Du tust nicht "uns" einen Gefallen, sondern DIR.

Deine Annahme, das dein Problem nun mit deinem nicht geposteten Code 
gelöst ist, ist .. mutig. Vielleicht sind ja da Besonderheiten und 
Nebeneffekte drin enthalten, die du gar nicht kennst und übersiehst?

Nicht alle Kommentare von Rückmeldungen mögen dir gefallen, und nicht 
alle Kommentatoren werden für den diplomatischen Dienst befähigt sein. 
Dennoch lernst eher DU was aus den Rückmeldungen, und nicht die 
Rückmelder.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Wackelkopf S. schrieb:
> @H.Joachim S. Ich mochte Arduino nicht weil man nur bestimmte
> Interruptquellen nutzen kann und nicht genau weiß was der Controller
> tut.

Ich verstehe, dass du einen Grund benötigst, um dich in den Assembler zu 
stürzen.
Aber deine Begründung/Annahme ist irrational.

Zumindest für die AVR Arduinos gilt:

1. Es gibt keine unerreichbaren Interruptquellen. Alle sind nutzbar!

2. Der komplette Arduino Wust liegt öffentlich aus. Es gibt keine 
Geheimnisse. Spätestens der mitgelieferte Disassembler zeigt dir das 
"Eingemachte".

Bitte nicht falsch verstehen!
Ich möchte dich nicht zu Arduino bekehren, oder dich von deinem ASM 
abbringen.

Das ist alles ok, nur eben nicht die Begründung, die ist sachlich 
falsch.

von Martin V. (oldmax)


Lesenswert?

Hi
Nun, nach wie vor ist Assembler kein totes Pferd, auch wenn sich 
professionelle Programmierer auf C bzw. hochsprachen berufen. Alles hat 
seine Berechtigung. Nebenbei sollte vielleicht mal gesagt werden, das in 
industriellen Steuerungen auch Programmierungen in Anweisungslisten 
befinden, die einer Assemblersprache ähnlich sind. Und nicht jeder, der 
hier hobby- oder berufsbedingt eine Programmiersprache benutzt, will nur 
C, sondern ist auch an anderen Sprachen interessiert. Also, nett, das es 
immer wieder Missionare gibt, aber wenn jemand Hilfe in Assembler 
möchte, dann gebt sie.
@Wackelkopf..
Vielleicht interessierst du dich hierfür
https://www.makerconnect.de/media/user/oldmax/PC%20und%20Mikrocontroller%20Teil%201%20und%202%20Stand%2026.07.2019.pdf
gruß oldmax

von Stefan F. (Gast)


Lesenswert?

Ich möchte noch ein weiteres Assembler Tutorial für den ATtiny13 
empfehlen:
http://stefanfrings.de/avr_workshop/index.html

von Einer K. (Gast)


Angehängte Dateien:

Lesenswert?

Martin V. schrieb:
> Also, nett, das es
> immer wieder Missionare gibt, aber wenn jemand Hilfe in Assembler
> möchte, dann gebt sie.

Das kann man auch verbinden.
Also ASM-Hilfe und Arduino-Missionar

Wie vielen bekannt ist, ist die Arduino Welt eher eine C++ Welt.
Aber dennoch ist es durchaus möglich dort Assembler einzubinden.

Um mal zu zeigen wie "einfach" das ist hab ich 3 Dateien in den Anhang 
gepackt.

Eine leere *.ino Datei.
Das möchte Arduino so, denn ohne *.ino geht nix.

Eine main.S Datei.
Diese bitte zu der leeren *.ino in den Ordner werfen.
Die *.S enthält den ganzen Assembler Stoff.
Es wird dort ein main Label erzeugt und global bekannt gemacht, damit 
der Linker befriedigt wird.
Ebenso eine ISR

Im main, wird PB5 auf Output gesetzt und Timer1 initialisiert.
Die Timer ISR toggled PB5
Es wird ein ca. 0,5Hz Rechteck aus gegeben.
Die LED an dem Pin blinkt in dem Takt vor sich hin.


Und zum Schluss die dritte Datei eine *.asm.
Sie ist das disassemblierte Kompilat.
In ihr kann man schön sehen, was Assembler/Kompiler und Linker daraus 
fabrizieren.

-----

Der Code ist rudimentär.
Und meine ASM Fähigkeiten im Grunde auch.

Es ist also sicher kein vorbildhafter Code.
Es soll nur zeigen, dass auch in Richtung ASM mit der Arduino IDE mehr 
möglich ist, als so mancher vermuten wird.

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.