OT: programming problem

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?

Reply to
Robert Baer
Loading thread data ...

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

It is all in the chip datasheet.

piglet

Reply to
piglet

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.

LUPINR INCFSZ COUNT1 GOTO LUPINR DECFSZ COUNT2 GOTO LUPINR DECFSZ COUNT3 GOTO LUPINR DEXIT

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

--
Regards, 
Martin Brown
Reply to
Martin Brown

Thanks lots!

Reply to
Robert Baer

Thanks again.

Reply to
Robert Baer

Robert Baer wrote:

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?
Reply to
Robert Baer

[snip code]

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 ;

errorlevel -302 ;suppress "not in bank 0" message

cblock 0x20 tick_counter temp ADC_value_lo ADC_value_hi endc

;reset vector org 0 clrf PCLATH goto main

;interrupt vector org 4 banksel INTCON bcf INTCON,T0IF ;clear Timer0 interrupt flag movlw INIT_COUNT ;re-initialise count movwf TMR0 decf tick_counter,f retfie

main: banksel TRISIO movlw 0x00 ;all pins outputs movwf TRISIO bsf TRISIO, GP0 ;AN0 input banksel ANSEL movlw 0x01 ;AN0 as analog input movwf ANSEL banksel ADCON0 movlw 0x01 ;ADC clock Fosc/8, channel 0, ADC turned on (01000001) movwf ADCON0 banksel OPTION_REG movlw b'00000011' ;prescaler 1/128 movwf OPTION_REG ; banksel TMR0 movlw INIT_COUNT ;initialise timer count value clrf tick_counter movwf TMR0 bsf INTCON,GIE ;enable global interrupt bsf INTCON,T0IE ;enable Timer0 interrupt banksel 0

mainloop: call read_ADC bsf GPIO,LED call dly bcf GPIO,LED call dly goto mainloop

dly: movfw ADC_value_hi movwf tick_counter dly1: movf tick_counter,f skpz goto dly1 return

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

end

=============================================

HTH,

Paul

Reply to
P E Schoen
[snip]

Your attention to detail is worryingly limited.

MOVF sW,W moves the saved sW into W

Again you have coded a NOP unless sW==0

--
Regards, 
Martin Brown
Reply to
Martin Brown

That is fine if you want longer delays and I agree it is a better solution (although his chances of getting it working are very low).

--
Regards, 
Martin Brown
Reply to
Martin Brown

formatting link

-Lasse

Reply to
Lasse Langwadt Christensen

Thanks. Like that un-documented error suppression trick.

Reply to
Robert Baer

1) That is exactly what i want; to save sW into W. 2) Compiler issues 0x0826 which interprets into a MOVF direction bit=0 meaning destination is W.
Reply to
Robert Baer

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

Reply to
Robert Baer

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

; ---------------------------------------------- DELAY MOVWF sW ; MOVF STATUS,W ;[REMoved STATUS stuff; no change]] ; MOVWF sSTATUS CLRF COUNT1 CLRF COUNT2 MOVLW d'43' ; fudge for about 1 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,W RETURN ; ---------------------------------------------- sine ORG 0x0100 tab1: ;; RETLW 0x01 ; [0] t=0.7500 r=0.0000 ; ADDWF PCL,F CALL DELAY GOTO repeat

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 ;; RETLW 0x01 ; [4] t=0.7656 r=0.3865 ;; RETLW 0x02 ; [5] t=0.7695 r=0.6040 RETLW 0x02 ; [6] t=0.7734 r=0.8696 ;; RETLW 0x02 ; [7] t=0.7773 r=1.1832 RETLW 0x03 ; [8] t=0.7812 r=1.5445 RETLW 0x03 ; [9] t=0.7852 r=1.9534

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

Comments?

Reply to
Robert Baer

Snip the code down to the smallest segment that demonstrates the fault and describe what you see happen and what you expected to see.

How do you expect to tell the difference if all paths return value 1?

Run it in the emulator and/or single step it and watch the registers carefully. This has to be user error. PICs really do work!

Here are a couple of canonical concrete examples with no safety features for crossing page boundaries so be careful where you put them:

DIG2SEG: ; enter with 0

Reply to
Martin Brown
[snip]

I'd check for intermittent contacts on the pickit3 as well; I had to reolder the connector on mine not long after I got it.

--- news://freenews.netfront.net/ - complaints: snipped-for-privacy@netfront.net ---

Reply to
new_ibm

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!

piglet

Reply to
piglet

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.