Disco disco disco... Hello and in today's video I'm going
to be covering the comparator module and interrupt
based programming. Now let's first go over the
hardware connections. I have a variable resistor
connected on VCC and ground on its full resistance pins. From the tap pin. I connect to RA0 RA1
and RE2. Which is analogue input 0 1 and 7 as
AN1 and AN0 is going to be comparator 1 and
2s voltage input and then AN7 is just going to be a read and then I have a LEDs connected
to the B PORT and I'm only going to be using RB0 and RB7. As to indicate which comparator
is currently out putting and then I have an usb-to-serial connected to RX and TX of the
PIC to show the current voltage that the reference voltage is at. Now let's have a look at the
datasheet. Now the comparator is controlled by the CMCON register or comparator control
register in bit 7 it gives you the output bit
of comparator number 2 by one indicating
that the comparator is active or inactive and for this case I'm going to invert the
output of comparator 2. So it will be one when Vin+ is less than Vin-
and then the opposite for comparator 1. Which will not be inverted. So a 1 will
be when Vin+ is greater than Vin- and these two bits are read only. Then we have
bit 5 and 4 which will either invite your comparator
or give you a non inverted output. In this
case I'm going to invert computer module to So C2INV will be 1 and then for comparator
1 C1 invert will be 0 to give us a non-inverted output. Then we have bit 3 which is the comparator
inputs switch bit which will determine which input pins we use for Vin- on our
comparator and in this case it will be 0. So that we use AN4 for comparator 1 and
AN1 for comparator 2. Then we have the comparator mode select bit. Which is from bit 0 to bit 3.
Then they have functional description of each type of mode we can use. We have the comparator
reset. Where we use AN0 and AN3 as our comparator inputs for comparator 1. Then
we have AN1 and AN2 which we use as input for comparator 2 but the outputs are
off and then we have triple 1 state which is just the competitors are completely off
and grounded and disconnected from their respective input pins. Then we have the normal states
where we can use them as two independent comparators. Each one with their own output. Then we have
independent competitors with dedicated output. Where... With each respective input pins
but you can directly output the state of the comparator onto RA4 and RA5 respectively.
Then we have the common reference. Witch just connects the Vin+ to both competitors
from AN3. Then we have the two common reference comparators which is the same as the common
reference comparator but your output is on RA4 and RA5 as well. Then we have one
independent comparator which just switches off comparator 2 and then only CIN1
will work with its respective inputs and then also output on RA4 and then we have the
mode that I'm going to use which is the four input Multiplex to 2 comparators which I am
only going to use AN1 for comparator 1 and AN1 for comparator 2 but the main thing is
here you can use the internal voltage reference for your Vin+ and that will be 1110 which
is if I remember correctly 6. Then the next register we're going to have a look at is CVRCON
register which is the comparator voltage reference register. Now in bit 7 it turns the
circuit on or off my default it is power down. Then we have the comparator Vref output enable
bit which one going to sit as 0. So that we have no output on the pin originally wanted it
to output on the pin. So that we actually physically see what the voltage is but my
craptastic voltmeter does not trigger at the voltages. Then we have the comparator voltage
reference the select bit. This just sets the resolution of the comparator. The one I'm
going to use is 0 for 0.25 resolution to 0.75 resolution. Then we have bit 4 witch is the voltage reference source select
bit and I'm going to use my voltage reference source as VDD and VSS. So my supply voltages and
then we have a CVR bit selectors which can only range from value 0 to 15 and then depending
on what are CVRR bit is in bit 5. We use one of these two formulas. Now if we have a look
in those formulas in my Excel sheet you can see that when CVRR is equals to 1
our maximum reference point is 3.125 volts and all the steps in between from 0 volts
and then if our CVRR is equal to 0 our minimum reference point is 1.25 volts and 3.59 volts
at maximum with a reference voltage of 5. Now back to the datasheet and then we have a diagram
of the function of the reference voltage output. Where we can see it's just a resistor divider
network with the CVRR enable and an extra resistor into the network and then based off
whatever our selection... our measuring selection point is will be CVref out. Then we have the
switch selector for our voltage reference selector and then at the bottom as well for
the voltage reference selector and then we have the enable FET and then during sleep mode
we can see that when the device wakes up from sleep through an interrupt or a watchdog timer
the contents of the CVRCON register are not affected. I think that should be is. I'm not sure.
To minimize current consumption in sleep mode. The voltage reference should be
disabled. So what they are referring to here is. You need to shut down CVR enable if you enter
sleep mode if you don't want to use it during sleep mode. In our case we are going to use it
during sleep mode. Here you can see the output for the voltage reference. Now according
to this you going to need some in... an external circuitry like an OPAMP buffer to get the output
with a capacitor connected to the pin. For the interrupts we are going to use these
three bits. With CMIP being the priority and then CMIE for the enable of the interrupt and
then our flag to detect if it was the comparator that has been triggered. Now the next module
we're going to have a look at is the analogue to digital converter. Now this module setup
exactly the same as my analogue to digital converter tutorial video with some slight
changes and I'll be covering those changes in this video. Now my analogue select bit will
always read from analogue channel 7 and then I set up the analogue pins to be the triple
1 configuration. So AN7 is analogue and AN1 and 2 are analogue pins. Unfortunately these
other pins have to be sacrificed to get AN7 as a analogue pin and then we going
to have a look at interrupts and then we have a look at the interrupt bits for this. We are going
to use... we're going to set the priority of the interrupt. We going to enable the interrupt
and use the IF flag to detect if it was an analogue interrupt and then the last register
we're going to use is our timer 2 module. Witch you can have a look at my fading LED video
or my timer an oscillator control video. Now the slight changes I have here is simply to
put my post scalar at 16 and then my prescaler at 16 as well. So that I have the maximum time
before and overflow interrupt is triggered. Then we quickly have a look at the interrupt bits
for this. Which will be TMR2IF to once again tell us if it's a timer interrupt and
then we have the enable and the priority bits for this interrupt. Now we can have a look
at the code. Now in the code. I have a define here which sets the resolution of my analogue
to digital converter. So that I can convert whatever the reading bits are two a voltage. So
I have 5 / 1,023. Then I have my forward declaration for my interrupts. Then I have the print puffer.
Which if I need to print something that I can print it. Then I have a boolean that
tells me when a ADC conversion is done via the interrupt. Then I have a function to print the
value of the ADC in volts to a serial terminal and inside the function I am using a float
that is equals to the merged value of the ADC result register high and low times its resolution and
then a sprintf. Just to have a nice string to print out and then I have a function to
set certain LEDs depending on which comparator is currently triggered. So if comparator 2
triggered RB7 is turned on and RB0 is turned off and if comparator 1 is triggered RB7 is off
RB0 is on and then in the main IDLEN is equals to 1. So that when we call sleep state the
peripherals are still running in the background but the CPU is off to save power and then
I just set the oscillator to 8 MHz and wait for it to stabilize on 8 MHz and then I set
TRIS B as all outputs. I put the whole port B as low and then I set the 3 analogue
pins as input. I am actually not sure if this is necessary but just for safety. We do it and
then we have the UART enable. Then we have the prescaler and postscaler for timer 2 to
set our timer interrupt lengths for each overflow and I see now I've made a mistake that
4 should be 15 to set it to a 16 postscaler and a 16 prescaler. Then we have the analogue
to digital converter. With the analogue controller register 1 set here and then
the main change is PGFC. So that we have AN7 as an analogue input and all the AN
channels below it also as analogue inputs. Then we are analogue control register 2 witch
nothing has changed in. Then and then we have analogue control register 0 which this
CHS bit which is the channel select bit needs to be changed to 7 to sample from analogue
channel 7 and then we have the analogue enable. Then we have the comparator voltage reference
module here. Comparator of voltage reference select here. We set that to 0 to set VDD
and VSS as our reference points. We set our comparator reference to a resolution from
0 to 0.667 by setting our reference to 1. Then the output control is equals
to 0. So they don't put output on RA2 and then we use the CVR bit... our CVR bit to 15
or F in hex which corresponds to 3.125 volts as a reference point. Then we have the comparator
module setup bit 0 to 2 as our CM bit which corresponds to the four input Multiplex to
two comparators. Then we have the input select bit which is 0. So that we have AN1
and AN0 as our inputs for comparator 1 and 2 and then we have our inversion bits
comparator 1 is not invited. So it's equals to 0 and comparator 2 is inverted. So it is
equals to 1 and then we enable the interrupts for... for the comparator model and set it as
high priority interrupt by settings CMIP as 1 and then we have timer module 2 interrupts.
We set that as a low priority by setting the priority bit as 0 and then we have
the ADC interrupt to tell us when an ADC conversion is done and we put that as a high priority
interrupt and then I just have a printout tell me when the program was started. We
enable the interrupts and then we enable the comparator module and then we enable timer
2. Now in the main loop. If an ADC conversion is done. We print out the value. We set the
boolean as false. So that we don't reread it by accident and then we turn on the timer
again and then we enter sleep mode with the CPU off but the peripherals are running in
the background and then and a high priority interrupt. We disable our interruption soon as
we enter it. Then if a comparator trigger happens. We set the corresponding LED to whichever
comparator has been triggered. Then we clear the flag and then in the next interrupt check.
We check if a ADC conversion is done and then we simply just set the boolean for ADC conversion
is done to true and then we clear the interrupt flag and then we re-enable interrupts when
we exit and then the low priority interrupt. We check if timer 2 interrupt overflower
has happened. We switch off the timer and we started a ADC conversion and we cleared the
flag. Now each one of these in interrupts will wake the CPU from sleep and then the main loop
will continue and then check if there was a new ADC conversion and then print that to
the Putty terminal. Now let's program the PIC with my fixes. Now as you can see. Comparator 2 is triggered
by the red LED being on which is bit 7. Then when I adjust the voltage lower with the trim
pot or variable resistor. You can see bit 0 turn on it. When the voltage drops below the Trigger
Point voltage of the internal reference. And you can see on screen to PIC measuring the
voltage. Now at a certain point you'll see that both LED is goes... go on and that's the comparator
fluctuating between two values as you can see the on-screen measurement. The PIC is reading
anywhere between 3 to .1 .12 volts
on each interrupt
you can see alternating between
the two states. Disco disco disco disco disco disco disco disco. And that's a basic
introduction to using comparators on a PIC and using interrupt
based programming any code that I have written
will be linked on my Git. Any parts that I have used will be linked down in the
description. A like comment and subscribe would be greatly appreciated. Thank you have a nice day