PIC LAB-1
P2
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.
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 1 f
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
|