PIC LAB-1
P4
EXPERIMENT
7a
Hee Haw Sound
This experiment creates a Hee Haw sound for an alarm. The diagram shows
the number of cycles for the HEE and the time taken for each cycle, equates to
a certain length of time. The frequency of the HAW is lower and the number of
cycles must be worked out so that the time for the HAW is equal to the time
for the HEE.
This is simple when writing the program. The values loaded into the two files
for the HEE are reversed for the HAW.
The routine consists of two sections: HEE and HAW. Each section has two
nested loops. The inner loop creates the length of time for the HIGH and LOW
to produce a single cycle and the outer loop creates the number of
cycles.
;Expt7a.asm
;Project: Hee Haw Sound
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Hee1
Hee2
Hee3
Hee4
Haw1
Haw2
Haw3
|
ORG 0
BSF 03,5
CLRF 06
BCF 03,5
CLRF 06
GOTO Hee1
MOVLW 0FFh
MOVWF 14h
MOVLW 0C0h
BSF 06,7
NOP
DECFSZ 15h,1
GOTO Hee3
MOVLW 0C0h
MOVWF 15h
BCF 06,7
NOP
DECFSZ 15h,1
GOTO Hee4
DECFSZ 14h,1
GOTO Hee2
MOVLW 0C0h
MOVWF 14h
MOVLW 0FFh
MOVWF 15h
BSF 06,7
NOP
DECFSZ 15h,1
GOTO Haw2
MOVLW 0FFh
MOVWF 15h
BCF 06,7
NOP
DECFSZ 15h,1
GOTO Haw3
DECFSZ 14h,1
GOTO Haw1
GOTO Hee1
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.
;Clear display
;Number of loops
;The loop
file
;Duration of HIGH
;Turn on piezo
;Create the HIGH time
;Duration of the LOW
;The LOW file
;Turn off piezo
;Create the LOW time
;Decrement the loop file
;Do more cycles
;Number of loops
;The loop file
;Turn on piezo
;Create the HIGH time
;Duration of the LOW
;The LOW file
;Turn off piezo
;Create the LOW time
;Decrement the loop file
;Do more cycles
|
|
EXPERIMENT 8
A to D
Conversion
This experiment shows 0-256 parts of a 10k potentiometer on the 8 LEDs. It is
not accurate, but shows the concept of A to D conversion.
Many microcontrollers have an input that can read any value of voltage from 0v
to 5v (and higher by using a voltage divider network). Normally there are 256 steps in this range to produce a resolution of
approx 20mV for 0-5v scale. This is called an A to D input (A to D converter - analogue
input) and is ideal for measuring voltages and other values that are
classified as ANALOGUE. A very simple external circuit can
be added to measure different parameters such as the change in resistance of a temperature
probe and other analogue devices.
The PIC16F84 does not have an internal A to D converter, however we can create an A to D
feature by using two lines and a sub-routine.
To create an analogue input, a capacitor
"C" is connected in series with an unknown resistor (R) and
charged via one of the lines of the microcontroller. The diagram below
shows how this is done.
The first diagram shows a resistor
and capacitor connected in series. This is called a TIME DELAY circuit. The
capacitor is initially uncharged and the resistor charges the capacitor to
a specified value. The time taken to reach this value is called the Time
Delay.
The mid-point of the two components is called the "detection
point."
It does not matter if the resistor is above the capacitor or below. The same
Delay Time (or a similar time) will be produced.
In the second diagram the capacitor is above the resistor and if the
top line is taken HIGH, the voltage at the detection point will fall to
a specified value after a Delay Time.
If the value of the resistor is changed, the time taken for the voltage at the
detection point to reach a specified value will alter.
That's exactly what happens in the third circuit above.
The micro monitors the voltage on the detection point and when it reaches the
lower threshold for the input line, the program displays the
"count-value" on the 8 LEDs.
The other feature that has to be worked out is the time taken for the
capacitor to charge. In our circuit, the capacitor has charged before 255
loops have been executed (when the pot is at maximum resistance) and we cannot
same at a faster rate, so the maximum display-value is "DF." To
obtain a full reading, the capacitor will need to be increased in value.
;Expt8.asm
;Project: 0-256 parts of an input
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Delay
DelayA
Delay2
Look
Look2
Look3
Main
|
ORG 0
BSF 03,5
CLRF 06
MOVLW 1F
MOVWF 05
BCF 03,5
CLRF 06
GOTO Main
MOVLW 80h
MOVWF 1B
DECFSZ 1A,1
GOTO DelayA
DECFSZ 1B,1
GOTO DelayA
RETURN
NOP
DECFSZ 1A,1
GOTO Delay2
DECFSZ 1B,1
GOTO Delay2
RETURN
CLRF 0C
BSF 06,7
NOP
INCF 0C,1
BTFSC 05,4
GOTO Look2
MOVF 0C,0
MOVWF 06
CALL Delay2
CALL Delay2
CALL Delay2
BCF 06,7
CALL DelayA
RETURN
CALL Look
GOTO Main
END
|
;This is
the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Make port A input
;Go to Bank 0 - the program memory area.
;Clear display
;Create 100mS delay
;Create approx 250mS delay
;Count-down file
;Take cap HIGH
;Look2 is the counting and looking loop
;Is input LOW?
;Put file 0C into W
;Output to 8 LEDs
;Take cap low
;100mS delay
;Tells assembler end of program
|
|
EXPERIMENT 8a
Measuring Resistance
This experiment
measures resistance. You can get very low-cost digital multimeters to measure
resistance and display the value on a four digit display. We cannot compare with
cost and complexity of this type of display, but our circuit has other
features. It will activate a device when a particular value of resistance
is detected. This allows measurement of degrees of rotation of a potentiometer
or the conductivity of a liquid (via two probes), plus many other areas where
resistance values change.
Our demonstration program uses a potentiometer to detect resistance in the
range 0k to 10k however any other range can
be read, by changing the value of C. The accuracy of the circuit is determined
by
the tolerance of C (most capacitors are 10%). The time taken to produce a
low on the input is used as a jump value in a look-up table
and a display-value is obtained for the 7-segment display. For
simplicity, the values 0 to 9, plus "-" overflow, are displayed.
Further experiments show two and three-digit accuracy.
;Expt8a.asm
;Project: Resistance Scale:0-9
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Table
Delay
DelayA
Delay2
DelayB
Look
Look2
Look3
Main
|
ORG 0
BSF 03,5
CLRF 06
MOVLW 1F
MOVWF 05
BCF 03,5
CLRF 06
GOTO Main
ADDWF 02h,1
RETLW 3Fh
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh
RETLW 40h
MOVLW 80h
MOVWF 1B
DECFSZ 1A,1
GOTO DelayA
DECFSZ 1B,1
GOTO DelayA
RETURN
MOVLW 20h
MOVWF 1A
DECFSZ 1A,1
GOTO DelayB
RETURN
CLRF 0C
BSF 06,7
CALL Delay2
BTFSS 05,4
GOTO Look3
INCF 0C,1
GOTO Look2
MOVF 0C,0
CALL Table
MOVWF 06
CALL Delay
BCF 06,7
CALL Delay
RETURN
CALL Look
GOTO Main
END
|
;This is
the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Make port A input
;Go to Bank 0 - the program memory area.
;Clear display
;Add W to the Program Counter to create a jump.
;0 format= gfedcba
;1 If any table value has a leading letter, it must be
;2 preceded with a "0." E.g: 0A3h,
0FFh, 0CCh
;3
;4
;5
;6
;7
;8
;9
"-" overflow
;Create 100mS delay
;Create "Look" delay
;Count-down file
;Take cap HIGH
;This produces a long delay between looks
;Is input LOW?
;Put file 0C into W
;Output to 7-Segment display
;Take cap low
;100mS delay
|
|
EXPERIMENT
9
Pulse
Detection with a coil
This experiment
uses a coil to detect pulses. A magnet is moved past a coil and this creates a
voltage in the turns of the coil.
This is ideal for picking up the rotation of a shaft. It is non-mechanical and
will have an infinite life.
Reed switches have a very short life when used rapidly to detect shaft rotation and
have a fairly low speed of operation.
The output voltage of a coil is fairly low and needs two stages of
amplification for the signal to be large enough to be detected by the input of a microcontroller.
The clever arrangement on the front end of the analogue amplifier of the PIC
LAB-1 board allows a microphone or coil to be fitted. The coil does not
require the resistor, (it is required by the electret microphone) however it does not affect the operation. This
demonstration program increments the 7-segment display.
This allows a count-of-ten however experiments on the web include a 2
and 3-digit readout from the 7-segment display and an RPM counter.
The advantage of a magnetic pickup is the lack of switch-noise. The
pulses from the pick-up are very clean but must be debounced for low-speed
detection. The 2-stage
amplifier increases the sinewave signal and over-amplifies it to produce a
rail-to-rail signal commonly called a square-wave or digital signal.
;Expt9.asm
;Project: Pulse Detection with a coil
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Table
Delay
Main
Main1
Main2
|
ORG 0
BSF 03,5
CLRF 06
MOVLW 02
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 06
GOTO Main
ADDWF 02h,1
RETLW 3Fh
RETLW 06h
RETLW 5Bh
RETLW 4Fh
RETLW 66h
RETLW 6Dh
RETLW 7Dh
RETLW 07h
RETLW 7Fh
RETLW 6Fh
NOP
DECFSZ 1A,1
GOTO Delay
RETURN
CLRF 1E
BTFSS 05,0
GOTO Main2
BTFSC 1F,0
GOTO Main1
INCF 1E,1
MOVLW 0A
XORWF 1E,0
BTFSC 03,2
GOTO Main
MOVF 1E,0
CALL Table
MOVWF 06
CALL Delay
BSF 1F,0
GOTO Main1
BCF 1F,0
GOTO Main1
END
|
;This is
the start of memory for the program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0010
;Make RA1 input
;Go to Bank 0 - the program memory area.
;Clear the button-press file
;Clear display
;format= gfedcba
;0 If any table value has a leading
letter, it must be
;1 preceded with a
"0." E.g: 0A3h, 0FFh, 0CCh
;2
;3
;4
;5
;6
;7
;8
;9
;Create 1mS delay
;Holds the count-value
;Test the input line on port A
;LOW detected
;HIGH detected. First pass of routine?
;HIGH already detected
;First time detected. Increment count.
;Has count reached ten?
;Compare file 1E with ten
;Check the zero flag in Status file
;Count has reached ten
;Copy count into W
;W will return with display-value
;Output display value
;Debounce the coil
;Set detection flag
;Loop Main1
;Clear detection flag
;Loop Main1
;Tells assembler end of program
|
|
EXPERIMENT 10
Temperature
Detection
There are many
expensive devices
to detect temperature (thermal probes) but the cheapest is an ordinary
diode.
The voltage across a diode decreases 2mV for each °C rise in temperature.
Providing a sensitive circuit is connected to the diode, a temperate change
can be detected.
There is a problem with temperature-detecting circuits. The
transistors in the circuit also have semiconductor junctions and the voltage
across them changes at the same rate as the diode. This will upset the
detecting process if the circuit and the detector are increasing in
temperature at the same time and if some form of compensation is not included.
The amplifying circuit must be protected from a temperature-rise or some form
of thermal cancelling must be included, if you want an accurate readout.
For simplicity, we have not provided any stabilizing circuit in this
project. We are assuming the interfacing circuitry is not subject to
temperature variations. On the PIC LAB-1 PC board, the base-bias circuit
for the amplifying stage (for the "temp probe") has a fixed reference voltage
produced by
the natural characteristic of 2.1v across a green LED, making a total
reference voltage of 4.2v.
This goes part-way to the design of a stable amplifying stage.
The display shows in binary on the 8 LEDs. This gives a readout of 255
divisions and the circuit is so stable that the display will remain
static.
The first thing you can do is fit the 10k pot to the "Temp Probe"
input and rotate the shaft.
You will need to turn the shaft very slowly until you see the display begin to
change. As the resistance of the pot is reduced, the display will start
to fill up and at FF, it will be full. If the resistance is reduced further,
the counter-file 0C will fill for the second time and produce a false reading.
This is something that has to be prevented in a final version.
The pot has only a very small range where it is effective as it is simulating
the voltage across a forward-biased diode and our tests showed this to be
500mV at room temperature. Remove the pot and fit the diode. A readout of approx mid-range
will be produced.
The readout on the display increases as the temperature increases since the
program INCrements the count-file 0C. By DECrementing the counter-file 0C, the
display will decrease as the temperature rises.
The diode is so sensitive that a slight amount of warm air over to it will alter the
display.
If you touch one leg of the diode, the heat of your finger will also alter
the display.
Try not to touch both leads at the same time as the resistance of your
fingers will upset the reading. Bring a hot soldering iron near the diode
will cause the display will change - proving the diode is very sensitive to
temperature change.
The display is not graduated and this is something we will provide in a future
experiment. There are two parts of the program that will
need to be worked on, to produce a display. One part determines the
temperature and the other determines the resolution - in other words the
number of increments (or divisions) for each degree C or F.
The results are then placed in a table.
;Expt10.asm
;Project: Temperature Detection
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Delay
Delay2
DelayB
Look
Look2
Look3
Main
|
ORG 0
BSF 03,5
CLRF 06
MOVLW 04
MOVWF 05
BCF 03,5
CLRF 06
GOTO Main
NOP
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN
MOVLW 02h
MOVWF 1A
DECFSZ 1A,1
GOTO DelayB
RETURN
CLRF 0C
BSF 05,3
CALL Delay2
INCF 0C,1
BTFSC 05,2
GOTO Look2
MOVF 0C,0
MOVWF 06
CALL Delay
BSF 03,5
MOVLW 00
MOVWF 05
BCF 03,5
BCF 05,3
NOP
BCF 05,2
CALL Delay
BSF 03,5
MOVLW 04
MOVWF 05
BCF 03,5
RETURN
CALL Look
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 0100
;Make RA2 input & RA3 output
;Go to Bank 0 - the program memory area.
;Clear display
;Create approx 250mS delay
;Create 9uS delay
;Count-down file
;Take cap HIGH
;15uS delay between looks
;Is input LOW?
;Put file 0C into W
;Output to 8 LEDs
;Go to Bank 1
;Load W with 0000 0000
;Make RA2 output & RA3 output
;Go to Bank 0 - the program memory area.
;Take cap low
;Discharge capacitor
;250mS delay
;Go to Bank 1
;Load W with 0000 0100
;Make RA2 input & RA3 output
;Go to Bank 0 - the program memory area.
;Tells assembler end of program
|
|
EXPERIMENT 11
Sound Detection
There is an enormous
range of possibilities with this application. You may want to detect a
low-frequency sound, a specific frequency, a length of
tone or a combination of audio signals.
All these applications are possible with a microcontroller as the program does
all the "sorting out" and you can display the result on a LED or a
piezo.
Sometimes the design of the amplifying stages can assist in detecting a
particular frequency or amplitude. More details are provided on the website.
To see the display respond to sounds picked up by the microphone, load the
program for Experiment 9 and fit the microphone to the "mic/coil"
input. The 7-segment display will increment rapidly when HIGH's and LOW's are
being detected.
Experiment 11 is an improvement on Experiment 9.
A LED is turned on for 1mS each time a HIGH is detected.
Any noise picked up by the microphone is amplified by two transistor stages
and converted to a digital signal. The signal is OVER-AMPLIFIED (to a point of
distortion - but this does not matter as we are not listening to it as an
audio signal) so
that the amplitude is guaranteed to pass the upper and lower thresholds of the
input.
The program detects a rise and fall in amplitude of the signal to identify a
complete cycle. The program actually detects NOISE and further programs on the
web detect frequency (such as a whistle) to produce a result.
;Expt11.asm
;Project: Sound Detection
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 02
MOVWF 05
BCF 03,5
CLRF 1F
CLRF 05
CLRF 06
GOTO Main
NOP
DECFSZ 1A,1
GOTO Delay
RETURN
BTFSS 05,1
GOTO Main1
BTFSC 1F,0
GOTO Main
BSF 06,0
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 0010
;Make RA1 input
;Go to Bank 0 - the program memory area.
;Clear detection flag
;Clear the display
;Clear the display
;Create 1mS delay
;Test the input line on port A
;LOW detected
;HIGH detected. First pass of routine?
;HIGH already detected
;Turn on LED
;Turn off LED
;Set the detection flag
;Clear the detection flag
;Tells assembler end of program
|
|
EXPERIMENT 11a
Sound-to-Frequency
This experiment
converts Sound (such as a whistle) to Frequency. The row of 8 LEDs show
the frequency as a binary value. The scale is not calibrated. The program
shows the application of the internal timer (TMR0). It is set to count in the
background (with a pre-scaler). The pre-scaler divides the clock frequency by
256 in our case and when the timer rolls over from FF to 00, the timer
overflow flag (T0IF) is SET. This flag is checked in the program for a
"time-up" signal.
;Expt11a.asm
;Project: Sound to Frequency
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON
& _WDT_OFF & _RC_OSC |
SetUp
Delay
DelayA
Delay1
DelayB
Display
Main
Main1
Main2
Main3
|
ORG 00
BSF 03,5
CLRF 06
MOVLW 02
MOVWF 05
BCF 01,5
BCF 01,3
BSF 01,0
BSF 01,1
BSF 01,2
BCF 03,5
BCF 0B,7
BCF 0B,5
CLRF 05
CLRF 06
GOTO Main
MOVLW 64h
MOVWF 1B
NOP
DECFSZ 1A,1
GOTO DelayA
DECFSZ 1B,1
GOTO DelayA
RETURN
MOVLW 10
MOVWF 1A
DECFSZ 1A,1
GOTO DelayB
RETURN
BSF 0B,2
MOVF 0C,0
MOVWF 06
CALL Delay
GOTO Main
CLRF 0Ch
BTFSS 05,1
GOTO Main
CLRF 01
BCF 0B,2
CALL Delay1
INCF 0C,1
BTFSC 05,1
GOTO Main2
CALL Delay1
BTFSS 05,1
GOTO Main3
BTFSS 0B,2
GOTO Main1
GOTO Display
END
|
;Start of memory for program.
;Go to Bank 1
;Make all port B output
;Load W with 0000 0010
;Make RA1 input
;Make sure timer is incremented via internal clock
;Make sure Prescaler is assigned to TMR0
;PS0 (OPTION) Timer0 rate 1:256 (256x256uS)
;PS1 when PS0, PS1 and PS2 are SET
;PS2
;Go to Bank 0 - the program memory area.
;Disable all interrupts
;Disable the TMR0 Interrupt
;Clear display
;Clear display
;Load with 100. Create 100mS delay
;Tells assembler end of program
;reset the "time-up" flag
;Put count file into W
;Display the count on 8 LEDs
;Holds the count
;Test input line on port A
;LOW detected
;clear TMR0 register
;Clear TMR0 overflow interrupt flag
;Reduce the number of "looks" per sec
;Increment the count
;Test input line on port A
;Input is still HIGH
;Reduce the number of "looks" per sec
;Test input line on port A
;Still LOW
;Check the "time-up" flag
;HIGH detected
|
|
To Top
Next
Page
|