Pages: [1]   Go Down
Author Topic: Timer  Problems  (Read 429 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, i'm trying to learn how to use timers  on my arduino in C.

The problem I have is scaling the 16MHz clock. I am trying to scale it by 8 and then generate a 1MHz signal by creating an interrupt every other cycle. The reason why i'm doing this the delay library goes all screwy when I create a timer.

My code looks like this

Code:
#include <avr/io.h>
#include <avr/interrupt.h>

void realtimeclock_setup() {
      TCCR0A |= (1<<WGM01);
      TCCR0B |= (1<<CS01) ; // 0.5us or 2Mhz
      OCR0A = 0x01; // a 1MHz signal
      TIMSK0 |= (1<<OCIE0A);
}

volatile uint32_t clk1;

SIGNAL(SIG_OUTPUT_COMPARE0A) {
  clk1++;
}

int delay_us(uint32_t val) {
      clk1 = 0;
      while ( clk1 < val ){
      }
      return 0;
}

int main (void){
      realtimeclock_setup();
      DDRB |= 0x04; // an LED
      DDRD &= 0xFB;
      PORTD |= 0x04;  //enable pullup
      sei();
      
      while (1) {
                  PORTB ^= 0x04;
                  delay_us(500000); //500ms
      }

      return 0;
}

Problem is that instead of a 1Hz blinking LED I have 0.2Hz blinking LED. Any avr C whizzes can see what i've done wrong?
« Last Edit: August 17, 2009, 04:15:46 pm by regomodo » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bump
Logged

Canada
Offline Offline
Full Member
***
Karma: 0
Posts: 218
You will become one with the Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I would recommend using the msTimer2 library.

Do this  (sample from FlashLED)

You can also check out the source code to the timer to see how they are doing things...  From what I understand, Timer1 can't be modified without messing up millis() and delay().  Even the use of Timer2 in an ISR that operates quickly may drive millis and delay to be slower than normal.

Code:
#include <MsTimer2.h>

// Switch on LED on pin 13 each second


void flash() {
  static boolean output = HIGH;
  
  digitalWrite(13, output);
  output = !output;
}

void setup() {
  pinMode(13, OUTPUT);

  MsTimer2::set(500, flash); // 500ms period
  MsTimer2::start();
}

void loop() {
}
Logged

Canada
Offline Offline
Full Member
***
Karma: 0
Posts: 218
You will become one with the Arduino!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Darn it!  You did say in C...

Well, check out msTimer2 anyway - it is all C afterall...
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cheers for the info. Yeah, i'm trying to stray away from arduino code as I want to learn C and avr's.

The thing is this code is just an attempt at creating a signal based on scaling the clock which is to be incorporated in a different project. Problem there is that the timings are down to ~50us.

I can't use the util/delay.h library like this

Code:
void my_delay(uint32_t time) {
    _delay_us(time);
 }

void main(void) {
   my_delay(100);
   blinkon;
   my_delay(100);
   blinkoff;
}
 
as it create massive hexfile. The _delay_us has to be called with a constant, not a variable. That's why i'm creating my own.
« Last Edit: August 19, 2009, 06:32:20 am by regomodo » Logged

Pages: [1]   Go Up
Jump to: