0

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!

1
  • So you will use also AVR registers in your sketch ? Commented Nov 9, 2016 at 6:42

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.