PIC LAB-1
P2

Use this Map for guidance
    

CONFIGURATION BITS
Before starting the Experiments, you need to know about the CONFIGURATION bits. These are the bits in the configuration file that determine some of the features of the chip. 
We are mainly concerned with the 5 lowest bits.  Note the double underbar before CONFIG.
Bits 0 and 1 select the oscillator. Bit 2 selects the watchdog timer. Bit 3 selects the Power-up timer and bit 4 selects the Code Protection. 
Setting the WDT, PWRTE and CP is also called "Setting the fuses."

Bit 4
is Code Protect. When it is "1" code protection is off. When it is "0" code protection is ON.
Bit 3 Power-up Timer Enable. When it is "1" power-up timer is enabled. When it is "0," power-up timer is disabled. The Power-up timer produces a 72mS delay and prevents the chip starting to execute code until 72mS after supply voltage has been detected. 
Bit 2 is Watchdog Timer Enable. When it is "1," watchdog timer is enabled. When it is "0," watchdog timer is disabled. 
Bits 1-0 are Oscillator Selection bits:
11 = RC oscillator - external RC components. The chip will operate from 1Hz to 4MHz.
10 = HS oscillator - High Speed crystal or resonator - maximum frequency for the chip 
01 = XT Oscillator - normal crystal oscillator - such 455kHz, 2MHz, 4MHz etc - use this for crystal. 
00 = LP Oscillator - 38kHz watch crystal 

The  __CONFIG (for this course), is shown in red:

CONFIG bits:	4	3	2	1	0
	               CP        PWRTE      WDT       FOSC1    FOSC2

                	1 	1	0	1	1        __CONFIG 1Bh
	        (code not     (enabled)      (off)          (external RC osc)
                         protected)
Note: The WDT timer bit has intentionally been SET in each of the following experiments so that you can see when a new program (or a re-burn) has been downloaded via IC-Prog. The tick beside WDT must be removed before burning commences. 
WDT
click to remove tick

Now we come to the experiments. 
ALL the files for experiments 1, 1a,1b etc to 12 are contained in: Expmts-all
After the experiments, there are a number of additional pages and projects including "21 Matches."  
Further experiments and theory can be found HERE.

EXPERIMENT 1
Turning on a LED
This experiment turns on a LED when button A is pressed. 
The button is connected to the lowest bit of Port A (bit0). When the button is pressed, the line goes HIGH. This is called positive logic. 
The LED is connected to the lowest bit of Port B (Bit0). Any bit of any port can be an input or output. It is convenient to make port "A" an input and port "B" an output. Port A has 5 lines and port B has 8 lines. 
The circuit below shows the active components for Experiment 1. The switch is connected to RA0 and the LED is connected to RB0. 


The circuit for Experiment 1

Any port-line can be changed from an input to an output or vice versa, at any time,  during the running of a program. 
If you are going to change the direction of a port-line, you must take into account any devices connected to the line. For instance, if a switch is connected between an output of the chip and rail; if the line is an output and is made LOW, the chip will be damaged when the button is pressed.  

The program consists of two loops in Main. The first instruction in Main looks at the input line and determines if the button has been pressed. This where a decision is made. If is is  not pressed, the micro is taken to the next instruction in the program and a loop is executed that makes an output line LOW to turn off a LED. If it is pressed, the micro is taken to the third instruction in Main to turn ON an output bit to illuminate a LED.  
The micro never stops executing instructions. It must be executing one loop or the other.
Main must be a loop (or more than one loop) as this is where the LED is turned ON and OFF and the microcontroller will loop this routine many times per second. 
In Main, instructions will take the micro to other routines called sub-routines, carry out operations such as delays, produce beeps, etc and return to Main, as you will see in a moment. 
Study the following experiment then click HERE for a test. 

                    ;Expt1.asm
                    ;Project: Turning on a LED
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp






Main



Main2
ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 06

BTFSS 05,0
GOTO Main2
BSF 06,0
GOTO Main
BCF 06,0
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Blank the display

;Test the input line on port A
;Button not pressed
;Button pressed. Turn on LED
;Loop Main
;Button not pressed. Turn off LED
;Loop Main

;Tells assembler end of program

