Forum: Mikrocontroller und Digitale Elektronik fehler in state maschine?


von Zoltan Janko (Gast)


Lesenswert?

Ich habe einen unterprogramm fur motorsteuerung geschrieben, der
programm wird in einen 5ms schleife immer mit CALL MOTOR   aufgerufen.
Aus irgendeinem grund will der statemaschine in diesem unterprogramm
nicht funktionieren. Ich vermute dass es in der ausrechnung von der
nachsten state liegt, aber wo?


;;;;;;;;;;;;;   MOTOR    ;;;;;;;;;;;;;;;;;;;;;;;
        RSEG segCODE
MOTOR:

        LDS R30,STATE_MOTOR      ;ladet nachste state
        CLR R31
        LDI R17,HIGH(MOTOR_TAB)
        LDI R16,LOW(MOTOR_TAB)
        ADD R30,R16
        ADC R31,R17              ;PLUS ANFANG ADRESSE
        IJMP                     ;springt ins tabelle




MOTOR_TAB:

                JMP DONOTHING        ;state 1
S_CCW_LAUF:     JMP CCW_LAUF         ;state 2
S_CW_LAUF:      JMP CW_LAUF          ;state 3
S_INCPWM:       JMP INCPWM_MAIN      ;state 4
S_SPEED_N:      JMP SPEED_N_MAIN     ;state 5


;***************************************************************

DONOTHING:

.
.
.
.
.
.
.

         LDI R16,(S_CCW_LAUF-MOTOR_TAB)
         STS STATE_MOTOR,R16
         RET

;*********************************************************************** 
******

CCW_LAUF:

.
.
.
.
.
         LDI  R16,(S_CW_LAUF-MOTOR_TAB)
         STS STATE_MOTOR,R16
         RET

CW_LAUF:
.
.
.
usw.


Ich benutze den iar assembler fur atmega128.
Danke fur jede hilfe und bemerkung.
MFG
Zolo

von Christof Krüger (Gast)


Lesenswert?

Hmmm.. Das Programm sieht eigentlich richtig aus.
Das einzige, was mir jetzt einfällt ist, dass der IJMP-Befehl nur
Adressen bis 64KiB adressieren kann. Ist dein Programm evtl. zu gross
geworden?

von Thorsten (Gast)


Lesenswert?

Hallo,
um zurückzuspringen benutzt du den ret-Befehl. Dieser holt sich die
Sprungadresse vom Stack, die normalerweise von einem call-Befehl auf
den Stack geschrieben wurde. Um in die verschiedenen States zu springen
benutzt du jedoch den jmp-Befehl. Dieser verändert jedoch nicht den
Stack.

Daher entweder mit call in die States springen und mit ret zurück oder
mit jmp in die States und mit jmp zurück. Aber nicht mischen.

Gruß
Thorsten

von Zoltan Janko (Gast)


Lesenswert?

Hallo Thorsten.


Was Du schreibst ist richtig, aber dass ist kein problem, weil
ich rufe diesen statemaschine motor programm mit Call Motor aus eine
5ms programmschleife(kern). Deshalb das RET befehl am ende des states
ist richtig.

Da ist ein anderes fehler.
MFG
Zolo

von Zoltan Janko (Gast)


Lesenswert?

Hallo Christof.


Das programm ist garnicht gross, ich versuche diesen state maschiene
aus 8051 platform auf AVR zu implementieren. Und die sache mit IJMP
sollte richtig sein, weil mit IJMP kann ich nach instruktionset
-atmega128 64kW (128kB) adresieren.

Da ist was anderes.
MFG
ZOLO

von Zoltan Janko (Gast)


Lesenswert?

Hallo Christof und anderen,

Ich habe den fehler in statemaschien gefunden, es lag wie vermutete in
der ausrechnung von adressen. Der IAR assembler (wahrscheinlich auch
andere) rechnen in bytes statt words was fur atmegas angemessene
wahre.

also:

1.)
Der assembler zahlt und adressiert per bytes aber der PC zeigt auf
instruktionen welche aus words bestehen. Also um die richtige adresse
zu kommen, welche ich ins PC uebergeben kann muss ich jedes Labelwert
mit 2 teilen.

2.) und
Am ende jedes states ist das selbe problem. Das unterschied zwissen
zwei label brauche ich auch ins word umzurechnen, also hier teile ich
den unterschied auch mit zwei.

Das richtiges programm sieht dann so aus:


;;;;;;;;;;;;;   MOTOR    ;;;;;;;;;;;;;;;;;;;;;;;
        RSEG segCODE
MOTOR:

        LDS R30,STATE_MOTOR      ;ladet nachste state
        CLR R31
        LDI R17,HIGH(MOTOR_TAB)
        LDI R16,LOW(MOTOR_TAB)
        LSR R17
        ROR R16                 ;TEILE MIT 2!!!!!
        ADD R30,R16
        ADC R31,R17              ;PLUS ANFANG ADRESSE
        IJMP                     ;springt ins tabelle




MOTOR_TAB:

                JMP DONOTHING        ;state 1
S_CCW_LAUF:     JMP CCW_LAUF         ;state 2
S_CW_LAUF:      JMP CW_LAUF          ;state 3
S_INCPWM:       JMP INCPWM_MAIN      ;state 4
S_SPEED_N:      JMP SPEED_N_MAIN     ;state 5


;***************************************************************

DONOTHING:

.
.
.
.
.
.
.

         LDI R16,((S_CCW_LAUF-MOTOR_TAB)/2)
         STS STATE_MOTOR,R16
         RET

;*********************************************************************** 
******

CCW_LAUF:

.
.
.
.
.
         LDI  R16,((S_CW_LAUF-MOTOR_TAB)/2)
         STS STATE_MOTOR,R16
         RET

CW_LAUF:
.
.
.
usw.



UND ES FUNKTIONIERT  fABERHAFT.
dANKE FUR DIE ANREGUNGEN.
MFG
zOLO

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.