DELAY MOVWF sW ; save W ; following gives Warning: Argument out of range. Least significant bits used. MOVF sSTATUS,STATUS ;assy: d=1;sSTATUS@25 == save STATUS CLRF COUNT1 CLRF COUNT2 MOVLW d'16' ; fudge for about 1 Sec delay MOVWF COUNT3
LUPINR INCFSZ COUNT1 ; race inside inner loop GOTO LUPINR ; high speed count GOTO LUPOTR ; go for another outer count
DEXIT: MOVF sW ; restore W ; following gives Warning: Argument out of range. Least significant bits used. MOVF STATUS,sSTATUS ;assy: d=0;STATUS@03 == restore STATUS RETURN Using this shows that W is NOT restored, that it set to the delay value. Therefore, i can assume ditto for STATUS. Comments in listing derived from compiled code; "d" stands for the direction bit.
You cannot do register to (different) register moves. MOVF will either move specified file register to W or to itself (the utility of which is that it updates flags, e.g. for a Z flag test later on).
When you wrote movf sSTATUS,STATUS the compiler saw the second parameter (STATUS) is non-zero and so set direction d=1 when coding.
So in your example above do this to save status word:
movf STATUS,W movwf sSTATUS ... ... movf sSTATUS,W movwf STATUS
On 06/10/2015 07:09, Robert Baer wrote: > Yes, the same old PIC16F648A.. > > DELAY MOVWF sW ; save W > ; following gives Warning: Argument out of range. Least significant > bits used. > MOVF sSTATUS,STATUS ;assy: d=1;sSTATUS@25 == save STATUS > CLRF COUNT1 > CLRF COUNT2 > MOVLW d'16' ; fudge for about 1 Sec delay > MOVWF COUNT3 > > LOOPIE DECFSZ COUNT3 > GOTO LUPOTR > GOTO DEXIT > > LUPOTR DECFSZ COUNT2 > GOTO LUPINR ; COUNTed once,do inner loop > GOTO LOOPIE > > LUPINR INCFSZ COUNT1 ; race inside inner loop > GOTO LUPINR ; high speed count > GOTO LUPOTR ; go for another outer count > > DEXIT: MOVF sW ; restore W > ; following gives Warning: Argument out of range. Least significant > bits used. > MOVF STATUS,sSTATUS ;assy: d=0;STATUS@03 == restore STATUS > RETURN > Using this shows that W is NOT restored, that it set to the delay value. > Therefore, i can assume ditto for STATUS. > Comments in listing derived from compiled code; "d" stands for the > direction bit. > > Help?
Learning how to program in PIC assembler might help. RTFM
formatting link
MOVF sW,W
MOVF sW,F merely tests if sW==0
Is this some sort of competition to maximise the number of GOTOs and random flow of control? Heaven help the maintenance programmers.
If you reorder the code sensibly half of the GOTOs vanish. COUNT3 needs to be one less due to dropping through the loop code.
I prefer to have a single delay routine that accepts W on input as the exact number of cycles to delay by as a separate routine. It makes doing variable precision delays in software so much easier. YMMV
I now have an "improved" version, but still do not have satisfactory results.
** start: ;** setup I/O CLRF 6 ; Set all Port B pins to logic 0 BSF 3,5 ; Bank 1 command comes next STATUS RP0 set CLRF 6 ; sel all Port B pins as outputs BCF 3,5 ; Bank 0 command comes next STATUS RP0 clear CLRF ptrlo CLRF ptrhi CLRW MOVWF 6 ; Port B to zero CALL DELAY ; "freeze" LEDs MOVLW 0xFF MOVWF 6 ; Port B ones CALL DELAY ; "freeze" LEDs setup: MOVLW Low(tab1) ; tab1 at org 0x0100 ADDWF ptrlo,W ; add pointer to W [so W=0 now] MOVLW High(tab1) ; [so W=1 now] BTFSC STATUS,C INCF PCLATH,F ; carry to hi ; CALL tab1 ; first table, first location (=0) ; RETurns here MOVWF 6 ; Port B from W shows 0x01 [OK] CALL DELAY ; "freeze" LEDs repeat: INCF ptrlo ; next loc MOVWF 6 ; Port B from W shows 0x18 [???] CALL DELAY ; "freeze" LEDs INCF ptrlo ; next loc MOVWF 6 ; Port B from W shows 0x18 CALL DELAY ; "freeze" LEDs INCF ptrlo ; next loc ; BTFSC STATUS,Z ; INCF ptrhi MOVWF 6 ; Port B from W shows 0x18 CALL DELAY ; "freeze" LEDs GOTO setup ; ---------------------------------------------- DELAY MOVWF sW MOVF STATUS,W MOVWF sSTATUS CLRF COUNT1 CLRF COUNT2 MOVLW d'93' ; fudge for about 4 Sec delay MOVWF COUNT3 LUPINR DECFSZ COUNT1 GOTO LUPINR DECFSZ COUNT2 GOTO LUPINR DECFSZ COUNT3 GOTO LUPINR DEXIT: MOVF sSTATUS,W MOVWF STATUS MOVF sW RETURN
** So something in the delay routine is setting W to 0x18. WTH?
It is usually better programming practice to implement longer delays by using one of the timers with an interrupt and ISR. You can set the PR1 or PR2 registers, along with pre and post scalers, to get a convenient timer tick, such as 1 mSec. Then you can also make a timer register increment every 250 ticks for 1/4 second resolution.
Here is a sample of what can be done. I do almost everything in C now, so I had to search for something in ASM:
;Timer0.asm ;Reads ADC (AN0, pin 7) and sets a delay accordingly.
#include "P12F675.INC"
#define LED 2 ;GP2 (pin 5) #define INIT_COUNT 10 ;
;--------------------------------------------------------------------- ;read_ADC ;function to read ADC ;returns high and low bytes (10 bits) in ADC_value_hi ;and ADC_value_lo variables. Value is left-justified. ;---------------------------------------------------------------------
read_ADC: banksel ADCON0 bsf ADCON0,GO ;start conversion WaitADC: btfss ADCON0,GO ;GO/DONE clear when conversion is complete goto WaitADC ;wait for ADC to finish GetADC1: banksel ADRESH movfw ADRESH ;get high byte in W movwf ADC_value_hi bcf STATUS,Z rrf ADC_value_hi,f ;divide by 2 movlw .10 ;and add a constant addwf ADC_value_hi,f ;to give a narrow range of values return
Different problem...cut and paste of some sessions:
Erasing... Erase device complete
Programming... Programming/Verify complete
Target Removed
Target Detected Device ID Revision = 00000005
Target Removed
Target Detected Device ID Revision = 00000005
Erasing... Erase device complete
Programming... Programming/Verify complete
Target Removed ** unplugged PICkit3
Target Detected ** plugged it back in Target Device ID (00000000) does not match expected Device ID (00001100). ** note error message
Erasing... Erase device complete
Erasing... Erase device complete
Programming... Programming/Verify complete
Target Removed ** unplugged PICkit3
Target Detected ** plugged it back in Device ID Revision = 00000005 ** note OK
This is a PIC16F648A that had exhibited that problem and "stuck" bad and would not erase. Fixed it by baking at 200F for an hour.
I have the whole project board wrapped in anti-static bubble wrap this time. The only possible niggle is that the grounds (PICkit3, project board) are not exactly the same when disconnected; insulation/separation/connection is via the bubble wrap. BUT the device now looks OK...
First, program listing as-is: LIST p=P16F648A #include P16F648A.inc ; Was P16F628A __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _MCLRE_OFF & _BOREN_OFF __IDLOCS 0x0001
; VARIABLES ptrlo EQU 0x20 ; table pointer ptrhi EQU 0x21 COUNT1 EQU 0x22 ; delay counter COUNT2 EQU 0x23 COUNT3 EQU 0x24 sSTATUS EQU 0x25 sW EQU 0x26 ; ORG 0x0000 GOTO start GOTO start GOTO start GOTO start ORG 0x0010 start: ;** setup I/O CLRF 6 ; Set all Port B pins to logic 0 BSF 3,5 ; Bank 1 command comes next STATUS RP0 set CLRF 6 ; sel all Port B pins as outputs BCF 3,5 ; Bank 0 command comes next STATUS RP0 clear
CLRF ptrlo CLRF ptrhi
CLRW MOVWF 6 ; Port B to zero CALL DELAY ; "freeze" LEDs
MOVLW 0xA5 ;FF [changed to see pattern change]] MOVWF 6 ; Port B ones CALL DELAY ; "freeze" LEDs setup: MOVLW Low(tab1) ADDWF ptrlo,W ; add pointer to W MOVLW High(tab1) BTFSC STATUS,C INCF PCLATH,F ; carry to hi CALL tab1 ; first table, first location (=0), W=1 ; RETurns here MOVWF 6 ; Port B from W CALL DELAY ; "freeze" LEDs repeat: INCF ptrlo ; next loc ; BTFSC STATUS,C ; INCF ptrhi MOVF ptrlo,W CALL tab1 ;;*REMoving this, one sees W counting ;; otherwise, LEDs show 0x00 0xA5 0xA5 0xA5 0xA5... MOVWF 6 ; Port B from W CALL DELAY ; "freeze" LEDs GOTO repeat
WTH is happening? Shouldn't i see the same thing either way? Results are also nutso (exactly the same) if i have "standard" tab1: ADDWF PCL,F RETLW 0x01 ; [1] t=0.7539 r=0.0240 RETLW 0x01 ; [2] t=0.7578 r=0.0964 RETLW 0x01 ; [3] t=0.7617 r=0.2173
Follow the flow around those two above instructions (call delay, goto repeat), once and then again and again. Then be very grateful the PIC has a small return stack!
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.