Creating Delay for PIC16F877A(Assembly)

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

Post Reply
Ronaldo95163
Posts: 1
Joined: Tue Feb 21, 2017 4:56 pm

Creating Delay for PIC16F877A(Assembly)

Post by Ronaldo95163 » Tue Feb 21, 2017 6:46 pm

Hey guys...I've just started working with the PIC and assembly for the very first time for a few weeks now and I wrote a delay routine to get a LED blinking. The thing is it works but i'm not sure if my logic is 100% spot on for the delay function. So here it is

Code: Select all

LIST 		p=16F877A
INCLUDE 	                <P16F877A.inc>

X 			EQU 		        0x20		
Y 			EQU			0x21 		


			

			ORG 		0x00
			

			BANKSEL 	TRISD
			BCF 		TRISD,7
			BSF		TRISD,2
			BANKSEL 	PORTD

		
						

state		        btfss		        PORTD,2
			GOTO 		main
			GOTO		ledoff
			
			
		
main		
			CALL		setval
			BSF 		PORTD,7
			CALL 	delay
			CALL		setval
			BCF		PORTD,7
			CALL		delay
			btfss		PORTD,2
			GOTO	main
			GOTO 	ledoff

ledoff		BCF			PORTD,7
			GOTO		state

		
		
delay		movlw 	0xF9
			nop
loop		        addlw 	0xFF
			btfss 	STATUS,Z
			goto 		loop
			decfsz	X
			goto 		delay
			decfsz	Y
			goto 		delay
			return

setval		MOVLW		0xFF
			MOVWF		X
			MOVLW		0x04
			MOVWF		Y
			return


			END
It also has a switch incorporated into it that stops the LED from flashing once it's depressed. This also works as well
So here goes my explanation for the delay routine.

It's supposed to turn the LED on for 1 second then turn it off for 1 second and repeat the process.

I have a 4Mhz external clock connected to the pic so I know that it takes 1 micro second for each instruction to be executed. So for me to get a delay of 1 second I would need a total of 1 000 000 instruction cycles.

So firstly I made a routine that takes up 1000 instructions in the delay

2 + (3*248) + 6 = 1000 instruction cycles.
(See the code below)
This was obtained by moving the value 249 in the working register as shown above and decrementing it through the instructions:

Code: Select all

delay
                        movlw 	0xF9
			nop
loop		        addlw 	0xFF
			btfss 	STATUS,Z
			goto 		loop
			decfsz	X
			goto 		delay
and performing a bit test each time on the zero flag of the status register. If the zero flag was set then it means the value in the working register is now 0 and the routine is ran again by calling delay. This is run 255 times which is set by the value in X.

Note 255*1000

Now once the value of X has reached zero then the delay function is ran again Y times where the value of Y is 4 as seen in the setval routine.

So 255*1000*4 = 1 020 000 instruction cycles which is approximately 1 second.

I also tested it with the stopwatch and it also approximates to 1 second as well.
It also works for other delays by scaling the value of Y accordingly.

Now I know I probably could have done this delay way more efficiently, but this is what I came up with at the time. The only thing is i'm not sure if my logic in the calculations of the instruction cycles were correct to make the delay and I probably just got lucky. If someone can verify that my logic is sound then that would bet greatly appreciated.

Thanks in advance guys.

User avatar
phalanx
Non-SFE Guru
Posts: 1972
Joined: Sun Nov 30, 2003 8:57 am
Location: Candia, NH

Re: Creating Delay for PIC16F877A(Assembly)

Post by phalanx » Tue Feb 21, 2017 6:55 pm

When you say you tested it by the stopwatch, do you mean the one built into MPLAB that counts instruction cycles? If so, that's as accurate as it gets. There's nothing inherently wrong with your routine, but as you suspected, it isn't very efficient. While the delay routine is running, your PIC can't be doing anything else. This is why microcontrollers have hardware timers and interrupts but that's a lesson for another day. If your sole purpose is to blink an LED then your routine is fine. Keep in mind that the only time your routine checks your push button as at the end of the 1 second delay after the LED is turned off. If you aren't holding the button at that specific time, the button press will be ignored.

Did you know there is an online delay generator for PICs? You can find it here: http://www.piclist.com/techref/piclist/ ... /delay.htm. All you do it type in your parameters and it will generate the appropriate delay time for you.

-Bill

Post Reply