PIC16F627A Blink issue

Status
Not open for further replies.

AtomSoft

Well-Known Member
As i am starting to practice on more chips i use the blink as a start... But i ran into a issue... it doesnt want to blink just stays on solid... and since i can not debug with out a ICD 2 well... i cant debug lol here is my code

Code:
	list      p=16f627A           ; list directive to define processor
	#include <P16F627A.inc>       ; processor specific variable definitions
	__CONFIG   0x3f78 ;_CP_OFF & _DATA_CP_OFF & _LVP_OFF & _WDT_OFF & _INTOSC_OSC_CLKOUT 

	cblock 0x00
	d1
	d2
	d3
	endc

	ORG     0x00			; processor reset vector
Main
	clrf	PORTA			;Initialize PORTA by setting output data latches
	movlw	0x07 			;Turn comparators off and
	movwf	CMCON 			;enable pins for I/O functions
   	bsf 	STATUS, RP0		;select bank 1
	movlw	0x1D			;data direction
	movwf	TRISA			;set PortA all outputs
	bsf	PCON, 3			;OSCF: INTOSC oscillator frequency bit: 1=4 MHz typical
	bcf	STATUS, RP0		;select bank 0

Loop	
	bsf	PORTA, 1		;set RA1 High
	call	Delay
	bcf	PORTA, 1		;set RA1 Low
	goto	Loop			;go back and do it again

Delay
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0
	goto	$+1
	return
	END				; directive 'end of program'
 
Well it is obvious, after bsf PORTA,1 you call delay but after bcf PORTA,1 you forgot to call it again and jump to Loop which sets the output to 1 again.

Petr
 
petrv said:
Well it is obvious, after bsf PORTA,1 you call delay but after bcf PORTA,1 you forgot to call it again and jump to Loop which sets the output to 1 again.

Well spotted!
 
 
RAM starts at 0x20 on the 16F627A PIC
Code:
    list      p=16f627A           ; list directive to define processor
    #include <P16F627A.inc>       ; processor specific variable definitions
    __CONFIG  _WDT_OFF & _INTOSC_OSC_NOCLKOUT

    cblock 0x20
    d1,d2,d3
    endc

    ORG     0x00            ; processor reset vector
Main
    clrf    PORTA            ;Initialize PORTA by setting output data latches
    movlw    0x07             ;Turn comparators off and
    movwf    CMCON             ;enable pins for I/O functions
       bsf     STATUS, RP0        ;select bank 1
    movlw    0x1D            ;data direction
    movwf    TRISA            ;set PortA all outputs
    bsf    PCON, 3            ;OSCF: INTOSC oscillator frequency bit: 1=4 MHz typical
    bcf    STATUS, RP0        ;select bank 0

Loop    
    bsf    PORTA, 1        ;set RA1 High
    call    Delay
    bcf    PORTA, 1        ;set RA1 Low
    goto    Loop            ;go back and do it again

Delay
    movlw    0x03
    movwf    d1
    movlw    0x18
    movwf    d2
    movlw    0x02
    movwf    d3
Delay_0
    decfsz    d1, f
    goto    $+2
    decfsz    d2, f
    goto    $+2
    decfsz    d3, f
    goto    Delay_0
    goto    $+1
    return
    END                ; directive 'end of program'    END
 
Last edited:
Not 100% true, ICD2 *can* debug it but not alone, it is necessary to buy a special adapter from Microchip (AC162053) - costs about $35 - that allows you to debug code for 627A/628A/648A.

Of course 16F88 can be debugged with ICD2 or PicKit2 alone, without any additional hardware.

Petr
 
ok thanks guys i cant believe i missed something so small and yeah i know it starts at 0x20 but just habit of 00 lol thanks.
 
ICD? Learn to use the simulator in the IDE very very good period. A few taps of the single step F7 key would have solved this in under 30 seconds. I never actually used ICD, do not know how, don't want to know.

Standardize your delays. Make a set for micro seconds, milli seconds, and seconds similar to my code below.
Code:
Set LED
Call usec100
Call usec100
Clear LED
Call usec100
Call usec100
Loop

movlw .50
movw milli_time        ; Load milli_time only once because it is persisted into milli_time_temp.
Set LED                ; A.K.A non-volatile.
Call milli_delay
Clear LED
Call milli_delay
Loop



Code:
USEC_10:
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	RETURN
USEC_20:
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	GOTO	$ + 1
	RETURN
USEC_100:			;----FORMULA--4MHZ CLOCK---------
	MOVLW	.31		;  [3(CNTJ-1)+2] + CHANGE
	MOVWF	CNTJ		;  CHANGE = 8 USEC
	DECFSZ	CNTJ, F		;  [3(CNTJ-1)+2] + 8
	GOTO	$ - 1	        ;--------------------------------
	NOP
	NOP
	RETURN

MS_DELAY:
	MOVF	MILLI_TIME, W    ;---------------------------------------
        MOVW    MILLI_TIME_TEMP  ;MILLI SECOND DELAY
