Jake's Electronics

a place to document


Flashing LED

When first starting with Microcontrollers and programming, one of the first projects people like to build is a flashing LED. For a beginner, the whole process of going from a bunch of components scattered over their work desk to a functioning Microcontroller controlled system is extremely satisfying. It is not only satisfying but can also be a little bit daunting so the first logical step when starting out is to be able to control an LED.

What Is It:

This circuit is simply a Flashing LED controller by a Microchip PIC Microcontroller.


Flashing LED Breadboard


How it works:

As this is an extremely basic circuit there isn't too much to it. Although there are a few fundamental steps when it comes to Microcontrollers no matter what the project.

Please note that when referring to line numbers I am referring to the full program listing under the 'Source Code' heading below.

First, like with any project, the processor (line 11), the processor's include file (line 12), and the device configuration bits (line 13) are specified. Proceeding this, a block of constants are defined (line 33) to give meaningful names to the general purpose RAM registers that will be used within the program. This is not necessary however it is recommended as it makes the program easier to read and debug. For example, replacing the numerical RAM address of H'20' with the word DELAYGPR1 is much easier to understand as it has semantic meaning, as shown below.

        MOVLW    H'4E'                  ; Move literal hexadecimal number 4E (deciaml 78) to Working register
        MOVWF    H'20'                  ; Move value stored in W register to RAM address H'20'

Replaced by;

        MOVLW    H'4E'                  ; Move literal hexadecimal number 4E (deciaml 78) to Working register
        MOVWF    DELAYGPR1              ; Move value stored in W register to RAM address H'20'

Following this the originate vectors are specified (line 39 & 42). These outline where the program should originate from. Although not necessary and although this program doesn't use interrupts, it is good practice to specify these address pointers but these can be ignored for this program.

Now we get into the meat of the program. The SETUP sub-routine (line 46) sets which pins should be inputs and which should be outputs. It also turns the comparator function off so pins that have dual function can be used for inputs or outputs. The FLASHLOOP sub-routine does exactly as the label suggests. It flashes the LED and loops. Let's look at this sub-routine line by line.

Line 63:

        BSF     PORTA, 0                ; Set PORTA, 0 (pin 17)

The BSF instruction stands for Bit Set in File register. It is basically saying turn bit 0 within File register PORTA, which is a physical I/O port of the device. Pin 17 to be exact. So to make it even clearer, turn pin 17 on!.

Line 64:

        CALL    DELAY_250mS             ; Execute Delay

The CALL instruction causes a jump to a specific location in the program memory so a piece of code can be executed. In this project, the internal clock is clocking the program at around 4Mhz or 1 instruction per micro second or 1 million instructions per second. Simply turning the LED on then off would flash the LED way too fast for the human eye to see. Therefore a delay is inserted between turning the LED on and off. As this delay is going to be used between turning the LED on and off and between turning the LED off and on, we can use a CALL instruction to call a sub-routine when we need it, instead of having to write the delay twice (or more). So the CALL instruction at line 64 forces the program to jump to line 70 where the delay will be executed. I wont go into detail about how the delay works as it has been covered numerous times on the web. Just Google "PIC Microcontroller Delay Routine". But I will mention that when a CALL instruction is executed, a RETURN or RETLW must be executed when the sub-routine is over so the program can resume where it was originally interrupted.

Line 65:

        BCF     PORTA, 0                ; Clear PORTA, 0 (pin 17)

The BCF instruction stands for Bit Clear in File register. Just like the BSF instruction turns an output pin on, the BCF turns it off.

Once again, a CALL instruction (line 66) calls the delay sub-routine

Line 67:

        GOTO    FLASHLOOP               ; GOTO FLASHLOOP and loop over

Unlike a CALL instruction, the GOTO instruction forces a jump to a specific location in the program memory and will simply continue from there. Before a CALL instruction forces a program memory jump, it will save the current program address. When the called sub-routine is finished and the RETURN instruction is executed, the saved program memory address is loaded from the stack so the program can go back and resume. The PIC16F628A has a stack 6 deep. So you can have a maximum of 6 nested CALLs or CALL within a CALL times 6. The GOTO instruction does not save the program memory address location nor does it require a RETURN instruction. It simply re-routes the program when it reaches a GOTO and this is exactly what is needed at this point in the program. The program has turned the LED on and off, now go back and do it again!

Source Code:

