Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Adding a 5 sec delay into my current program

Status
Not open for further replies.

ColonelSanders

Newbie level 2
Joined
May 21, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
24
Greetings everyone. I am new to this forum. What I am trying to do is take a program I have already wrote and modify it a bit. First, this is for a PIC16F84A. I have a training board I can program this to but also can use MPLAB spftware to simulate.

Currently, my program code first Lights all LED's for a 0.48 second delay, then it extinguishes all LEDs with a 0.48 delay, then it moves on to the actual main program.

The 0.48 second delay is used later on within the program. What I am trying to do is have the initial LED test to use a 5 second delay instead of a 0.48 second delay, but still utilize the 0.48 second delay for the rest of the program.

To start, I will post my original program code that works correctly with only 0.48 second delay. Next I will post the code where I tried implementing the desired 5 second delay only in the initial LED test.

I would appreciate any advice that anyone could give me on how to accomplish my goal of having a 5 second delay (LEDs on 5 sec, LEDs off five seconds) in the initial LED test.




ORIGINAL (working) PROGRAM CODE BELOW:

Code:
		#include <GENERAL.H> ;This is the header file

COUNT1	EQU	0X20			; Counter for the inner loop
COUNT2	EQU	0X21			; Counter for the middle loop
COUNT3	EQU	0X22			; Counter for the outer loop

		__CONFIG	0X3FF6	;This is the control bits for CONFIG register

		ORG		0X0000		;RESET or WDT reset vector
		GOTO	START
		
		ORG		0X0004		;Regular INT vector

;This is the area where your interrupt service routine goes

		RETFIE

START						;The starting place of the user codes

; The I/O must be set up. Pins 7,8,9,10 (PORTB) and 17,18,1,2 (PORTA)
; All other pins are inputs. This allows both port latches to use the same literal

	CLRF	PORTA			; Ensure both port latches are all 0 before
	CLRF	PORTB			; setting up I/O

	BSF		STATUS,RP0		; Shift to bank 1 to change TRIS registers
	MOVLW	0XF0			; TRISA and TRISB both use F0 to have pins 0 - 3
	MOVWF	TRISA			; as outputs
	MOVWF	TRISB
	MOVLW	0XFE
	MOVWF	OPTION_REG		; The prescales needs to be set to 04 for the
							; watchdog timer to time out 1.15 seconds

	BCF		STATUS,RP0		; Shift to bank 0 for normal operation

	MOVLW	0X0F			; This will illuminate all lights
	MOVWF	PORTA			; when it is loaded in both ports
	MOVWF	PORTB

	CALL	DELAY			; Provides a .48 second delay

	CLRF	PORTA			; This will extenguish all lights
	CLRF	PORTB			; when it is loaded in both ports

	CALL	DELAY			; Provides a .48 second delay


SWTEST
	CLRWDT

	BTFSC	PORTB,RB5		; This is the switch for all LEDs being lit
	CALL	ALLIGHTS		; (Switch 3)

	CLRWDT

	BTFSC	PORTB,RB6		; This is the switch for red LEDs beig lit
	CALL	GREENLIGHTS		; (Switch 2)

	CLRWDT

	BTFSC	PORTB,RB7		; This is the switch for the yellow LEDs being lit
	CALL	YELLOWLIGHTS	; (Switch 1)

	MOVLW	0X00			; This will extenguish all lights
	MOVWF	PORTA			; when it is loaded in both ports
	MOVWF	PORTB

	GOTO	SWTEST			; Return to the top of the switch test loop

ALLIGHTS
	MOVLW	0X0F			; This will illuminate all lights on PORTA
	MOVWF	PORTA
	MOVLW	0X00			; and extenguish all on PORTB
	MOVWF	PORTB
	CALL	DELAY
	MOVLW	0X00			; This will extenguish all lights on PORTA
	MOVWF	PORTA
	MOVLW	0X0F			; and illuminate all lights on PORTB
	MOVWF	PORTB
	CALL	DELAY
	RETURN					; Return to the top of the switch test loop

