Forum: Mikrocontroller und Digitale Elektronik Programm Funktioniert nicht


von Markus (Gast)


Lesenswert?

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

von fnah (Gast)


Lesenswert?


von Michael U. (Gast)


Lesenswert?

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

von Maxim (Gast)


Lesenswert?

Ach Mist, genau den Fehler habe ich heute in der Schule gemacht und mich 
gewundert, warum's nicht läuft.

von Spess53 (Gast)


Lesenswert?

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

von Markus (Gast)


Lesenswert?

ja ne, is klar.
aber wie mach ich das jetzt, dass die leds bei 0x00 aus sind und bei 
0xFF an sind?

von Jörg X. (Gast)


Lesenswert?

> 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)

von Markus (Gast)


Lesenswert?

wie gesagt, ich benutze das stk500, da muss es doch bestimmt nur eine 
änderung im code geben, oder?

von Jörg X. (Gast)


Lesenswert?

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

von Spess53 (Gast)


Lesenswert?

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

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.