;                                                                                                  ;
;                        Program: Blinking LED                                                     ;
;                        Author:  Jake Sutherland                                                  ;
;                        Start Date: Monday 25th August 2008                                       ;
;                        Finish Date:                                                              ;
;                        Comments: Revised 2013                                                    ;
;                                                                                                  ;

        LIST            P=PIC16F628A
        INCLUDE         P16F628A.INC
        errorlevel      -302    ;Eliminate bank warning

;                                                                                                  ;
;                                   PIC16F628A Microcontroller                                     ;
;                                            ____ ____                                             ;
;                             VREF/AN2/RA2 -| 1  - 18 |- RA1/AN1                                   ;
;                             CPM1/AN3/RA3 -| 2    17 |- RA0/AN0                  LED via Resistor ;
;                           CMP2/T0CKI/RA4 -| 3    16 |- RA7/OSC1/CLKIN                            ;
;                             VPP/MCLR/RA5 -| 4    15 |- RA6/OSC2/CLKOUT                           ;
;                                      VSS -| 5    14 |- VDD                                       ;
;                                  INT/RB0 -| 6    13 |- RB7/T1OSC1/ICSPDAT                        ;
;                                DT/RX/RB1 -| 7    12 |- RB6/T1OSCO/T1CLKI/ICSPCLK                 ;
;                                CK/TX/RB2 -| 8    11 |- RB5                                       ;
;                                 CCP1/RB3 -|_9____10_|- RB4/PGM                                   ;
;                                                                                                  ;
;                                                                                                  ;

DELAYGPR1                               ; Variable used for temporary information storage in the delay subroutines
DELAYGPR2                               ; Variable used for temporary information storage in the delay subroutines
DELAYGPR3                               ; Variable used for temporary information storage in the delay subroutines

        ORG     0x000                   ; Processor reset vector location. On power up, the program jumps here
        GOTO    SETUP                   ; 

        ORG     0x004                   ; Interrupt vector location. When an Interrupt occurs, the program jumps here
        GOTO    SETUP                   ; 

SETUP  ; This routine initialises the chip, setting the inputs and outputs
        CLRF    PORTA                   ; Initialise PORT A by setting output data latches
        CLRF    PORTB                   ; Initialise PORT B by setting output data latches
        MOVLW   H'07'                   ; Turn Comparators off and enable pins for I/O functions
        MOVWF   CMCON                   ;
        BCF     STATUS, RP1             ; Bank 1
        BSF     STATUS, RP0             ; Bank 1
        MOVLW   B'11100000'             ; RA<7:5>, Inputs. RA<4:0> Outputs.
        MOVWF   TRISA                   ;

        MOVLW   B'11110011'             ; RB<7:4> Inputs. RB<3:2> Outputs.  RB<0:1> Inputs.
        MOVWF   TRISB                   ;

        BCF     STATUS, RP1             ; Bank 0
        BCF     STATUS, RP0             ; Bank 0
FLASHLOOP  ; This routine loops continuously, simply setting and clearing PORTA, 0 (pin 17) with a quarter second delay (approx) in between
        BSF     PORTA, 0                ; Set PORTA, 0 (pin 17)
        CALL    DELAY_250mS             ; Execute Delay
        BCF     PORTA, 0                ; Clear PORTA, 0 (pin 17)
        CALL    DELAY_250mS             ; Execute Delay
        GOTO    FLASHLOOP               ; GOTO FLASHLOOP and loop over 

DELAY_250mS  ; Actual delay = 0.25 seconds = 250000 cycles
        MOVLW   H'4E'                   ;
        MOVWF   DELAYGPR1               ;
        MOVLW   H'C4'                   ;
        MOVWF   DELAYGPR2               ;
DELAY_250mS_0                           ;
        DECFSZ  DELAYGPR1, F            ;
        GOTO    $+D'2'                  ;
        DECFSZ  DELAYGPR2, F            ;
        GOTO    DELAY_250mS_0           ; 249993 cycles
        GOTO    $+D'1'                  ;
        NOP                             ; 3 cycles
        RETURN                          ; 4 cycles (including call)

END                                     ; Directive 'end of program'
.asm File Icon .hex File Icon


Flashing LED Schematic

Parts List:

Part Quantity Schematic Designator
PIC16F628A Microcontroller 1 U1
LED 1 D1
1KΩ 1 R1
.1μF Multilayer Ceramic 1 C1
Breadboard 1  
Jumper Wire    
Power Requirements    
5 Volt DC Regulated, 100mAh