GREENLIGHTS
; If switch 2 is set, only RA1 and RB1 must be illuminated, the delay called, and then
; lit, and the delay called
	MOVLW	0X04			; This will light the green lights only
	MOVWF	PORTA
	MOVLW	0X02
	MOVWF	PORTB
	CALL	DELAY
	MOVLW	0X09			; This will light the red ights only
	MOVWF	PORTA
	MOVLW	0X00
	MOVWF	PORTB
	CALL	DELAY
	RETURN

YELLOWLIGHTS
; If switch 3 is set,RA2, RB0, RB2, RB3 must be turned on, the delay called
; and then RA0 and RA1 turned on, and the delay called again.
	MOVLW	0X02			; This will light the yellow lights only
	MOVWF	PORTA
	MOVLW	0X0D
	MOVWF	PORTB
	CALL	DELAY
	MOVLW	0X09			; This will light the red lights only
	MOVWF	PORTA
	MOVLW	0X00
	MOVWF	PORTB
	CALL	DELAY
	RETURN					; Return to the top of the switch test loop

DELAY
; This subroutine is a fixed delay loop. It is 2,393,421 clock cycles long, for
; a wait time of .4799 seconds with a 20 MHZ resonator.
	CLRF	COUNT1
	CLRF	COUNT2
	CLRF	COUNT3

	MOVLW	0X7E			; (1)
	MOVWF	COUNT3			; (1)

LOOPOUT
	MOVLW	0X4F			; (1)
	MOVWF	COUNT2			; (1)

LOOPMID
	MOVLW	0X4F			; (1)
	MOVWF	COUNT1			; (1)

LOOPIN
	DECFSZ	COUNT1,F		; (1 of 2)
	GOTO	LOOPIN			; (2)

; This will be executed 29 times

	DECFSZ	COUNT2,F		; (1 of 2)
	GOTO	LOOPMID			; (2)

; This loop will be executed 29 times

	DECFSZ	COUNT3,F		; (1 of 2)
	GOTO	LOOPOUT			; (2)

; This loop will be executed 126 times

	RETURN					; (2)

	END




My Attempt at adding the desired 5 second delay (probably royally screwed it up!):

Code:
#include <GENERAL.H> ;This is the header file
COUNT1          EQU				0X20                                      ; Counter for the inner loop
COUNT2          EQU				0X21                                      ; Counter for the middle loop
COUNT3          EQU				0X22                                      ; Counter for the outer loop

    __CONFIG          0X3FF6  ;This is the control bits for CONFIG register

ORG    0X0000                  ;RESET or WDT reset vector
GOTO   START

ORG    0X0004                  ;Regular INT vector
;This is the area where your interrupt service routine goes
RETFIE

START                          ;The starting place of the user codes
	; The I/O must be set up. Pins 7,8,9,10 (PORTB) and 17,18,1,2 (PORTA)
	; All other pins are inputs. This allows both port latches to use the same literal
	CLRF     PORTA                 ; Ensure both port latches are all 0 before
	CLRF     PORTB                 ; setting up I/O

	BSF      STATUS,RP0            ; Shift to bank 1 to change TRIS registers
	MOVLW    0XF0                  ; TRISA and TRISB both use F0 to have pins 0 - 3
	MOVWF   TRISA                  ; as outputs
	MOVWF   TRISB
	MOVLW    0XFE
	MOVWF   OPTION_REG             ; The prescales needs to be set to 04 for the
	; watchdog timer to time out 1.15 seconds
	BCF     STATUS,RP0             ; Shift to bank 0 for normal operation
	MOVLW    0X0F                  ; This will illuminate all lights
	MOVWF   PORTA                  ; when it is loaded in both ports
	MOVWF   PORTB
	CALL    DELAY5S                ; Provides a 5 second delay
	CLRF    PORTA                  ; This will extenguish all lights
	CLRF    PORTB                  ; when it is loaded in both ports
	CALL    DELAY5S                ; Provides a 5 second delay