MS_LOOP	MOVLW	0XA4             ;DELAY = X MILLI-SECOND (4MHZ CLOCK).
	MOVWF	CNTJ             ;---------------------------------------
	DECFSZ	CNTJ, F
	GOTO	$ - 1
	MOVLW	0XA4
	MOVWF	CNTJ
	DECFSZ	CNTJ, F
	GOTO	$ - 1

	DECFSZ	MS_TIME_TEMP, F	;IF COUNTER ENDS,
	GOTO	MS_LOOP		;ELSE- REPEAT
	RETURN			;THEN- EXIT LOOP
See my last signature line below. ===========================\/
 
Last edited:
Simulator just doesnt work in some cases.

Like here is my end code for a 7 Seg Display count up 0 - 9... I wouldnt want to try to simulate this.. would get confusing... RA5 and RA7 are inuse so used RB0 and RB1...
Code:
	list      p=16f627A           ; list directive to define processor
	#include <P16F627A.inc>       ; processor specific variable definitions
	__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT 

	cblock 0x20
	d1
	d2
	d3
	endc

	ORG     0x00			; processor reset vector
Main
	clrf	PORTA			;Initialize PORTA by setting output data latches
	movlw	0x07 			;Turn comparators off and
	movwf	CMCON 			;enable pins for I/O functions
   	bsf 	STATUS, RP0		;select bank 1
	movlw	0x00			;data direction
	movwf	TRISA			;set PortA all outputs
	movwf	TRISB			;set PortB all outputs
	bsf	PCON, 3			;OSCF: INTOSC oscillator frequency bit: 1=4 MHz typical
	bcf	STATUS, RP0		;select bank 0

Loop	
	movlw	b'01011111'		;Show 0
	movwf	PORTA
	movlw	0x01		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'00000110'		;Show 1
	movwf	PORTA
	movlw	0x00		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'10011011'		;Show 2
	movwf	PORTA
	movlw	0x03		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'10001111'		;Show 3
	movwf	PORTA
	movlw	0x02		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'11000110'		;Show 4
	movwf	PORTA
	movlw	0x02		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'11001101'		;Show 5
	movwf	PORTA
	movlw	0x02		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'11011101'		;Show 6
	movwf	PORTA
	movlw	0x03		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'00000111'		;Show 7
	movwf	PORTA
	movlw	0x00		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'11011111'		;Show 8
	movwf	PORTA
	movlw	0x03		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	movlw	b'11011111'		;Show 9
	movwf	PORTA
	movlw	0x02		; RB0 = E RB1 = G
	movwf	PORTB
	call	Delay
;////////////////////////////////////////////////////
	goto	Loop
Delay				; 1 Sec Delay
	movlw	0x07
	movwf	d1
	movlw	0x2F
	movwf	d2
	movlw	0x03
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0
	goto	$+1
	goto	$+1
	goto	$+1
	return
	END				; directive 'end of program'
 
Of course the use of the simulator is limited but sometimes it is still useful - for example I used it yesterday to quickly verify my delay loop produces the exact delay and not a few instr. cycles longer or shorter... using the logic analyzer inside the simulator it was easy and quick.

Petr
 
How come sometimes my Logic Analyzer isnt available? Like i cant open it because its greyed out?
 
Setting d1,d2,d3 in a watch and pressing the F7 would have revealed that d1 to d3 were not being assigned and overwritten, and that a delay between BCF and GOTO were missing.
Code:
    cblock 0x00
    d1,d2,d3
    endc

    ORG     0x00           ; processor reset vector
Loop    
    bsf    PORTA, 1        ;set RA1 High
    call    Delay
    bcf    PORTA, 1        ;set RA1 Low
    goto    Loop           ;go back and do it again
 
AtomSoft (and gang),

I suspect this may be slightly off topic but I wanted to say I agree with donniedj about using a good general purpose delay subroutine and thought I'd share one of the delay systems I use with 16F' devices.

This small (12 instruction) delay subroutine system was designed to work with a 4, 8, 12, 16, or 20 MHz clock and provides a variable delay of 16 to 262144 cycles (Tcy) which can be specified in cycles, microseconds, or milliseconds. You can also specify delays in microseconds or milliseconds plus or minus some number of cycles to produce precise isochronous delay loops.

Here's a simple key press beep routine to demonstrate. The first example uses the DelayMS() macro but doesn't account for the 6 instruction cycles in the loop and won't produce an exact 500 Hz tone. The second example uses the DelayCy() macro instead with usecs or msecs multiplier in the operand and subtracts 6 instruction cycles to produce an exact 500 Hz tone no matter what clock frequency you're using.

Code:
;
;  key press beep -- 1 msec delay, no loop timing correction
;
;  497.018 Hz --  4 MHz clock
;  498.504 Hz --  8 MHz clock
;  499.004 Hz -- 12 MHz clock
;  499.251 Hz -- 16 MHz clock
;  499.400 Hz -- 20 MHz clock
;
        bsf     Beep,5          ; do 32 msec switch press beep    |B0
