
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
ORG 0 ;This is the start of memory for the program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 06 ;Clear display
GOTO Hee1
Hee1 MOVLW 0FFh ;Number of loops
MOVWF 14h ;The loop file
Hee2 MOVLW 0C0h ;Duration of HIGH
BSF 06,7 ;Turn on piezo
Hee3 NOP
DECFSZ 15h,1 ;Create the HIGH time
GOTO Hee3
MOVLW 0C0h ;Duration of the LOW
MOVWF 15h ;The LOW file
BCF 06,7 ;Turn off piezo
Hee4 NOP
DECFSZ 15h,1 ;Create the LOW time
GOTO Hee4
DECFSZ 14h,1 ;Decrement the loop file
GOTO Hee2 ;Do more cycles
MOVLW 0C0h ;Number of loops
MOVWF 14h ;The loop file
Haw1 MOVLW 0FFh
MOVWF 15h
BSF 06,7 ;Turn on piezo
Haw2 NOP
DECFSZ 15h,1 ;Create the HIGH time
GOTO Haw2
MOVLW 0FFh ;Duration of the LOW
MOVWF 15h ;The LOW file
BCF 06,7 ;Turn off piezo
Haw3 NOP
DECFSZ 15h,1 ;Create the LOW time
GOTO Haw3
DECFSZ 14h,1 ;Decrement the loop file
GOTO Haw1 ;Do more cycle
GOTO Hee1
END
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
ORG 0 ;This is the start of memory for the program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
MOVLW 1F
MOVWF 05 ;Make port A input
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 06 ;Clear display
GOTO Main
Delay MOVLW 80h ;Create 100mS delay
MOVWF 1B
DelayA DECFSZ 1A,1
GOTO DelayA
DECFSZ 1B,1
GOTO DelayA
RETURN
Delay2 NOP ;Create approx 250mS delay
DECFSZ 1A,1
GOTO Delay2
DECFSZ 1B,1
GOTO Delay2
RETURN
Look CLRF 0C ;Count-down file
BSF 06,7 ;Take cap HIGH
Look2 NOP ;Look2 is the counting and looking loop
INCF 0C,1
BTFSC 05,4 ;Is input LOW?
GOTO Look2
Look3 MOVF 0C,0 ;Put file 0C into W
MOVWF 06 ;Output to 8 LEDs
CALL Delay2
CALL Delay2
CALL Delay2
BCF 06,7 ;Take cap low
CALL DelayA ;100mS delay
RETURN
Main CALL Look
GOTO Main
END ;Tells assembler end of program
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
ORG 0 ;This is the start of memory for the program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
MOVLW 1F
MOVWF 05 ;Make port A input
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 06 ;Clear display
GOTO Main
Table ADDWF 02h,1 ;Add W to the Program Counter to create a jump.
RETLW 3Fh ;0 format= gfedcba
RETLW 06h ;1 If any table value has a leading letter, it must be
RETLW 5Bh ;2 preceded with a "0." E.g: 0A3h, 0FFh, 0CCh
RETLW 4Fh ;3
RETLW 66h ;4
RETLW 6Dh ;5
RETLW 7Dh ;6
RETLW 07h ;7
RETLW 7Fh ;8
RETLW 6Fh ;9
RETLW 40h "-" overflow
Delay MOVLW 80h ;Create 100mS delay
MOVWF 1B
DelayA DECFSZ 1A,1
GOTO DelayA
DECFSZ 1B,1
GOTO DelayA
RETURN
Delay2 MOVLW 20h ;Create "Look" delay
MOVWF 1A
DelayB DECFSZ 1A,1
GOTO DelayB
RETURN
Look CLRF 0C ;Count-down file
BSF 06,7 ;Take cap HIGH
Look2 CALL Delay2 ;This produces a long delay between looks
BTFSS 05,4 ;Is input LOW?
GOTO Look3
INCF 0C,1
GOTO Look2
Look3 MOVF 0C,0 ;Put file 0C into W
CALL Table
MOVWF 06 ;Output to 7-Segment display
CALL Delay
BCF 06,7 ;Take cap low
CALL Delay ;100mS delay
RETURN
Main CALL Look
GOTO Main
END
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
ORG 0 ;This is the start of memory for the program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
MOVLW 02 ;Load W with 0000 0010
MOVWF 05 ;Make RA1 input
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 1F ;Clear the button-press file
CLRF 06 ;Clear display
GOTO Main
Table ADDWF 02h,1 ;format= gfedcba
RETLW 3Fh ;0 If any table value has a leading letter, it must be
RETLW 06h ;1 preceded with a "0." E.g: 0A3h, 0FFh, 0CCh
RETLW 5Bh ;2
RETLW 4Fh ;3
RETLW 66h ;4
RETLW 6Dh ;5
RETLW 7Dh ;6
RETLW 07h ;7
RETLW 7Fh ;8
RETLW 6Fh ;9
Delay NOP ;Create 1mS delay
DECFSZ 1A,1
GOTO Delay
RETURN
Main CLRF 1E ;Holds the count-value
Main1 BTFSS 05,0 ;Test the input line on port A
GOTO Main2 ;LOW detected
BTFSC 1F,0 ;HIGH detected. First pass of routine?
GOTO Main1 ;HIGH already detected
INCF 1E,1 ;First time detected. Increment count.
MOVLW 0A ;Has count reached ten?
XORWF 1E,0 ;Compare file 1E with ten
BTFSC 03,2 ;Check the zero flag in Status file
GOTO Main ;Count has reached ten
MOVF 1E,0 ;Copy count into W
CALL Table ;W will return with display-value
MOVWF 06 ;Output display value
CALL Delay ;Debounce the coil
BSF 1F,0 ;Set detection flag
GOTO Main1 ;Loop Main1
Main2 BCF 1F,0 ;Clear detection flag
GOTO Main1 ;Loop Main1
END ;Tells assembler end of program
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
ORG 0 ;This is the start of memory for the program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
MOVLW 04 ;Load W with 0000 0100
MOVWF 05 ;Make RA2 input & RA3 output
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 06 ;Clear display
GOTO Main
Delay NOP ;Create approx 250mS delay
DECFSZ 1A,1
GOTO Delay
DECFSZ 1B,1
GOTO Delay
RETURN
Delay2 MOVLW 02h ;Create 9uS delay
MOVWF 1A
DelayB DECFSZ 1A,1
GOTO DelayB
RETURN
Look CLRF 0C ;Count-down file
BSF 05,3 ;Take cap HIGH
CALL Delay2 ;15uS delay between looks
Look2 INCF 0C,1
BTFSC 05,2 ;Is input LOW?
GOTO Look2
MOVF 0C,0 ;Put file 0C into W
Look3 MOVWF 06 ;Output to 8 LEDs
CALL Delay
BSF 03,5 ;Go to Bank 1
MOVLW 00 ;Load W with 0000 0000
MOVWF 05 ;Make RA2 output & RA3 output
BCF 03,5 ;Go to Bank 0 - the program memory area.
BCF 05,3 ;Take cap low
NOP
BCF 05,2 ;Discharge capacitor
CALL Delay ;250mS delay
BSF 03,5 ;Go to Bank 1
MOVLW 04 ;Load W with 0000 0100
MOVWF 05 ;Make RA2 input & RA3 output
BCF 03,5 ;Go to Bank 0 - the program memory area.
RETURN
Main CALL Look
GOTO Main
END ;Tells assembler end of program
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
ORG 0 ;This is the start of memory for the program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
MOVLW 02 ;Load W with 0000 0010
MOVWF 05 ;Make RA1 input
BCF 03,5 ;Go to Bank 0 - the program memory area.
CLRF 1F ;Clear detection flag
CLRF 05 ;Clear the display
CLRF 06 ;Clear the display
GOTO Main
Delay NOP ;Create 1mS delay
DECFSZ 1A,1
GOTO Delay
RETURN
Main BTFSS 05,1 ;Test the input line on port A
GOTO Main1 ;LOW detected
BTFSC 1F,0 ;HIGH detected. First pass of routine?
GOTO Main ;HIGH already detected
BSF 06,0 ;Turn on LED
CALL Delay
BCF 06,0 ;Turn off LED
BSF 1F,0 ;Set the detection flag
GOTO Main
Main1 BCF 1F,0 ;Clear the detection flag
GOTO Main
END ;Tells assembler end of program
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
ORG 00 ;Start of memory for program.
SetUp BSF 03,5 ;Go to Bank 1
CLRF 06 ;Make all port B output
MOVLW 02 ;Load W with 0000 0010
MOVWF 05 ;Make RA1 input
BCF 01,5 ;Make sure timer is incremented via internal clock
BCF 01,3 ;Make sure Prescaler is assigned to TMR0
BSF 01,0 ;PS0 (OPTION) Timer0 rate 1:256 (256x256uS)
BSF 01,1 ;PS1 when PS0, PS1 and PS2 are SET
BSF 01,2 ;PS2
BCF 03,5 ;Go to Bank 0 - the program memory area.
BCF 0B,7 ;Disable all interrupts
BCF 0B,5 ;Disable the TMR0 Interrupt
CLRF 05 ;Clear display
CLRF 06 ;Clear display
GOTO Main
Delay MOVLW 64h ;Load with 100. Create 100mS delay
MOVWF 1B
DelayA NOP
DECFSZ 1A,1
GOTO DelayA
DECFSZ 1B,1
GOTO DelayA
RETURN
Delay1 MOVLW 10
MOVWF 1A ;Tells assembler end of program
DelayB DECFSZ 1A,1
GOTO DelayB
RETURN
Display BSF 0B,2 ;reset the "time-up" flag
MOVF 0C,0 ;Put count file into W
MOVWF 06 ;Display the count on 8 LEDs
CALL Delay
GOTO Main
Main CLRF 0Ch ;Holds the count
BTFSS 05,1 ;Test input line on port A
GOTO Main ;LOW detected
CLRF 01 ;clear TMR0 register
BCF 0B,2 ;Clear TMR0 overflow interrupt flag
Main1 CALL Delay1 ;Reduce the number of "looks" per sec
INCF 0C,1 ;Increment the count
Main2 BTFSC 05,1 ;Test input line on port A
GOTO Main2 ;Input is still HIGH
Main3 CALL Delay1 ;Reduce the number of "looks" per sec
BTFSS 05,1 ;Test input line on port A
GOTO Main3 ;Still LOW
BTFSS 0B,2 ;Check the "time-up" flag
GOTO Main1 ;HIGH detecte
GOTO Display
END
Quick Links
Legal Stuff
Social Media