Alternativ till Cpfseq instruktionen i PIC18FXX2

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
nanopile
Inlägg: 312
Blev medlem: 9 april 2006, 17:06:50
Ort: Stockholm

Alternativ till Cpfseq instruktionen i PIC18FXX2

Inlägg av nanopile »

Hej allihop.

Hoppas inte detta låter för korkat, antar att inte Microchip vill göra om designen på sina mikrokontrollers men det är egentligen vad jag önskar att de gör hehe.
Som om de nu skulle det, kanske i nästa generation eller så.
Jag andvänder PIC18F442.
Skulle vilja andvända Cpfseq såhär eftersom jag har ganska mycket val på en massa ställen.

Movlw 0x00
Cpfseq Selection
Call StartMachine
Movlw 0x01
Cpfseq Selection
Call IncreaseSpeed
Movlw 0x02
Cpfseq Selection
Call StopMachine
------
Har andvänt detta system hittils:
-----
Movlw 0x00
Cpfseq Selection
Goto SkipAheadToIncreaseSpeed
Call StartMachine
SkipAheadToIncreaseSpeed
Movlw 0x01
Cpfseq Selection
Goto SkipAheadToStopMachine
Call IncreaseSpeed
SkipAheadToStopMachine
Movlw 0x02
Cpfseq Selection
Goto SomethingElse
Call StopMachine
SomethingElse

Just nu andvänder jag typ 30 selections med värden som ändras lite med tiden, brukar andvända Fsr1 och placera Indf1 i Selection:s ställe eller köra som det står här.
Har fått lära mig att man inte ska andvända Goto för att det genererar spagettikod men vad gör man annars här?
Är det inte lite dum lösning att ha mängder med lables, en för varje selection, blir lite ohållbart tycker jag, eller?

Fick detta av Microchip:
MOVF SELECTION, W
ADDWF PCL, F

BRA StartMachine
BRA IncreaseSpeed
BRA Stopmachine
BRA $ ;TRAP, CODE SHOULD NOT GET HERE

Men är det inte så att om Wreg blir större än antalet vägval så kommer exekveringen o fortsätta efter BRA $ i detta fall skulle väl programmet fortsätta på fel ställe o krasha?
Dessutom måste man ju komma ur subrutinen med en goto och spagettikoden är på god väg eller?
Användarvisningsbild
Icecap
Inlägg: 26736
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Microchips lösning är ju annars den enkla tycker jag.

Jag ser inte hur det kan vara ett problem att ha "för många labels", väljer man rätt namn på dom blir det ju just överskådligt och tydligt.

Att man med "ADDWF PCL,F" måste kolla att W inte är för högt är ju självklart, man kan även ha en default som den hoppar till vid strul.

Vad jag förstår att du vill är att ha den "switch()" som finns i C:
Om W är: - ska följande utföras:
0 - StartMashine
1 - IncreaseSpeed
osv.

Kod: Markera allt

; Numrera funktionerna
Fun_StartMashine equ 0
Fun_IncreaseSpeed equ 1
Fun_Selection equ 2
... osv.
Fun_Highest equ 31 ; Du skrev att du använde 30...

; Här kommer det en rutin
Execute_Function
  ;W innehåller funktionskoden som ska utföras när denna rutin kallas
  sublw Fun_Highest
  btfss STATUS,C
  return ; Om funktionskoden inte ger Carry ska detta utföras (=illegal funktion)
  rlcf w ; Dubbla för att stega i words
  addwf pcl,f  ; Indexera hoppen
  ; Här börjar indexeringen
  goto StartMashine ; Index 0
  goto IncreaseSpeed ; Index 1
  goto Selection ; Index 2
  ... osv osv.

StartMashine
...
return

IncreaseSpeed
...
return

Selection
...
return
Då kan du ladda funktionen in i W och utföra ett "CALL Execute_Function" varpå funktionen blir utförd.

Jag har dock lite svårt att förstå varför det ska vara så svårt och krångligt...
Är det så att vad som ska utföras beror på kommunikation från extern enhet?
Skriv svar