SWTEST
	CLRWDT
	BTFSC   PORTB,RB5              ; This is the switch for all LEDs being lit
	CALL    ALLIGHTS               ; (Switch 3)
	CLRWDT
	BTFSC   PORTB,RB6              ; This is the switch for red LEDs beig lit
	CALL    GREENLIGHTS            ; (Switch 2)
	CLRWDT
	BTFSC   PORTB,RB7              ; This is the switch for the yellow LEDs being lit
	CALL    YELLOWLIGHTS           ; (Switch 1)
	MOVLW   0X00                   ; This will extenguish all lights
	MOVWF   PORTA                  ; when it is loaded in both ports
	MOVWF   PORTB
	GOTO    SWTEST                 ; Return to the top of the switch test loop

ALLIGHTS
	MOVLW   0X0F                   ; This will illuminate all lights on PORTA
	MOVWF   PORTA
	MOVLW   0X00                   ; and extenguish all on PORTB
	MOVWF   PORTB
	CALL    DELAY
	MOVLW   0X00                   ; This will extenguish all lights on PORTA
	MOVWF   PORTA
	MOVLW   0X0F                   ; and illuminate all lights on PORTB
	MOVWF   PORTB
	CALL    DELAY
	RETURN                         ; Return to the top of the switch test loop



GREENLIGHTS
; If switch 2 is set, only RA1 and RB1 must be illuminated, the delay called, and then
; lit, and the delay called
	MOVLW   0X04                    ; This will light the green lights only
	MOVWF   PORTA
	MOVLW   0X02
	MOVWF   PORTB
	CALL    DELAY
	MOVLW   0X09                    ; This will light the red ights only
	MOVWF   PORTA
	MOVLW   0X00
	MOVWF   PORTB
	CALL    DELAY
	RETURN



YELLOWLIGHTS
; If switch 3 is set,RA2, RB0, RB2, RB3 must be turned on, the delay called
; and then RA0 and RA1 turned on, and the delay called again.
	MOVLW    0X02                   ; This will light the yellow lights only
	MOVWF   PORTA
	MOVLW    0X0D
	MOVWF   PORTB
	CALL    DELAY
	MOVLW    0X09                   ; This will light the red lights only
	MOVWF   PORTA
	MOVLW    0X00
	MOVWF   PORTB
	CALL    DELAY
	RETURN                          ; Return to the top of the switch test loop



DELAY
; This subroutine is a fixed delay loop. It is 2,393,421 clock cycles long, for
; a wait time of .4799 seconds with a 20 MHZ resonator.
	CLRF    COUNT1
	CLRF    COUNT2
	CLRF    COUNT3
	MOVLW    0X7E                    ; (1)
	MOVWF   COUNT3                   ; (1)
LOOPOUT
	MOVLW    0X4F                    ; (1)
	MOVWF   COUNT2                   ; (1)
LOOPMID
	MOVLW    0X4F                    ; (1)
	MOVWF   COUNT1                   ; (1)
LOOPIN
	DECFSZ  COUNT1,F                 ; (1 of 2)
	GOTO    LOOPIN                   ; (2)
	; This will be executed 29 times
	DECFSZ  COUNT2,F                 ; (1 of 2)
	GOTO    LOOPMID                  ; (2)
	; This loop will be executed 29 times
	DECFSZ  COUNT3,F                 ; (1 of 2)
	GOTO    LOOPOUT                  ; (2)
	; This loop will be executed 126 times
	RETURN                           ; (2)

DELAY5S
CLRWDT

	MOVLW	0XE3
	MOVWF	COUNT1
	MOVLW	0X7F
	MOVWF	COUNT2
	MOVLW	0X37
	MOVWF	COUNT3

DELAY5S_0
CLRWDT
	DECFSZ	COUNT1, F
	GOTO	next1
	DECFSZ	COUNT2, F
