This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:examples:timer:delay [2015/11/03 06:04] – raivo.sell | en:examples:timer:delay [2020/07/20 09:00] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ~~PB~~ | + | < |
====== Delay ====== | ====== Delay ====== | ||
Line 63: | Line 63: | ||
<code c> | <code c> | ||
- | // | + | // Software delay in milliseconds |
- | // Software delay in milliseconds. | + | |
- | // | + | |
void sw_delay_ms(unsigned short count) | void sw_delay_ms(unsigned short count) | ||
{ | { | ||
Line 71: | Line 69: | ||
while (count-- > 0) | while (count-- > 0) | ||
{ | { | ||
- | // 1ms delay with a special function. | + | // 1ms delay with a special function |
_delay_ms(1); | _delay_ms(1); | ||
} | } | ||
Line 80: | Line 78: | ||
<code c> | <code c> | ||
- | // | + | // The demonstration program of the software delay of the HomeLab |
- | // The demonstration program of the software delay of the HomeLab. | + | // The program is blinking a LED for a moment after ~1 second |
- | // The program is blinking a LED for a moment after ~1 second. | + | |
- | // | + | |
#include < | #include < | ||
#include < | #include < | ||
- | // | ||
- | // Determining the pin of the test LED | ||
- | // | ||
- | pin debug_led = PIN(B, 7); | ||
- | |||
- | // | ||
// Main program | // Main program | ||
- | // | ||
int main(void) | int main(void) | ||
{ | { | ||
- | // Setting the pin of the LED as output. | + | // Setting the pin of the LED as output |
- | pin_setup_output(debug_led); | + | pin_setup_output(led_debug); |
// Endless loop | // Endless loop | ||
Line 104: | Line 93: | ||
{ | { | ||
// Lighting the LED | // Lighting the LED | ||
- | pin_clear(debug_led); | + | pin_clear(led_debug); |
// Software delay for 100 ms | // Software delay for 100 ms | ||
Line 110: | Line 99: | ||
// Switching off the LED | // Switching off the LED | ||
- | pin_set(debug_led); | + | pin_set(led_debug); |
- | // Software delay for 900 milliseconds. | + | // Software delay for 900 milliseconds |
sw_delay_ms(900); | sw_delay_ms(900); | ||
} | } | ||
Line 120: | Line 109: | ||
Although it seems that the LED blinks in every 1 second, the time is actually a little bit longer, because the callouts of LED’s and delay functions are taking a couple of clock rates of the microcontroller | Although it seems that the LED blinks in every 1 second, the time is actually a little bit longer, because the callouts of LED’s and delay functions are taking a couple of clock rates of the microcontroller | ||
- | The program code below is a delay function based on a timer, which is simplified a little bit. The principle of counting is the same as it is at software delay function – a desired amount of 1 ms long delays are produced. The delay is produced with an 8-bit ATmega 128 counter 0. It is calculated previously that at clock frequency 14,7456 Mhz the timing signal has to be divided at least 64 times, so that the counter would not reach to overflow in 1 ms. The value which the counter must have so that the overflow occurs after 1 ms is presented in the form of an expression and the variable is // | + | The program code below is a delay function based on a timer, which is simplified a little bit. The principle of counting is the same as it is at software delay function – a desired amount of 1 ms long delays are produced. The delay is produced with an 8-bit counter 0. It is calculated previously that at clock frequency 14,7456 Mhz the timing signal has to be divided at least 64 times, so that the counter would not reach to overflow in 1 ms. The value which the counter must have so that the overflow occurs after 1 ms is presented in the form of an expression and the variable is // |
In the cycle takes place initialing of the counter and zeroing the flag of the overflow (by writing 1 into that). Then is waited until the counter counts to 256 from the initial value, i.e. to the overflow. At the moment of the overflow the flag goes high and the delay of 1 ms has taken place. In the end of the function the timer is stopped. | In the cycle takes place initialing of the counter and zeroing the flag of the overflow (by writing 1 into that). Then is waited until the counter counts to 256 from the initial value, i.e. to the overflow. At the moment of the overflow the flag goes high and the delay of 1 ms has taken place. In the end of the function the timer is stopped. | ||
Line 126: | Line 115: | ||
<code c> | <code c> | ||
- | // | + | // Hardware delay in milliseconds |
- | // Hardware delay in milliseconds. | + | |
- | // | + | |
void hw_delay_ms(unsigned short count) | void hw_delay_ms(unsigned short count) | ||
{ | { | ||
- | // Calculating the initial value of the timer. | + | // Calculating the initial value of the timer |
register unsigned char timer_start = 256 - F_CPU / 1000 / 64; | register unsigned char timer_start = 256 - F_CPU / 1000 / 64; | ||
- | // Starting the timer. | + | // Starting the timer |
timer0_init_normal(TIMER0_PRESCALE_64); | timer0_init_normal(TIMER0_PRESCALE_64); | ||
- | // Counting the variable of the delay to the 0. | + | // Counting the variable of the delay to the 0 |
while (count-- > 0) | while (count-- > 0) | ||
{ | { | ||
- | // Initializing the timer. | + | // Initializing the timer |
timer0_set_value(timer_start); | timer0_set_value(timer_start); | ||
- | // Zeroing the overflow flag. | + | // Zeroing the overflow flag |
timer0_overflow_flag_clear(); | timer0_overflow_flag_clear(); | ||
- | // Waiting for overflow. | + | // Waiting for overflow |
while (!timer0_overflow_flag_is_set()) | while (!timer0_overflow_flag_is_set()) | ||
{ | { | ||
Line 153: | Line 140: | ||
} | } | ||
- | // Zeroing the overflow flag. | + | // Zeroing the overflow flag |
timer0_overflow_flag_clear(); | timer0_overflow_flag_clear(); | ||
- | // Stoping the timer. | + | // Stoping the timer |
timer0_stop(); | timer0_stop(); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Referenced delay function uses a timer library whose source code for ATmega controller looks like the following: | ||
+ | |||
+ | <code c> | ||
+ | // Timer 0 prescaler selection type | ||
+ | typedef enum | ||
+ | { | ||
+ | TIMER0_NO_PRESCALE | ||
+ | TIMER0_PRESCALE_8 | ||
+ | TIMER0_PRESCALE_32 | ||
+ | TIMER0_PRESCALE_64 | ||
+ | TIMER0_PRESCALE_128 | ||
+ | TIMER0_PRESCALE_256 | ||
+ | TIMER0_PRESCALE_1024 | ||
+ | } | ||
+ | timer0_prescale; | ||
+ | |||
+ | // Setting Timer 0 to a normal mode | ||
+ | inline void timer0_init_normal(timer0_prescale prescale) | ||
+ | { | ||
+ | TCCR0 = prescale & 0x07; | ||
+ | } | ||
+ | |||
+ | // Stopping the Taimer 0 | ||
+ | inline void timer0_stop() | ||
+ | { | ||
+ | TCCR0 = 0x00; | ||
+ | } | ||
+ | |||
+ | // Taimer 0 value set | ||
+ | inline void timer0_set_value(unsigned char value) | ||
+ | { | ||
+ | TCNT0 = value; | ||
+ | } | ||
+ | |||
+ | // Timer 0 overflow flag clear | ||
+ | inline void timer0_overflow_flag_clear(void) | ||
+ | { | ||
+ | bit_set(TIFR, | ||
+ | } | ||
+ | |||
+ | // Timer 0 overflow flag state reading | ||
+ | inline bool timer0_overflow_flag_is_set(void) | ||
+ | { | ||
+ | return (bit_is_set(TIFR, | ||
} | } | ||
</ | </ | ||
Line 164: | Line 198: | ||
<code c> | <code c> | ||
- | // | + | // Demonstration program of hardware delay of the HomeLab |
- | // Demonstration program of hardware delay of the HomeLab. | + | // The Program blinks LED for a moment after every ~1 second |
- | // The Program blinks LED for a moment after every ~1 second. | + | |
- | // | + | |
#include < | #include < | ||
#include < | #include < | ||
- | // Main program. | + | // Main program |
int main(void) | int main(void) | ||
{ | { | ||
- | // Setting the pin of the LED as output. | + | // Setting the pin of the LED as output |
- | pin_setup_output(debug_led); | + | pin_setup_output(led_debug); |
- | // Endless loop. | + | // Endless loop |
while (true) | while (true) | ||
{ | { | ||
- | // Lighting the LED. | + | // Lighting the LED |
- | pin_clear(debug_led); | + | pin_clear(led_debug); |
- | // Hardware delay for 100 milliseconds. | + | // Hardware delay for 100 milliseconds |
hw_delay_ms(100); | hw_delay_ms(100); | ||
- | // Switch off of the LED. | + | // Switch off of the LED |
- | pin_set(debug_led); | + | pin_set(led_debug); |
- | // Hardware delay for 900 milliseconds. | + | // Hardware delay for 900 milliseconds |
hw_delay_ms(900); | hw_delay_ms(900); | ||
} | } |