EXPERIMENT 1a
Turning on a LED for 0.5sec - without debounce
This experiment turns on a LED for 0.5 sec when button "A" is pressed. It does not matter how long button "A" is pressed. The LED turns on immediately button "A" is pressed and turns off after 0.5 sec. 
If the button is kept pressed after the LED turns off, the LED turns on AGAIN as the program detects noise from the switch. 
This highlights the need for DEBOUNCE. 
Debounce is shown in the next experiment. 
There are variations of this: The LED can turn on for 0.5sec AFTER the button has been released (Experiment 1d) or the LED can turn on for 0.5sec MORE than the button-press time (Experiment 1e).  
All these programs show how to control the output. You can extend the program to two flashes or a delay between flashes or a flash then turn on a LED or driver transistor to operate a globe or motor, or any other output device. 
This program is an extension of Experiment 1, with the introduction of a delay. 
The maximum delay for 2 files is 250mS. To achieve 500mS, the Delay sub-routine is called two times. This requires less instructions than creating a 500mS delay, and is simpler to understand. 
The program is shown below and an alternate program is shown that controls the driver transistor. 
The control of a single line of the output port is called BIT MANIPULATION. 
Two or more output lines can be controlled at the same time by loading W with a hex value and moving the value to file 06. If this is done, all the output lines will be affected and if a line is HIGH and the corresponding bit in the instruction is "0" the line will change state. This may not be wanted and that's why bit manipulation is the safest. 

                    ;Expt1a.asm
                    ;Project: LED on for 0.5sec. No debounce
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp








Delay






Main









Main1
ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN

BTFSS 05,0
GOTO Main1
BTFSC 1F,0
GOTO Main
BSF 06,0
CALL Delay
CALL Delay
BCF 06,0
BSF 1F,0
GOTO Main
BCF 1F,0
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Blank the display


;Create approx 250mS delay






;Test the input line on port A
;Button not pressed
;Button pressed first time?
;Button already pressed
;First time button pressed. Turn on LED
;Illuminate for 250mS
;Illuminate for 250mS
;Turn off LED
;Set button-press flag
;Loop Main
;Clear button-press flag
;Loop Main

Main












Main1
BTFSS 05,0
GOTO Main1
BTFSC 1F,0
GOTO Main
BSF 06,0
BSF 06,7
CALL Delay
CALL Delay
BCF 06,0
CALL Delay
BCF 06,7
BSF 1F,0
GOTO Main
BCF 1F,0
GOTO Main

END
;Test the input line on port A
;Button not pressed
;Button pressed first time?
;Button already pressed
;First time button pressed. Turn on LED
;Turn on driver transistor
;Illuminate for 250mS
;Illuminate for 250mS
;Turn off LED
;Keep driver transistor ON
;Turn off driver transistor
;Set button-press flag
;Loop Main
;Clear button-press flag
;Loop Main

;Tells assembler end of program

EXPERIMENT 1b
Turning on a LED for 0.5sec - with debounce
This experiment turns on a LED for 0.5 sec when button "A" is pressed. The LED does not turn on when the button is released. The secret is the very short delay 7x256uS at Main 1. This is just long enough to cover the time when the switch is being released. Release the switch very slowly and you will see the LED illuminate. This proves the delay is just covering the noise from the release of the switch. 
Study the following experiment then click HERE for a test. 

                  ;Expt1b.asm
                  ;Project: LED on for 0.5sec with debounce
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp








Delay






Main



Main1













Main2
ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN

BTFSS 05,0
GOTO Main2
BTFSC 1F,0
GOTO Main
NOP
NOP
NOP
NOP
DECFSZ 1A,1
GOTO Main1
BTFSS 05,0
GOTO Main2
BSF 06,0
CALL Delay
CALL Delay
BCF 06,0
BSF 1F,0
GOTO Main
BCF 1F,0
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Blank the display


;Create approx 250mS delay
;Decrement file 1A
;Loop
;Decrement file 1B
;Loop
;Return

;Test the input line on port A
;Button not pressed
;Button pressed first time?
;Button already pressed
;No Operation



;
Create short delay
;Look again
;Is switch still pressed?
;It was only noise
;Turn on LED
;Illuminate for 250mS
;Illuminate for 250mS
;Turn off LED
;Set button-press flag
;Loop Main
;Clear button-press flag
;Loop Main

EXPERIMENT 1c
Two pushes to turn on a LED for 0.5sec
This experiment turns on a LED for 0.5 sec after two presses of the push-button. The program shows how to take control of a push-button to recognise a particular sequence of presses or length of press etc.  A program must "poll" or "look-at" an input on a regular basis and hold the information in a file called a "flag file," then go to the Main routine and carry out other operations. 
The micro must not get stuck in a sub-routine, as it always has other things to do. The program below shows how to place the switch instructions in a sub-routine and the Main program looks at the state of the button via a flag file. 

                    ;Expt1c.asm
                    ;Project: Two pushes to turn on a LED
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp








Delay






Delay2




Sw














Sw2


Sw3



Main





ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN

NOP
DECFSZ 1A,1
GOTO Delay2
RETURN