next1
CLRWDT
	GOTO	next2
	DECFSZ	COUNT3, F
next2
CLRWDT
	GOTO	DELAY5S_0

	RETURN

	END
 

Actually, I have solved my own problem and feel a bit silly for not realizing this. I do believe that by having the WDT enabled it was being triggered due to my 5 second delay. I took out the WDT altogether and it works fine now. I would, however, be curious to know how to make it work with the WDT enabled. I am assuming I would need to tweak the OPTION_REG setting? Thanks !!
 

you need to clear the watchdog timer before it times outs and reset the processor

in C there is usually a function call, e.g. PIC18, PIC24, etc
Code:
                 ClrWdt();						// clear watchdog timer

there will be a similar instruction in assembly language, e.g.
Code:
CLRWDT
 

Hi,

Nice piece of coding with plenty of comments added.

As shown below have made a couple of changes to your code to make things clearer.

Looks like you have created your own 'general' .inc file - unusual, but its probably better if your refer to the standard Microchip INC files.
( assume your are using the Assembler within MPLAB and not some third party assembler)

Rather than a meaningless number you can code your Config statement as shown, much clearer to see what parameters are set to.

The Banksel directive is much easier to use than the BSF STATUS ...


While its good to understand how a Delay loop works, it can be a pain working out the exact timings.
Much easier to use this calculator **broken link removed**


Code:
	list      p=16F84A            ; list directive to define processor
	#include <p16F84A.inc>        ; processor specific variable definitions

	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC


;     #include <GENERAL.H> ;This is the header file
;  __CONFIG          0X3FF6  ;This is the control bits for CONFIG register


COUNT1          EQU				0X20                                      ; Counter for the inner loop
COUNT2          EQU				0X21                                      ; Counter for the middle loop
COUNT3          EQU				0X22                                      ; Counter for the outer loop

;


  

	ORG    0X0000                  ;RESET or WDT reset vector
	GOTO   START

	ORG    0X0004                  ;Regular INT vector
;This is the area where your interrupt service routine goes
	RETFIE

START                          ;The starting place of the user codes
	; The I/O must be set up. Pins 7,8,9,10 (PORTB) and 17,18,1,2 (PORTA)
	; All other pins are inputs. This allows both port latches to use the same literal
	CLRF     PORTA                 ; Ensure both port latches are all 0 before
	CLRF     PORTB                 ; setting up I/O

;	BSF      STATUS,RP0            ; Shift to bank 1 to change TRIS registers
	banksel TRISA

	MOVLW    0XF0                  ; TRISA and TRISB both use F0 to have pins 0 - 3
	MOVWF   TRISA                  ; as outputs
	MOVWF   TRISB
	MOVLW    0XFE
	MOVWF   OPTION_REG             ; The prescales needs to be set to 04 for the
	; watchdog timer to time out 1.15 seconds

;	BCF     STATUS,RP0             ; Shift to bank 0 for normal operation
	banksel	PORTA
 
Last edited:

As a general rule, if you are using software delays, create a routine for the shortest delay you are using and when you need a longer one, just call it in a loop as many times as necessary. Always include a 'clrwdt' instruction in the innermost loop, it doesn't matter if use it more often than needed, you have already seen the consequences of not using it often enough!

The lack of a 16-bit timer is a pain in that processor, you can create timer delays with the 8-bit one but bigger counters are easier. If you use timers and interrupts to create delays it makes the program far more versatile because it can do other things while waiting for the delay period to finish. It would be worthwile 'upgrading' to a 16F628A or better still a 16F1847 which have more internal features and exactly pin compatible and probably cheaper too.

Brian.
 

better still a 16F1847 which have more internal features and exactly pin compatible and probably cheaper too.

Hi,

Just make sure your programmer can handle the newer 16F1847.

Also consider the compatible 16F88 which is almost as good and usually in most programmers device files.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top