Documente Academic
Documente Profesional
Documente Cultură
Welcome to my AVR Diary episode 5, today we’re going to talk about delay we’ve encountered in the
previous video.
Now previously, when we brilliantly blinked the LED, you might be curious and change the numbers
inside the “_delay_ms(500)” to another value
And you might notice the higher the value, the longer we have to wait for the LED to blink
Conversely, the lower the value, the faster the blink becomes.
So what is this? How does it know that 1000ms means roughly 1second, etc.
Now before going any further there’s something you have to know about the timer and counter that
happens inside the microcontroller.
I don’t want to make this too complicated, but remember previously I talked about high and low level
language, high level language can be understand by humans, on the other hand, low level language is a
machine language.
We code our program in C, but our .c code doesn’t directly go to uC, when the code is compiled, it is
converted to object then to hex file, this is the lower level language that our uC could understand. The
lowest level language in embedded system is called assembly, assembly language consist of many
instructions. These instructions need to be run by our uC. Our uC has a certain speed at which one could
run each instruction. This is called the frequency of the microcontroller, or to be precise the frequency
of CPU inside the uC.
So first, we got the internal clock of the microcontroller, which by default is set to 1MHz.
Do you see that previously in our blinking LED code we have to declare F_CPU
/*
*
* Created: 22-Sep-18 09:21:12
* Author : Orvin Demsy
* This code is made for youtube video part 3 and 4
* Part 3 : First Code How to Light Up LED GPIO
* Part 4 : Adding Switch to Control the LED
*/
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRA=0xFF;
PORTA = 0x00;
//init_tim();
while (1)
{
PORTA = 0x80; //PORTA = 0b1000000
_delay_ms(1000);
PORTA = 0x00; //PORTA = 0b1000000
_delay_ms(1000);
}
return 0;
}
Despite its name being F_CPU, which we could arguably guess is short of “Frequency CPU”, it has
nothing to do with the internal clock of the microcontroller!
Declaration of F_CPU is required when using _delay_ms() function. This F_CPU is a way to tell the
_delay_ms() at what speed the CPU is currently running.
So far we have two things with similar name but actually completely different things.
Because the F_CPU is actually telling the _delay_ms() the real frequency of uC so that the _delay_ms()
could count exactly how long the delay should be.
int main(void)
{
DDRA=0xFF;
PORTA = 0x00;
//init_tim();
while (1)
{
PORTA = 0x80; //PORTA = 0b1000000
_delay_ms(1000);
PORTA = 0x00; //PORTA = 0b1000000
_delay_ms(1000);
}
return 0;
}
As you can see the program will still run, but instead of blinking at rate 1 second, it’s blinking at
approximately 2 seconds.
Try changin the F_CPU to 3million or 8million, and observe what happens!
I guess that’s all folks! This is something I’m struggling with when learning AVR, so I thought I would be a
great idea to share this knowledge to those who got confused with F_CPU.