BTFSS 05,0
GOTO Sw3
BTFSC 1F,2
RETURN
BTFSC 1F,0
RETLW 00
BTFSS 1F,1
GOTO Sw2
BSF 06,0
CALL Delay
CALL Delay
BCF 1F,1
BSF 1F,2
BCF 06,0
RETURN
BSF 1F,1
BSF 1F,0
RETURN
BCF 1F,0
BCF 1F,2
RETURN

CALL Sw
CALL Delay2
other instructions
other instructions
BCF 1F,0
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Blank the display


;Create approx 250mS delay






;Create 1mS debounce delay




;Test the push button
;Button not pressed
;Test end-of-flash flag

;First pass?
;No
;Test first-press flag
;First press
;Button has been pressed twice. Illuminate LED
;Keep LED on
;Keep LED on
;Clear second-push flag bit
;Set end-of-flash flag
;Turn LED off

;Set the first-press flag
;Set button pass flag bit

;Clear button pass flag bit
;Clear end-of-flash flag




;Carry out other instructions

;Clear first-push flag bit


;Tells assembler end of program

EXPERIMENT 1d
LED turns on for 0.5sec after button released
This experiment shows how to turn on an output when a button has been released. 

                    ;Expt1d.asm
                    ;Project: LED ON when button released
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp








Delay






Delay2




Sw



Sw2








Main





ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN

NOP
DECFSZ 1A,1
GOTO Delay2
RETURN

BTFSS 05,0
GOTO Sw2
BSF 1F,0
RETURN  
BTFSS 1F,0
RETURN
BSF 06,0
CALL Delay
CALL Delay
BCF 1F,0
BCF 06,0
RETURN

CALL Sw
CALL Delay2
other instructions
other instructions
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Blank the display


;Create approx 250mS delay






;Create 1mS debounce delay




;Test the push button
;Button not pressed
;Button is pressed. Set the button-press flag
;Return


;Illuminate LED
;Keep LED on
;Keep LED on
;Clear button flag bit
;Turn LED off



;Debounce switch
;Carry out other instructions



;Tells assembler end of program

EXPERIMENT 1e
LED stays on 0.5sec longer than the button-press time

This experiment shows how to turn on an output for 0.5sec longer than button-press time. It's just a matter of adding a single instruction into the program. BSF 06,0 is added in Sw sub-routine.

                    ;Expt1e.asm
                    ;Project: LED ON for 0.5s more than
                    ;         button-press time.
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp








Delay






Delay2




Sw




Sw2








Main





ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN

NOP
DECFSZ 1A,1
GOTO Delay2
RETURN

BTFSS 05,0
GOTO Sw2
BSF 1F,0
BSF 06,0
RETURN  
BTFSS 1F,0
RETURN
BSF 06,0
CALL Delay
CALL Delay
BCF 1F,0
BCF 06,0
RETURN

CALL Sw
CALL Delay2
other instructions
other instructions
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Blank the display


;Create approx 250mS delay






;Create 1mS debounce delay




;Test the push button
;Button not pressed
;Button is pressed. Set the button-press flag
;Turn on LED
;Return
;Test to see if button is pressed
;Return
; Illuminate LED
;Keep LED on
;Keep LED on
;Clear button flag bit
;Turn LED off



;Debounce switch
;Carry out other instructions



;Tells assembler end of program

EXPERIMENT 1f
Flash a LED
This experiment shows how to flash a LED. To make the LED flash with an on-time of  0.25seconds and off-time of 0.75seconds requires a 4-step program shown in the Flowchart below:

From the flow-chart you can see you need to do 4 things: 
1. Turn ON an output
2. Keep the output ON for a period of time - called the Delay time
3. Turn OFF the output
4. Keep the output turned OFF for a period of time - called the Delay time

The processor (the heart of the microcontroller chip) must be kept running all the time. The PIC16F84 chip requires external components to complete the oscillator circuit. By using a 4k7 and 22p capacitor the oscillator will operate a 4MHz. This frequency is internally divided by 4 so that one instruction is processed every microsecond. This makes it very easy to produce accurate delay routines.

                    ;Expt1f.asm
                    ;Project: Flash a LED
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp





Delay






Main





ORG 0
BSF 03,5
CLRF 06
BCF 03,5
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN

BSF 06,0
CALL Delay
BCF 06,0
CALL Delay
CALL Delay
CALL Delay
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Go to Bank 0 - the program memory area.
;Blank the display


;Create approx 250mS delay






;Turn on LED
; Illuminate LED
;Turn LED off



;Loop the program

;Tells assembler end of program

