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:

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.

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?

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.