You were on the right track for your timer delays. The timer1 Us delay could be modified with a pre-scale of 1, and an OCR1A = 14 to give better
Us resolution. The Timer 0 delay looks like it was never completed. The format can basically follow the Timer1 format you used. A prescale of 64
along with the OCR0A = 249 you gave seems to give the correct results.
Below is the code you gave with the changes above and a main() function to test the output using a scope on a PORTB pin.
Code:
#include <avr/io.h> // (atmel studio 6 include)
void delay();
void delayMs(unsigned int delay);
void delayUs(unsigned int delay);
void initTimer1();
void initTimer0();
int main()
{
DDRB = 0xFF;
initTimer1();
initTimer0();
while(1)
{
PORTB = 0xff;
delayMs(5);
PORTB = 0x00;
delayMs(5);
/* PORTB = 0xff;
delayUs(5);
PORTB = 0x00;
delayUs(5); */
}
return(1);
}
/// Timer 1 Code for us delay ///
void initTimer1() {
//set timer 1 into CTC mode by placing 1 into WGM12. all others are zero
TCCR1A &= ~(1 << WGM10);
TCCR1A &= ~(1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B &= ~(1 << WGM13);
// calculate OCR1A for a 1us delay. OCR1A = (Td * fclk)/ Ps
// prescaler of 1
// OCR1A = (1e-6 * 16e6)/8
// OCR1A = 2
//start the clock with prescaler 1 and OCR1A = 14
TCCR1B &= ~(1 << CS12);
TCCR1B |= (1 << CS10);
TCCR1B &= ~(1 << CS11);
OCR1A = 14;
}
void delayUs(unsigned int delay)
{
unsigned int count = 0;
TIFR1 |= (1 << OCF1A); // set the counter flag down
TCNT1 = 0; // clear the count register
// enter a loop to compare count with delay value needed
while (count < delay)
{
if (TIFR1 & (1 << OCF1A))
{ //increment every time the timer raises a flag (counting 1 us flags)
count++;
TIFR1 |= (1 << OCF1A); //set timer to start counting again
}
}
}
/// Timer 0 Code for ms delay//
void initTimer0() {
//set timer 0 into CTC mode by placing 1 into WGM01. all others are zero
TCCR0A &= ~(1 << WGM00); // 0
TCCR0A |= (1 << WGM01); // 1
TCCR0B &= ~(1 << WGM02); // 0
//start the clock with prescaler 64 and OCR0A = 249
TCCR0B |= (1 << CS00);
TCCR0B |= (1 << CS01);
TCCR0B &= ~(1 << CS02);
OCR0A = 249;
}
/* This delays the program an amount specified by unsigned int delay.
Use timer 0. Keep in mind that you need to choose your prescalar wisely
such that your timer is precise to 1 millisecond and can be used for
100-200 milliseconds
*/
void delayMs(unsigned int delay)
{
unsigned int count = 0;
TIFR0 |= (1 << OCF0A); // set the counter flag down
TCNT0 = 0; // clear the count register
// enter a loop to compare count with delay value needed
while (count < delay)
{
if (TIFR0 & (1 << OCF0A))
{ //increment every time the timer raises a flag (counting 1 us flags)
count++;
TIFR0 |= (1 << OCF0A); //set timer to start counting again
}
}
}