Application of delay function in avr-gcc

Publisher:cwm6269310Latest update time:2015-12-31 Source: eefocusKeywords:avr  gcc  delay Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
       In 51, we write our own delay functions, whether in assembly or C. Although there are templates, it is still a bit annoying sometimes. Haha. But when we use avr microcontrollers, we are blessed. Because avr-gcc provides us with a very convenient delay function, just include:
#include
This header file defines two levels of delay functions:
; In 51, our delay functions are all written by ourselves
void _delay_us (double __us);       // microsecond level
void _delay_ms (double __ms);     // millisecond level

sp;   
But don't be happy too soon, because there are conditions for using them correctly in your avr-gcc, which I will explain slowly below.

This parameter is related to the F_CPU value in the Makefile. The value of the F_CPU variable defined in the Makefile will be passed to the compiler. If you use AVR_studio 4.1X to edit and debug, use the built-in AVR-GCC to compile, and let AVR_studio automatically generate the Makefile for you, then you can:
, either in assembly or in C. Although there are models
                                           Project -> Configuration Options -> Gerneral -> Frequency    as shown below:
; In 51, our delay functions are all written by ourselves
Write down your F_CPU value. F_CPU indicates the operating frequency of your AVR microcontroller . The unit is Hz, not MHZ. Don't make a mistake. For example, if it is 7.3728M,    then F_CPU = 7372800.
You will find a definition like this in the "delay.h" header file:
#ifndef F_CPU; In 51, our delay functions are all written by ourselves
# warning "F_CPU not defined for "
# define F_CPU 1000000UL     // 1MHz
#endif
board, sometimes it's still a bit annoying. Haha. But in the application of av
This is to provide a default frequency value of 1MHz when you do not define the F_CPU variable (including null) or AVR_studio Frequency does not have a value, so that the compiler will not make mistakes when compiling.

sp;   
Here are the bodies of these two functions:
void _delay_us(double __us)         // microseconds
{; In 51, our delay functions are all written by ourselves
uint8_t __ticks;
double __tmp = ((F_CPU) / 3e6) * __us;    // 3e6 is because the called _delay_loop_1() is three instructions
if (__tmp < 1.0)    &nb
   __ticks = 1;
else if (__tmp > 255)
   __ticks = 0;; In 51, our delay functions are all written by ourselves
else
   __ticks = (uint8_t)__tmp;
_delay_loop_1(__ticks);, whether in assembly or in C language. Although there is a module
}

void _delay_ms(double __ms)        // millisecond board, sometimes it's a bit annoying. Haha. But in the application av
{
uint16_t __ticks;
double __tmp = ((F_CPU) / 4e3) * __ms; // 4e3 is because the called _delay_loop_2() is four instructions    &nb

if (__tmp < 1.0)
   __ticks = 1;, whether in assembly or in C language. Although there is a module
else if (__tmp > 65535)
   __ticks = 0;
else; In 51, our delay functions are all written by ourselves
   __ticks = (uint16_t)__tmp;
_delay_loop_2(__ticks);
}
, either in assembly or in C. Although there are models
You will find that they both call    the two functions _delay_loop_1(); and _delay_loop_2();
The two functions are as follows:
void _delay_loop_1(uint8_t __count) board, sometimes it's a bit annoying. Haha. However, when using av
{
__asm__ volatile (
   "1: dec %0" " ", whether in assembly or in C language. Although there is a module
   "brne 1b"
   : "=r" (__count)
   : "0" (__count)sp;    
);
}
void _delay_loop_2(uint16_t __count), both in assembly and in C. Although there is a modulo
{
__asm__ volatile (
   "1: sbiw %0,1" " "    &nb
   "brne 1b"
   : "=w" (__count)
   : "0" (__count)sp;    
);
}

board, sometimes it's still a bit annoying. Haha. But in the application of av
Both functions are written in avr-gcc inline assembly format. I won't go into the specific syntax rules. You can refer to avr-libc. However, these two functions are very simple and easy to understand. One is byte decrement and the other is word decrement. If you look carefully at the above functions, you will find that there are the following conditions for using them correctly:
        1. First, you need to correctly define the value of your F_CPU, which is the actual frequency of your AVR microcontroller . Otherwise, the delay will be inaccurate.
         2. You must turn on optimization when compiling. Do not select 0 for OPT in Makefile, and do not select O0 if you are using AVR_studio.
  &nb
        3. When you use these two delay() functions, use constants as the actual parameters passed to the two functions, not variables.
        4. The time parameters __ms and __us are within a range. Do not exceed the range. __ms: 1 - [262.14 ms / (F_CPU/1e6) ], __us: 1- [768 us / (F_CPU/1e6)]. [...] The integer part is used.

sp;   
For the 4th scope, here is an example:
      If F_CPU = 7372800, then __ms range: 1 - 35, and __us range: 1 - 104.

sp;   
Only when the above conditions are met can you use the delay functions _delay_us() and _delay_ms() correctly. For the third condition, why do we use constants? And for the second condition, why do we need to turn on the optimization option? This is to allow the compiler to calculate the delay value when compiling, rather than compiling it into the program and calculating it at runtime. In that case, the length of the code will be increased, and the delay time of your delay program will be longer or unpredictable, resulting in timing errors.

I found that it took me more than two hours to write, which doesn't seem long. It seems easy to say, but it still takes some effort to write it down. I hope it helps you. Haha. Share happiness and make progress together.

Keywords:avr  gcc  delay Reference address:Application of delay function in avr-gcc

Previous article:About the use of ADC of AVR microcontroller
Next article:SPWM Program for AVR Microcontroller

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号