DoBeep  movf    PORTA,W         ; read port A                     |B0
        xorlw   1<<Spkr         ; toggle speaker bit              |B0
        movwf   PORTA           ; toggle speaker pin              |B0[COLOR=magenta]
        DelayMS(1)              ; delay 1 msec for 500 Hz tone    |B0[/COLOR]
        decfsz  Beep,F          ; done?  yes, skip, else          |B0
        goto    DoBeep          ; loop (toggle Spkr pin again)    |B0
Code:
;
;  key press beep -- 1 msec delay, with loop timing correction
;
;  500 Hz -- any clock (4, 8, 12, 16, or 20 MHz)
;
        bsf     Beep,5          ; do 32 msec switch press beep    |B0
DoBeep  movf    PORTA,W         ; read port A                     |B0
        xorlw   1<<Spkr         ; toggle speaker bit              |B0
        movwf   PORTA           ; toggle speaker pin              |B0[COLOR=magenta]
        DelayCy(1*msecs-6)      ; delay 1 msec minus 6 cycles     |B0[/COLOR]
        decfsz  Beep,F          ; done?  yes, skip, else          |B0
        goto    DoBeep          ; loop (toggle Spkr pin again)    |B0
Here's the actual 16F' delay subroutine system code. It includes a couple lines between the macros and the actual subroutine where you can try the DelayCy(), DelayUS(), or DelayMS() macro for simulation testing using the MPLAB StopWatch. Remember, you must set the clock equate to your clock frequency (in MHz).

Have fun. Regards, Mike

Code:
;******************************************************************
;                                                                 *
;  DelayMS(), DelayUS(), DelayCy()    Mike McLaren, K8LH, Jun'07  *
;                                                                 *
;  requires the use of constant operands known at assembly time!  *
;                                                                 *
;  simple macro "front ends" and a small 16-bit delay subroutine  *
;  which allows specifying delays in msecs, usecs, or cycles.     *
;                                                                 *
;  the delay range is based on the microprocessor clock and the   *
;  delay subroutine loop time (a 4 cycle loop in this case).      *
;                                                                 *
;     4 MHz, 1 cycles/usec, 16..262144 usecs, 1..262 msecs        *
;     8 MHz, 2 cycles/usec,  8..131072 usecs, 1..131 msecs        *
;    12 MHz, 3 cycles/usec,  6...87381 usecs, 1...87 msecs        *
;    16 MHz, 4 cycles/usec,  4...65536 usecs, 1...65 msecs        *
;    20 MHz, 5 cycles/usec,  4...52428 usecs, 1...52 msecs        *
;                                                                 *
;  example: a 1 msec delay can be produced the following ways     *
;                                                                 *
;       DelayMS(1)              ; delay 1 msec                    *
;       DelayUS(1000)           ; delay 1 msec                    *
;       DelayCy(1*msecs)        ; delay 1 msec                    *
;       DelayCy(1000*usecs)     ; delay 1 msec                    *
;                                                                 *
;  the latter two methods allow you to add or subtract cycles to  *
;  maintain precise (clock independent) isochronous loop timing.  *
;                                                                 *
;******************************************************************
        radix   dec
[COLOR=magenta]
clock   equ     4               ; user clock freq in MHz[/COLOR]
usecs   equ     clock/4         ; cycles per microsecond
msecs   equ     clock/4*1000    ; cycles per millisecond
;                                                                 *
;  DelayMS(), DelayUS(), and DelayCy() macros                     *
;                                                                 *
DelayMS macro   pDelay          ; msec range from table above
        DelayCy(pDelay*msecs)   ; convert to cycles
        endm                    ;
 
DelayUS macro   pDelay          ; usec range from table above
        DelayCy(pDelay*usecs)   ; convert to cycles
        endm
 
DelayCy macro   pCycles         ; cycles, 16..262159 range
        movlw   high((pCycles-16)/4)+1
        movwf   TMRH
        movlw   low ((pCycles-16)/4)
        call    DelayLo-(pCycles%4)
        endm
;                                                                 *
;  example code for simulation testing;                           *
;                                                                 *
SimTest DelayUS(16000)          ; remember to set 'clock' equate
        nop                     ; put simulator break point here
;                                                                 *
;******************************************************************
;                                                                 *
;  Delay(16..262159 Tcy) subroutine   Mike McLaren, K8LH, Jun'07  *
;                                                                 *
;  12 words, 1 RAM variable, 14-bit core                          *
;                                                                 *
Delay.16
        nop                     ; entry point for delay%4 == 3
        nop                     ; entry point for delay%4 == 2
        nop                     ; entry point for delay%4 == 1
DelayLo addlw   -1              ; subtract 4 cycle loop time
        skpnc                   ; borrow?  yes, skip, else
        goto    DelayLo         ; do another loop
        nop                     ;
DelayHi addlw   -1              ; subtract 4 cycle loop time
        decfsz  TMRH,F          ; done?  yes, skip, else
        goto    DelayLo         ; do another loop
        goto    $+1             ; burn off 2 cycles
        return                  ;
;                                                                 *
;******************************************************************
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…