Go Down

Topic: Hardware CTC (Read 829 times) previous topic - next topic

berlineddy

Hi Guys,

I want to do toggle a LED on and off every half a second via the hardware.

my Hardware is a Duemilanove running at 16 MHz

this is the code i am currently trying to run:


Code: [Select]
#include <avr/io.h>

void setup(){
  // reset registers
  TIMSK1 = 0x00;
  TCCR1A = 0x00;
  TCCR1B = 0x00;
  TCNT1 = 0x00; 
 
  // OC1A as output
  pinMode(9, OUTPUT);
 
  // count 0.521 sec
  OCR1A = 15000;
 
  // CTC
  TCCR1B |= ( 1 << WGM13 );
  TCCR1B |= ( 1 << WGM12 );
 
  TCCR1A |= ( 0 << WGM11 );
  TCCR1A |= ( 0 << WGM10 );
 
  // Prescaler to 1024
  TCCR1B |= ( 1 << CS12 );
  TCCR1B |= ( 0 << CS11 );
  TCCR1B |= ( 1 << CS10 );
 
 
  // TOGGLE OC1A
  TCCR1A |= ( 0 << COM1A1 );
  TCCR1A |= ( 1 << COM1A0 );
}

void loop(){
 
}


the problem with this code, is that it only turn the led on and then does nothing else :(

has anybody a suspicion what might be wrong her?

greetings from Berlin,
Eddy

CrossRoads

Could be written a little simpler:
Code: [Select]

void setup(){
pinMode (9, OUTPUT);
}
void loop (){
digitalWrite (9, HIGH);
delay (500);
digitalWrite (9, LOW);
delay (500);
}
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

berlineddy

ohhhh

i fixed it myselve

i had to change

Code: [Select]
  TCCR1B |= ( 1 << WGM13 );

to

Code: [Select]
  TCCR1B |= ( 0 << WGM13 );

CrossRoads

Also, just noticing you have everthing in void setup, which only runs once.
And nothing in void loop, which runs repeatedly.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

berlineddy

yes thats the nice thing about hardware timers.

you just set them up once then you can put your cpu to sleep but the timer-modules on the chip does all the timing and everything for you.


Steen

could you please give a little more info about those hardware timers? i would like to learn that..

shelleycat

If you google for AVR manual ATmega168, you get the wiki page on the processor on the first page, and the .pdf processor manuals.
The processor manuals have details of the 3 hardware timers.

The timers are called Timer0, Timer1 and Timer2.  One is used for delay() and millis(), so you should not mess with that (unless you don't use those functions).  Timer 2 is not used (except if you use PWM).

The  timers are basically counters, which can be driven via a prescalar from the processor clock.  They can also be organised to pulse an output pin when they hit the top or bottom, or call an interrupt.  They are controlled by timer registers, which are pretty low level.  You don't have to know about them because the core Arduino software takes care of the set up as it starts.  You can control them using symbolic constants.

Here is an example of timer 2 being used to generate an interrupt, you would need to call setup_interrupt() in your setup() function.

Code: [Select]

#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT

void setup_interrupt()
{
  //Timer2 Settings: Timer Prescaler /64  CS22 only
  TCCR2B |=  (1<<CS22);
  TCCR2B &= ~((1<<CS20) | (1<<CS21));
  TCCR2B &= ~(1<<WGM22);

  // Use normal mode
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  // Use internal clock - external clock not used in Arduino
  ASSR &= ~(1<<AS2);
  //Timer2 Overflow Interrupt Enable, clear the two output compare interrupt enables
  TIMSK2 |= (1<<TOIE2);
  TIMSK2 &= ~((1<<OCIE2A) | (1<<OCIE2B));
  RESET_TIMER2;
  sei();
}


And this code is a partial interrupt routine:
Code: [Select]


ISR(TIMER2_OVF_vect) {
  RESET_TIMER2;
  // read the input pin anyway, might use later, but timing more accurate here
  // direct port read is faster then digitalRead()

   g_byte_in_read_pin = PINB & 0x01;
.... more stuff

}


MarkT

When setting configuration registers don't do it one-bit-at-a-time - that puts the hardware through lots of different configurations in quick succession and could have unintended consequences.
[ I won't respond to messages, use the forum please ]

shelleycat

OK. I'll apply that in future.  For me, one bit at a time while developing was easier to understand.

Jack Christensen

Nick Gammon has written a lot about timers here:
http://www.gammon.com.au/forum/?id=11504

Dean Camera, an Atmel engineer, has also done some good writing on timers:
http://fourwalledcubicle.com/AVRArticles.php
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Go Up