EXPERIMENT 2
Toggle a LED
This experiment toggles the push button. Each time the button is pressed, a LED changes state. 
The program introduces a very simple DEBOUNCE feature. All switches must be debounced to prevent false counting or false detection. 
All switches produce noise and the micro is executing a program so quickly that it will pick up multiple pulses from a switch, each time it is pressed or released. To prevent this from happening we need to look at the push button at intervals that will prevent false counting. 
The simplest debounce is a delay routine. The micro only looks at the button at intervals, dictated by the length of the delay. As soon as the push button is detected, the micro executes an XOR instruction that toggles the output line to change the state of the LED. It then goes to a delay sub-routine and when it returns, it looks for the release of the button. 
This represents one cycle of the program and when the button is pressed again, the output line is toggled once more. 
The program requires two separate loops as the micro is executing instructions at 1 million per second and a loop is executed so quickly that the micro can see the press of a button many times if the loop is not extended. One loop is the "pressed loop" and the other is the "not pressed loop." 
The program introduces the "button-press" flag. This is the lowest bit (bit0) in file 1F. You can use any file but the PIC Programming Course uses files 1E and 1F for flags. There are three instructions relating to this flag: The instruction to test the flag: BTFSC 1F,0  the instruction to set the flag: BSF 1F,0  and the instruction to clear the flag: BCF 1F,0  They must be placed in the program in the correct order, for the flag-bit to work. The delay can be increased until absolutely no false-triggering is produced.  This will limit the speed of operation of the button and if a high-speed input is required, the pulses must be clean.

                    ;Expt2.asm
                    ;Project: Toggle a LED
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp








Delay




Main








Main2
ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main

NOP
DECFSZ 1A,1
GOTO Delay
RETURN

BTFSS 05,0
GOTO Main2
CALL Delay
BTFSC 1F,0
GOTO Main
MOVLW 01
XORWF 06,1
BSF 1F,0
GOTO Main
CALL Delay
BCF 1F,0
GOTO Main

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Blank the display 


;Create 1mS debounce delay


;Return

;Test the input line on port A
;Button not pressed
;Debounce the button
;Button pressed first time?
;Button already pressed
;First time button pressed
;Toggle LED
;Set button-press flag
;Loop Main
;Button not pressed. Call Delay
;Clear button-press flag
;Loop Main

;Tells assembler end of program

EXPERIMENT 3
Running LEDs

The program runs a single LED forward and back across the 8 LEDs.  When the push button is pressed, the action stops. Releasing the button enables the action.
This program shows the "shift-left, shift right" feature. The contents of any file can be shifted. We can detect a single bit "dropping off either end of a file" as it is shifted into a location called the CARRY - located in another file called the Status file. The address of the Carry is file 03, bit0. 
If we test for a bit in the carry, we can move a single bit back and forth across a file and thus output this result on a set of LEDs to get a RUNNING LED effect. 
The program also constantly looks for the press of the push button to halt the effect. 
The Delay is an extension of the sub-routine above. It uses the 1mS delay and loops it 100 times by decrementing file 1B. The interesting feature is the inclusion of two RLF 06,1. They shift the LED from the end so that all the LEDs illuminate equally. 

                    ;Expt3.asm
                    ;Project: Running LEDs
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh    ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

SetUp







Delay

Delay1




Delay2



Main

Main2
Main3




Main4
Main5
ORG 0
BSF 03,5
CLRF 06
MOVLW 01
MOVWF 05
BCF 03,5
BCF 03,0
GOTO Main

MOVLW 64h
MOVWF 1B
NOP
DECFSZ 1A,1
GOTO Delay1
DECFSZ 1B,1
GOTO Delay1
BTFSC 05,0
GOTO Delay2
RETURN

MOVLW 01
MOVWF 06
RLF 06,1
RLF 06,1
BTFSC 03,0
GOTO Main4
CALL Delay
GOTO Main3
RRF 06,1
RRF 06,1
BTFSC 03,0
GOTO Main2
CALL Delay
GOTO Main5

END
;This is the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0001
;Make RA0 input
;Go to Bank 0 - the program memory area.
;Clear the carry flag


;Load W with 100. Create 100mS delay






;Look at input
;Button pressed. Stop action


;Put 0000 0001 into W
;Illuminate the lowest LED
;Shift to the left so that end LED shows equal time
;Shift LED to the left.
;Has LED reached end of display?
;Yes
;No. Illuminate LED
;Loop shift-left instructions. 
;Shift to the right so that end LED shows equal time
;Shift LED to the right.
;Has LED reached end of display?
;Yes. 
;No. Illuminate LED
;Loop shift-right instructions.

;Tells assembler end of program

To Top