简体   繁体   中英

Custom Delay function using arduino IDE

I'm in a microprocessors class and we're writing our own delay functions that are actually accurate. Our professor gave us, what I assume is, a 4 ms delay function. I don't really understand how to transfer that to a .25 s or a 1 s delay, which are both needed for my homework.

The given function is as follows(Assume _BV() is defined as _BV(x) 1<<(x)):

DDRB |= _BV(1);
TCCR1A |= _BV(COM1A0);
TCNT1 = 0;
OCR1A = 100;
TIFR1 = _BV(OCF1A);
TCCR1B |= _BV(CS10);
while((TIFR1 & _BV(OCF1A)) == 0);

TIFR1 = _BV(OCF1A);
OCR1A = 100 + 64000;
while((TIFR1 & _BV(OCF1A)) == 0);
TCCR1B = 0;
TCCR1A = 0;

I've written the code needed to complete the homework except the two delay functions.

Here is what I have so far:

#include <avr/io.h>

uint8_t numIN;

void setup() {
  Serial.begin(9600);

  DDRB |= _BV(5);
}

void loop() {
  int i;

  numIN = 10;

  Serial.println("Enter a number between 0 and 9.");

  do {
    while (Serial.available() > 0)
    {
      numIN = Serial.read() - '0';
      if (numIN < 0 || numIN > 9)
      {
        Serial.println("Input Error!");
      }
    }
  } while (numIN < 0 || numIN > 9);

  Serial.print("You entered ");
  Serial.println(numIN);

  if (isEven(numIN))
  {
    for (i = 0; i < 5; i++)
    {
      PORTB |= _BV(5);
      delay(1000); //temporary
      //delay_Sec();
      PORTB &= ~_BV(5);
      delay(1000); //temporary
      //delay_Sec();
    }
  }

  else
  {
    for (i = 0; i < 5; i++)
    {
      PORTB |= _BV(5);
      delay(250); //temporary
      //delay_quarterSec();
      PORTB &= ~_BV(5);
      delay(250); //temporary
      //delay_quarterSec();
        }
  }
}

void delay_quarterSec(void)
{
  //need to finish
}

void delay_Sec(void)
{
  //need to finish
}

boolean isEven(int num)
{
  if (num & _BV(0))
    return false;

  else
    return true;
}

I'm just confused how I take my professor's code and transfer it to what I need to do. Any help is greatly appreciated!

I can give you a quick overview about what the provided code does.

(This is from memory, so don't take my word for it. And you don't mention your controller type. You will have to look up the registers up in detail.)

DDRB |= _BV(1);         // set the compare match output pin to output
TCCR1A |= _BV(COM1A0);  // enable output compare PIN toggle
TCNT1 = 0;              // set counter start value to 0
OCR1A = 100;            // set compare match value to 100 (the actual delay)
TIFR1 = _BV(OCF1A);     // clear the output compare flag 
TCCR1B |= _BV(CS10);    // enable the timer by setting the pre-scaler
while((TIFR1 & _BV(OCF1A)) == 0);  // wait until the timer counted to 100 (compare flag is set again)

So the actual delay depends on:

  • the setting of the prescaler
  • the clock speed of your controller
  • the value of OCR1A

Example:
If the prescaler is set to 1 and you run at 10MHz you got
t = (1 / (10000000/s)) * 100 = 10us

This should get you started.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM