Hello and in this video I'll be covering how to change the internal oscillator frequency
and how to set up a timer on a PIC. First let's go over the hardware configuration
for the current setup. Like previously I have two LEDs connected to RB6 and RB7 and
then a single switch connected to RB1. Now let's get the coding. Now i've preset up
some of the code here and what was added is the libraries for stdint and stdbool.
This is to better manage um variables and then I forward declared the interrupt service routines.
Then in the main. I have set both LEDs as outputs on RB7 and RB6 and then the button
as input on RB1 and then I set LEDs to low. Then I enable the internal priorities and then I enabled
the global interrupts. Then at the bottom is the interrupt service routines with global interrupts
enable and disable on execution. First we want to look at the datasheet and to set the internal
oscillators frequency. We are going to adjust oscillator config and we're going to adjust
the multiplexer to 8 megahertz. Now this ICs default configuration is 1 mega Hertz. Which is
potato slow. Now here we have the oscillator control register. What we want to change in
this register is IRFC. Which stands for the internal oscillator frequency bits to 7 hex
and then just to make sure we stay on the internal oscillator. We are going to set the system clock
select bit to 3 hex. Then we're gonna watch the internal oscillator frequency stable bit.
Until the oscillator is stabilized. Now we just copy the register name. Now back to the code. We
with oscillator control bits dot IRFC is equals to 0x07 hex and then next... Next is then OSCON
bits SCS is equal to 3 and then we wait for the oscillator to stabilize. So while oscillator
configuration bits IOFS is not equal to 1. Then we wait until that passes by and then do our code
setup. Now this is all you need to change the frequency of the internal oscillator and next
what we do is we change in our configuration bit header. We change our XTAL frequency to 8 million
Hertz. Now unfortunately there is not much to show on this. So the best ways to demonstrate it with a
timer. So we refer back to the datasheet and we start configuring timer 0. So the bits in timer
0 are timer enable and then do we want to have timer to operate as a 16-bit timer or an 8-bit
timer. Then next we select the clock source which is going to be the internal oscillator.
Which makes it function as a timer and not a counter and bit 4 is irrelevant for timers as
it only used in counter mode and then our 3de bit is the prescaler assignment. Which either enables
or disables the prescaler and then we have our prescaler select. Which is how much we reduce the
clock of the timer. For our calculations. Now we copy the register name and then we start configuring
the timer. First what we do is disable the timer with T0CON bits dot TMR0ON equals 0. Then we
set if we want it as an 8-bit or 16-bit counter. So we copy this line. We change this to T08BIT
equals 1. Then we select a clock source for our timer. Which is T0CON bits dot T0CS and we set
that to 0. So we use the internal oscillator as the clock source. Now bit 4 is irrelevant. So we
skip that and then we select our prescalar with T0CON bits PSA equals 0 to enable the prescalar
of the timer and the last thing is we select the prescalar value that we want. Which is done via
T0CON bits T0PS equals 2. So what we have in essence is our timer is disabled first. Then we
select our timer to be an 8 bit counter. Then we select the clock source to be the internal
oscillator. We enable the prescaler by setting PSA to 0. Then we set our prescaler to 8. So 1 to
8 format. Now note on some PICs the instruction frequency is the oscillator frequency divided
by 4. Which can be seen on the datasheet by the clocking scheme the microcontroller clock output
whether from an internal or external clock source is internally divided by 4 to generate for non
overlapping quadrant clocks. So effectively since we set the oscillator to 8 megahertz up here. We
are actually running at 2 megahertz instruction frequency. Now why I've picked this specific
configuration is because you have every 255 cycles you will have a overflow on the timer. Which is
equal to 1 milliseconds. Which can be calculated via this very professional piece of paint over
here. So you have your... your time per cycle is 4 over your clock frequency. Time per overflow will
be your time per cycle times your prescalar times 255. So in essence what you got is 4 divided by 8
megahertz equals 0.5 micro seconds and then your time per other flow will be 0.5 times 8 times 255.
Which is 1.024 milliseconds. Next what we are going to do is set up an overflow interrupt for
the timer. When we refer back to the datasheet. We go down and we see all the associated register on
every clock cycle timer 0 low will be incremented. time 0 I is only applicable when using the PIC
in 16-bit counter mode the INTCON register. Which holds the timer 0 enabled bit and the timer overflow
flag. Now what I don't mention in the associated registers is the timer 0 priority bit. Which is
located in the INTCON2 register on bit 2. Now back to the code. Now to enable the
interrupt for timer 0. We first set INTCON bits dot T0IE equals 1 and then in the INTCON2
register we set T0 interrupt priority equals to 1. To set it to the high priority interrupt
and then finally before we go into an infinite loop. We enable timer one. Now what does interrupt
will do is. Every time the counter reaches a value of 255. It will reset and then set the
timer 0 interrupt flag. Which we have set to trigger every 1.024 milliseconds. Now
next what I'm going to do is use the timer to blink an LED. So we start with quickly
declaring a global variable of size unsigned 8 bits. Call it blink underscore count equals 0.
Then we go to our infinite loop and we say if blink count is greater or equal to 200
Then toggle the state of the green LED. Now in our high priority interrupt. We say if INTCON bits dot
timer0 interrupt flag is true. Then increment the value of blink count. Then we reset the
interrupt flag and this will now blink the LED at 200 millisecond intervals approximately. Now
as shown by the green LED. We are blinking at approximately 200 milliseconds intervals. Now
next what I'm going to do is with a non-blocking denounce using the timer. We start with another
global counter variable of type unsigned 8-bit int. Call it button count that's equal to 0. Then
we declare a global boolean and we call it button underscore press and that's equal to false. Now we
go to a main loop start with an if statement and the if statement is if not button press. Then we
nest an if in that and then we test if the button was pressed with PORTB bits dot RB1. Then we set
the button press boolean to true. Then we have an if statement underneath that and says if button
press is true. We nest another if. If button count is greater or equal to 40. Now that 40 can be any
number you wish it to be and we nest if else in. Then we test if PORTB RB1 is still true
toggle the blue LED LATB bits LB6 is equal to the inverse of LATB LB6. We reset the button press
variable to false and set the button count equal to 0. Now if port B is not true. We just reset the
variables. Where the button is no longer pressed. Now after this statement is done. We got down
to our ISR. We add a if statement there as well. We say if button press is true increment
button count. Now we program the PIC. Now when pressed the blue LED will go on. Seems like my
debouncing was incorrect. So we go back to our if statement and we increase the 40 to 80. Program again.
Now let's see if the debouncing works in properly. Now. There we go. Now to recap the code. We added
stdint to enable us to use the macros for using uint8. We included stdbool. Then we can use
boolean. Our oscillator config. We clocked up the internal oscillator to 8 megahertz and we made
sure it stays on the internal oscillator. Then we wait for the oscillator to stabilize at 8
megahertz. Then we set our inputs and outputs for our LEDs and buttons. Then we set our LEDs
to low. We disable the timer at first. We set the timer to be in 8-bit counting mode. We select the
clock source to be the internal oscillator and then enable the prescaler and set the prescaler
to a 1 to 8 ratio. Then our internal priorities are enabled. Then we enable the interrupt for
timer 0. Then we set the interrupt priority of time 0 to high priority. Then we enable
the global interrupts and then we start the timer. Then in the main loop we test if the blink counter
is either greater or equals to 200. Then we toggle the green LED with LATB7. Then for the
button debouncing. We test if the button has been pressed if not read RB1 on port B and then if the
button has been pressed set the button pressed true. If the button has been pressed. Check the
button counter and if that is greater or equals to 80. Read port B again and if it is still high
toggle the blue LED on LATB7. Then reset our variables to false and 0 and in the high priority
interrupt every time the timer overflows increment the blink counter. I see now that I never reset
the blink counter. We add that to the blink code and we set that to 0. Now we should
actually have a better out come. Quickly gonna program the PIC. Then we should have a better result.
Strange that that worked. Okay so we just added the blink counter reset and in the
global interrupt enable in the high priority interrupt. We have the blink counter that
incremented every time the counter overflows and then if the button has been pressed increment
the button counter and then we reset the global interrupt flag. And that's how to configure the
internal oscillator of a PIC microcontroller and how to set up a timer to use for blinking
LEDs and debouncing buttons. Any parts that I have used will be linked on the description as
well as any code that I have written will be linked to my Git. A like share comment
and subscribe would be greatly appreciated. Thank you have a nice day. Oh by the way I
have solar panels for a project at some later stage (it's still on my desk 2021 XD) Cheers.