Mein Programm ist ein Anfängerprogramm, ich will neben c auch noch
assambler lernen, aber ich habe da startschwierigkeiten. kann mir jemand
den/die Fehler nennen die ich mache?
.include "m162def.inc"
.org 0x022
rjmp leuchte
.dseg
schritt: .byte 1
seconds: .byte 1
parts: .byte 1
.def save_sreg = r0
.def iwr0 = r18
.def iwr1 = r19
.def temp = r6
.def wr0 = r17
.def Leuchter = r16
.cseg
init:
ldi wr0, 0xFF
out DDRB, wr0
ldi wr0, 0x00
out PORTB, wr0
ldi wr0, 0xFF
out PORTD, wr0
ldi wr0, 1<<CS02 | 1<<CS00
out TCCR0, wr0
ldi wr0, 1<<TOIE0 ;enable timer interrupt
out TIMSK, wr0
ldi Leuchter, 0x00
out PORTB, Leuchter
ldi iwr0, 0x00
ldi iwr1, 0x00
sei
main:
rjmp main
leuchte:
inc iwr0
cpi iwr0, 4
breq rollen
reti
rollen:
ldi iwr0, 0
in Leuchter, PORTB
inc Leuchter
out PORTB, Leuchter
reti
ps. Ja ich habe im Simulator gedebuggt... und das "AVR Simulator:
Uninitialized stack pointer used at 0x000f" Spuckt er bei jedem OVF
aus...
Vielen Dank für Eure hilfe
Hallo,
ist das das komplette Programm?
Du startest mit .org 0x0022 rjmp leuchte
Der AVR startet nach Reset an Adresse 0.
Ich vermisste den rjmp init (oder wohin auch immer) an Adresse 0.
Die fehlende Stack-Initialisierung wurde ja schon agesprochen.
Günstiger (weniger für das Programm als für die Leser hier ;)) ist es
außerdem, mehr Symbole zu benutzen.
Statt .org 0x0022 den Namen der IRQ-Adresse, zu finden in der
m162def.inc
Also so z.B.
rjmp init ; Auf Adresse 0 -> Sprung zum Start bei Reset
.org OVF0addr
rjmp leuchte
Vorteilhaft ist es dann auch, den Vektor-Bereich komplett auszusparen
(wenn man die paar Bytes Flash nicht dringend braucht) und mit
.cseg
.org INT_VECTORS_SIZE ; erste Adresse nach den IRQ-Vektoren ->
m162def.inc
Init:
ldi wr0, 0xFF
usw. usw.
weiterzumachen.
Gruß aus Berlin
Michael
Hi
@Markus und die anderen Assemblerbeginner
Gewöhnt euch einfach mal an ,die Interruptsprungtabelle wie im
Datenblatt zu machen (bei etlichen PDFs kann man die sogar
rauskopieren). Das Programm wird dadurch wesentlich übersichtlicher und
man vermeidet etlichen Anfängerstress. Mit den '.org xxx' spart man
prinzipiell keinen Speicherplatz (bestenfalls etwas Schreibarbeit). Zur
Not kann man die nicht benutzten Interruptvektoren auf ein gemeinsames
Ziel umleiten.
Beispiel
rjmp RESET
rjmp EXT_INT0
rjmp dummy ;PC_INT0
rjmp dummy ;TIM0_OVF
rjmp dummy ;EE_RDY
...
RESET: Stackinitialisierung
...
dummy: reti
EXT_INT0: Interruptroutine
reti
;PC_INT0: reti
;TIM0_OVF: reti
;EE_RDY: reti
...
Bei einen neuen Interrupt brauchen nur die Auskommentierungen entfernt
werden.
MfG Spess
> aber wie mach ich das jetzt, dass die leds bei 0x00 aus sind und bei> 0xFF an sind?
- 'elektrische' Lösung: anders anschließen
- software Lösung: den einschalt wert vor dem 'out' umdrehen -- mit
'com' wahrscheinlich (mit ~ in C)
Auf dem stk-500 sind die LEDs zwischen den µC-Pin und Vcc angeschlossen,
wahrscheinlich, weil:
- die alten AVRs (at90s...) nicht genug Strom für LEDs liefern, aber
'sinken' , also quasi 'ableiten' können
- das Board verschiedene Spannungen für die µCs unterstützt, und so die
LEDs immer gleich hell leuchten.
also: Die LEDs gehen an, wenn man 0 augibt, gewöhn dich dran, ist doch
nicht so tragisch ;)
hth. Jörg
Hi
Worin liegt das Problem.
Einzelne Leds Schalten: 'cbi PortB,0' statt 'sbi PortB,0
Ganzes Byte ausgeben: com r16
Out PortB,r16
Indeinem Programm: ldi r16,$FF
out PortB,r16 ; alle Leds aus
etwas später: in r16,PortB
dec r16
out PortB,r16
übrigens ergibt das kein 'rollen' sondern eine binär Darstellung von
0..255
MfG Spess