Strange loop behavior

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

Moderator: phalanx

Post Reply
evellon
Posts: 3
Joined: Sat Jan 28, 2017 4:07 pm

Strange loop behavior

Post by evellon » Sat Jan 28, 2017 5:00 pm

Hello. I started learning PIC microcontrollers recently and I'm doing various beginner projects at the moment. Last one was making three LEDs blink one after the other (1 - 2 - 3 - 1 - 2 - 3 - and so on). The problem is that the last LED is on for shorter period of time compared to the other two although it uses the same delay loop. Here is my program's main loop:

Code: Select all

main_loop
		bcf		PORTA,2			  ; Clear RA2
		bsf		PORTA,0		  	  ; Set RA0

		call	Delay_1s

		bcf		PORTA,0			  ; Clear RA0
		bsf		PORTA,1			  ; Set RA1

		call	Delay_1s

		bcf		PORTA,1			  ; Clear RA1
		bsf		PORTA,2			  ; Set RA2

		call	Delay_1s
		goto	main_loop
I am using PIC16F84A with 20MHz external crystal oscillator connected to it HS (High Speed) mode. The LEDs are connected to RA0, RA1, and RA2. I've tried replacing the LEDS but the one connected to RA2 still turns off sooner. I also ran the program in a PIC simulator to check if it is a program issue. The 'goto main_loop' statement at the end should be causing the LED on RA2 to stay on for two more cycles and that was the result indeed. Everything was working fine in the simulation.

I tried another program - blinking all the LEDs together

Code: Select all

main_loop
		movlw	07h
		movwf	PORTA
		
		Delay_1s
		
		movlw	00h
		movwf	PORTA
		
		Delay_1s
		goto main_loop
Again, the LEDs stay on longer. Whatever I do the last delay loop in the main loop always seems to execute faster... Do you have any ideas what can be the reason?

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

Re: Strange loop behavior

Post by phalanx » Sun Jan 29, 2017 5:00 pm

Hi evellon,

There are a few possibilities but I don't have enough info from you to say for certain. Can you post your entire source as well as your configuration bits?

-Bill

evellon
Posts: 3
Joined: Sat Jan 28, 2017 4:07 pm

Re: Strange loop behavior

Post by evellon » Mon Jan 30, 2017 1:19 am

Code: Select all

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

	__CONFIG   _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC


;***** VARIABLE DEFINITIONS
w_temp        EQU     0x0C        ; variable used for context saving 
status_temp   EQU     0x0D        ; variable used for context saving
COUNT1		  EQU	  0x10		  ; Counter
COUNT2		  EQU	  0x11		  ; Counter
COUNT3		  EQU	  0x12		  ; Counter

;**********************************************************************
		ORG     0x000             ; processor reset vector
  		goto    main              ; go to beginning of program


		ORG     0x004             ; interrupt vector location
		movwf   w_temp            ; save off current W register contents
		movf	STATUS,w          ; move status register into W register
		movwf	status_temp       ; save off contents of STATUS register

; isr code can go here or be located as a call subroutine elsewhere


		movf    status_temp,w     ; retrieve copy of STATUS register
		movwf	STATUS            ; restore pre-isr STATUS register contents
		swapf   w_temp,f
		swapf   w_temp,w          ; restore pre-isr W register contents
		retfie                    ; return from interrupt

main

; remaining code goes here
		bcf		STATUS,RP0		  ;
		clrf	PORTA			  ; Initialize PORTA by
								  ; clearing output
								  ;	data latches
		bsf		STATUS,RP0		  ; Select Bank 1
		movlw	00h				  ; Value used to
								  ; initialize data
								  ; direction
		movwf	TRISA			  ; Set RA<4:0> as outputs
								  ; TRISA<7:5> are always
								  ; read as '0'

		bcf		STATUS,RP0		  ; Select Bank 0

main_loop
		bcf		PORTA,2			  ; Clear RA2
		bsf		PORTA,0		  	  ; Set RA0

		call	Delay_1s

		bcf		PORTA,0			  ; Clear RA0
		bsf		PORTA,1			  ; Set RA1

		call	Delay_1s

		bcf		PORTA,1			  ; Clear RA1
		bsf		PORTA,2			  ; Set RA2

		call	Delay_1s

		goto	main_loop

Delay_1s
		movlw	0x2D			  ; Set COUNTERs for 1s delay
		movwf	COUNT1
		movlw	0xE7
		movwf	COUNT2
		movlw	0x0B
		movwf	COUNT3

	delay_loop
		decfsz	COUNT1,1
		goto	delay_loop
		decfsz	COUNT2,1
		goto	delay_loop
		decfsz	COUNT3,1
		goto	delay_loop
		return

		END                     ; directive 'end of program'
Here it is. I've found some info about R-M-W problems caused by using bcf/bsf but using movlw/movwf to set PORTA didn't make any difference. I also tried the same program with PIC12F629 using it's internal oscillator and it was working fine. Is it possible to be a clock issue?

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

Re: Strange loop behavior

Post by phalanx » Mon Jan 30, 2017 7:25 am

The good news is I'm 99.9% sure I found your problem. In your configuration, you have the watchdog timer enabled (__CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC). In case you aren't familiar, a watchdog timer (WDT) will automatically reset the microcontroller if the timer overflows before the program executes a CLRWDT or SLEEP instruction. This is to ensure that if a program somehow gets into an unknown state, it will automatically reset after a given amount of time.

The WDT has a nominal timeout period of 18ms but there is a prescaler that can be assigned to it which is accessible through the OPTION_REG. By default, the prescaler is assigned to the WDT and has a 1:128 ratio giving you a reset time of 0.018s*128=2.304s which puts you right in the center of the third part of your pattern.

To fix this, you can do two things. The first is to insert CLRWDT instructions in key areas of your code. For your purposes, you could put one as the first instruction of your Delay_1s routine keeping in mind that as you expand your program, you may need to insert them elsewhere in your code to ensure proper operation. The other option is to simply disable the WDT in your configuration bits.

Let me know how that goes!

-Bill

evellon
Posts: 3
Joined: Sat Jan 28, 2017 4:07 pm

Re: Strange loop behavior

Post by evellon » Mon Jan 30, 2017 12:07 pm

You can now be 100% sure that you found the problem. Turning off WDT fixed the issue :)

Thank you!

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

Re: Strange loop behavior

Post by phalanx » Mon Jan 30, 2017 12:10 pm

I'm always happy when it's something simple!

-Bill

Post Reply