> De call som saknade return har jag tagit bort, och använder mig av goto istället.
Som jag minns det så borde du ha lagt till return och behållit call, skulle
inte koden ha blivit tydligare på så sätt ?
Generellt känns det som om du "hoppar runt" lite planlöst. Ofta är
det bättre och renare att använda call/return och sedan bara ha *en*
väg tillbaka (till loop i ditt fall). Nu har du "goto loop" på fem olika
ställen och jag ser rätt, och det blir onödigt svårt att följa koden.
T.ex så istället för att göra "goto min" och min avslutas med "goto loop"
så är det snyggare med "call min" och min avslutas med "return" och sedan
en "goto loop" direkt efter "call min", om du hänger med.
Generellt bör du lägga ner mycket mer jobb på att strukturera och dela in
koden i logiska block, något i stil med :
Kod: Markera allt
#include <p12F683.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _IESO_OFF & _FCMEN_OFF & _BOD_OFF & _CPD_OFF)
errorlevel -302
cblock 0x20
d1
d2
endc
;****************************************************
; Här hamnar vi vid reset eller power on !
;****************************************************
call init
;****************************************************
; Main loop !
;****************************************************
Loop:
banksel PIR1
btfss PIR1,TMR2IF ; Vänta för Timer2 overflow
banksel TRISIO
bcf TRISIO,2 ; Starta PWM
call Eeprom_write; Skriv CCPR1L värdet till EEPROM
banksel GPIO
btfss GPIO,1 ; Knapp Ner RA2 intryckt?
goto FadeDown ; Ja.
btfsc GPIO,4 ; Knapp Upp RA3 intryckt?
goto end_of_Loop ; Ja
FadeUp:
call Delay_fade ; Vänta i 0.01 sekunder
banksel CCPR1L
incfsz CCPR1L,f ; Höj PWM duty cycle. Om maximalt call Max
goto end_of_Loop
call Max
goto end_of_Loop
FadeDown:
call Delay_fade
banksel CCPR1L
decfsz CCPR1L,f ; Sänk PWM duty cycle. Om noll call Min
goto end_of_Loop
call Min
end_of_loop:
goto Loop
;****************************************************
; Subrutiner
;****************************************************
Max:
banksel CCPR1L ; PWM duty cycle 100%
movlw b'11111111'
movwf CCPR1L
banksel GPIO
btfsc GPIO,1 ; Lås max läge och vänta för knapp Ner
goto Max
return
Min:
banksel CCPR1L ; PWM duty cycle 0%
movlw b'00000000'
movwf CCPR1L
banksel GPIO ; Lås min läge och vänta för knapp Up
btfsc GPIO,4
goto Min
return
;****************************************************
; Olika delay rutiner
;****************************************************
Delay_fade:
movlw 0x3E
movwf d1
movlw 0x07
movwf d2
Delay_fade_0:
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_fade_0
goto $+1
nop
return
;****************************************************
; EEPROM rutiner.
;****************************************************
Eeprom_read:
banksel EEADR
movlw 0x00 ;Adress i EEPROM som ska läsas
movwf EEADR
bsf EECON1,RD ;Läs EEPROM
movf EEDAT,W ;Flytta data till W
banksel CCPR1L ; Sätta PWM duty cycle läs...
movwf CCPR1L ; ...värdet från EEPROM
return
Eeprom_write:
banksel EEADR
movlw 0x00 ; Adress till EEPROM skrivning
movwf EEADR
banksel CCPR1L
movf CCPR1L,W ; Flytta värdet CCPR1L till W
banksel EEDAT
movwf EEDAT ; Flytta W till EEDAT för skrivning
banksel EECON1
bsf EECON1,WREN
movlw 0x55 ; Lås upp skrivning till EEPROM
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1,WR ; Skriv
return
;****************************************************
; Init
;****************************************************
Init:
banksel CMCON0
movlw b'00000111' ; Stäng av komparatorn
movwf CMCON0
banksel ANSEL
clrf ANSEL ; Alla utgångar digitala
banksel TRISIO
movlw b'00010110' ; Stäng av PWM utgång och...
movwf TRISIO ; ...sätta ingångar
banksel PR2 ;PWM period
movlw b'11111111'
movwf PR2
banksel CCP1CON ; Konfigurera CCP modul för PWM
movlw b'00011100'
movwf CCP1CON
call Eeprom_read ; Läs värdet till CCPR1L från eeprom
banksel PIR1 ; Rensa TMR2IF interrupt flagga i PIR1 reg
bcf PIR1,TMR2IF
banksel T2CON ; Sätt Timer2 prescaler
movlw b'00000111'
movwf T2CON ; Starta Timer2
return
;****************************************************
end
Eller något liknande, du fattar nog...
Notera att de nu bara finns *1* "goto loop" !
Vid "end_of_loop" kan man lägga något som alltid ska göras
innan "goto loop", det är lite svårt om man har spritt ut en massa
"goto loop" över koden...
Sen har du ett par ställen där du "fastnar" och väntar på att en knapp
ska tryckas, t.ex i "Min" och "Max". Inte bra ! Det är bättre att markera
med någon flagga vad som gäller och sedan gå tillbaka till Loop direkt.
Jag ser sedan att du skriver till EEPROM så snart en knapp har tryckts.
Bättra att ha en time-out så att du kan trycka lite fram och tillbaka
och sedan (efter att det har varit stabilt i säg 10 sekunder) spara värdet.
Det blir onödigt mycket skrivningar till EEPROM som det är nu.