Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Tweak PICkit delay time

Status
Not open for further replies.

Ailadad

New Member
OK, brand new to any sort of programming. Got a PICkit 2. I am working with a lesson that came with it. All I need to do is adjust the delay time of the LED cycle. The program cycles through 8 LEDs (driving the outputs high), all LEDs have cycled in just over a second. I need to slow this down to 2-3 seconds for each LED. Here is the code:


#include <p16F887.inc>
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V

cblock 0x20
Delay1 ; Assign an address to label Delay1
Delay2
Display ; define a variable to hold the display
endc

org 0
Start:
bsf STATUS,RP0 ; select Register Bank 1
clrf TRISD ; make IO PortD all output
bcf STATUS,RP0 ; back to Register Bank 0
movlw 0x80
movwf Display
MainLoop:
movf Display,w ; Copy the display to the LEDs
movwf PORTD
OndelayLoop:
decfsz Delay1,f ; Waste time.
goto OndelayLoop ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
decfsz Delay2,f
goto OndelayLoop
bcf STATUS,C ; ensure the carry bit is clear
rrf Display,f ; rotate the display right
btfsc STATUS,C ; Did the bit rotate into the carry?
bsf Display,7 ; yes, put it into bit 7.
goto MainLoop
end


I tried adding a 3rd delay directly after:

decfsz Delay2,f
goto OndelayLoop

I added (also added to up top on the header code):

decfsz Delay3,f
goto OndelayLoop


Then the code continued where it left off. It worked. This slowed down the cycle to like a minute or two per each output. Way to slow.

I understand the concept pf the PIC processor speed, how many instructions it can process and/or how delay works with that, but I do not understand how to tweak a delay to a specific time. The way they had it set up in this lesson code, it looks like its a broad time jump. How can I enter in values to play with the delay time for this output cycle?



Any thoughts? Example code? Or can anyone help me modify this code so that I can understand it? Nothing to deep here, just want a logical explanation.




Thanks!
 
Last edited:
I would use a "general purpose" delay subsystem like the example below (for 4, 8, 12, 16, or 20 MHz clock);

Good luck on your project.

Kind regards, Mike

Code:
#include <p16F887.inc>
        __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
        __CONFIG _CONFIG2, _WRT_OFF & _BOR21V

        cblock  0x20
TimerHi                 ; DelayCy() subsystem
Display                 ; define a variable to hold the display
        endc

;******************************************************************
;
;  DelayCy() subsystem
;
        radix   dec

clock   equ     4               ; clock frequency in Megahertz
usecs   equ     clock/4         ; cycles/microsecond multiplier
msecs   equ     usecs*1000      ; cycles/millisecond multiplier
;                                                                 *
;  DelayCy() macro                                                *
;                                                                 *
DelayCy macro   pDelay          ; cycles (Tcy), minimum 16
        local   cycles
cycles = pDelay
     while cycles > 262032
        movlw   high((262016-16)/4)+1
        movwf   TimerHi
        movlw   low((262016-16)/4)
        call    DelayLo-(262016%4)
cycles -= 262016
     endw
        movlw   high((cycles-16)/4)+1
        movwf   TimerHi
        movlw   low ((cycles-16)/4)
        call    DelayLo-(cycles%4)
        endm

;******************************************************************
;
;  Main Program
;
        org     0
Start:
        bsf     STATUS,RP0      ; select Register Bank 1          |B1
        clrf    TRISD           ; make IO PortD all output        |B1
        bcf     STATUS,RP0      ; back to Register Bank 0         |B0
        movlw   0x80            ;                                 |B0
        movwf   Display         ; seed 'Display' variable         |B0
Loop:
        movf    Display,W       ; get display pattern             |B0
        movwf   PORTD           ; update LEDs                     |B0
        DelayCy(200*msecs)      ; delay 200 msecs                 |B0
        rrf     Display,W       ; shift right but copy            |B0
        rrf     Display,F       ; bit 0 into bit 7                |B0
        goto    Loop            ;                                 |B0

;******************************************************************
;                                                                 *
;  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    |B0
        nop                     ; entry point for delay%4 == 2    |B0
        nop                     ; entry point for delay%4 == 1    |B0
DelayLo addlw   -1              ; subtract 4 cycle loop time      |B0
        skpnc                   ; borrow?  yes, skip, else        |B0
        goto    DelayLo         ; do another loop                 |B0
        nop                     ;                                 |B0
DelayHi addlw   -1              ; subtract 4 cycle loop time      |B0
        decfsz  TimerHi,F       ; done?  yes, skip, else          |B0
        goto    DelayLo         ; do another loop                 |B0
        goto    $+1             ; burn off 2 cycles               |B0
        return                  ;

        end
 
Last edited:
Thanks, K8LH. I tried this code. I was able to build it in MPLAB and Program it into the PICkit 2 Debug Express, However, the outputs still cycle at the same exact speed. They have the same timing delay.


Is there anything less complicated, that is in an additional line or two, or three or four, that could be added to this existing code just to lengthen the delay between output switching?
 
FYI, I'm using this PIC in the PIKkit2: PIC16F887

The data sheet says it has an internal osc, from 8 MHz to 32 kHz that is a software selectable frequency.
 
Is there a way to use the nop instruction? Where you could add a multiplier after it to lengthen the delay?
 
Try this and see if it works for you
Code:
#include <p16F887.inc>
        __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
        __CONFIG _CONFIG2, _WRT_OFF & _BOR21V

     cblock 0x20
     d1          ; Assign an address to label Delay
     d2
     d3
     Display             ; define a variable to hold the diplay
     endc
     
     org 0
Start:
     bsf       STATUS,RP0          ; select Register Page 1
     clrf      TRISC               ; make IO PortC all output
     bcf       STATUS,RP0          ; back to Register Page 0
     movlw     0x08
     movwf     Display
MainLoop:
     movf      Display,w           ; Copy the display to the LEDs
     movwf     PORTC
OndelayLoop:
     			;1500000 cycles
	movlw	0x0D
	movwf	d1
	movlw	0x46
	movwf	d2
	movlw	0x04
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

     
     bcf       STATUS,C            ; ensure the carry bit is clear
     rrf       Display,f
     btfsc     STATUS,C            ; Did the bit rotate into the carry?
     bsf       Display,3           ; yes, put it into bit 3.
     goto      MainLoop
     end
 
be80be,

Thanks that worked. I had to tweak it a little. I needed to change it to PortD, that happens to be where these outputs are. And I changed the carry bit to carry into bit 7 instead of 4, so all 8 outputs are cycled, instead of 4.

Although I don't entirely understand it, I was able to play with it and get it to work.

Is this a sub routine delay?

Thanks again.
 
It's inline delay that may not be what you call it. But it is part of main code it's not called
like it would be if it was a sub
Code:
         call    OndelayLoop      ; you would use it like this
OndelayLoop:     			;1500000 cycles
	movlw	0x0D
	movwf	d1
	movlw	0x46
	movwf	d2
	movlw	0x04
	movwf	d3
Delay_0:
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0
        return
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top