Go Down

Topic: Problem using timer1 overflow (Read 744 times) previous topic - next topic

Pegasux

Jul 09, 2009, 01:46 pm Last Edit: Jul 10, 2009, 09:17 am by Pegasux Reason: 1
Greetings. I've tried to use timer1 for a larger count while the MCU is sleeping. I put the timer2 in asynchronous mode, as the datasheet says and use PWR_SAVE mode for sleep, but doesn't work. I send the registers as serial data in order to see register's values, but I think all are right and I'm making a mistake... When the timer1 interrupt overflows the led blinks, so the timer1 interrupt is working good, but the data is not sent via uart, so some is wrong with the sleep mode... If I use IDLE mode is always sending data without sleeping... I don't know why doesn't sleep... Also, using a delay before sending uart data the data is not sent, I don't know why the program is bloqued using a delay... You can test it with your arduino board and a serial software, there's no additional parts needed. Any help will be thanked.



#include <TimerOne.h>
#include <avr/sleep.h>

int interled = 13;
int state = LOW;

void setup() {
Serial.begin(9600); // open serial
pinMode(interled, OUTPUT);

Timer1.initialize();   // Initializes Timer1 (Period)
Timer1.attachInterrupt(flash, 2000000);      // 8388480 maximo

TCCR1A=0;
TCCR1B=5;
TCCR1C=0;
TCNT1H=0;
TCNT1L=0;
TIMSK1=1;
TIFR1=0;

TCCR2A=0;
TCCR2B=7;
TIFR2=0;
ASSR=0;
GTCCR=0;  
TIMSK2=0;    // borramos los bits OCIE2x y TOIE2
ASSR=(0<<5);  // bit AS2 a 0
TCNT2=0;    // escribimos algo en estos registros
OCR2A=0;
OCR2B=0;
delay(2); // testeamos que el bit busy del ASSR esté a 0 (lo hacemos con un delay y listo)
TIMSK2=0;    // borramos los bits OCIE2x y TOIE2

 
  ADCSRA=0;
// TWI | TIMER2 | TIMER0 | VOID | TIMER1 | SPI | USART | ADC
PRR=(1<<7)| (0<<6) | (1<<5) | (0<<3) |(1<<2)|(0<<1)|(1<<0);

set_sleep_mode(SLEEP_MODE_PWR_SAVE);   // sleep mode is set here

}

void loop() {


Serial.println();
Serial.print("TCCR1A ");
Serial.println(TCCR1A, HEX);
Serial.print("TCCR1B ");
Serial.println(TCCR1B, HEX);
Serial.print("TCCR1C ");
Serial.println(TCCR1C, HEX);  
Serial.print("TIMSK1 ");
Serial.println(TIMSK1, HEX);    
Serial.print("TIFR1 ");
Serial.println(TIFR1, HEX);    
Serial.print("TCCR2A ");  
Serial.println(TCCR2A, HEX);
Serial.print("TCCR2B ");
Serial.println(TCCR2B, HEX);
Serial.print("TIMSK2 ");
Serial.println(TIMSK2, HEX);    
Serial.print("TIFR2 ");
Serial.println(TIFR2, HEX);  
Serial.print("ASSR ");
Serial.println(ASSR, HEX);  
Serial.print("GTCCR ");
Serial.println(GTCCR, HEX);  
Serial.print("SMCR ");  
Serial.print(SMCR, HEX);    

delay(500);
//Turn off ADC

sei();  // habilita interrupciones

  TCCR2A=0;    // escribimos algo segun el protocolo
  delay(2);    // testeamos que el bit busy del ASSR esté a 0 (lo hacemos con un delay y listo)
sleep_mode();  // entramos en sleep

//Disable Sleep
sleep_disable();
//Disable interrupts
  cli();    // deshabilita interrupciones

delay(500);
}
void flash()
{
state = !state;
digitalWrite(interled, state);  
}




Mike Mc

Wow. My finger really hurts now  ::)

joker

I cannot go into details, but...
I noticed something which I know (for sure) is wrong! It relates to:

TCNT1H=0;
TCNT1L=0;

look at the ATMEGA168 Datasheet in 15.11.4 TCNT1H and TCNT1L - Timer/Counter1! It says:

The two Timer/Counter I/O locations (TCNT1H and TCNT1L, combined TCNT1) give direct access, both for read and for write operations, to the Timer/Counter unit 16-bit counter. To ensure that both the high and low bytes are read and written simultaneously when the CPU accesses these registers, the access is performed using an 8-bit temporary High Byte Register (TEMP). This temporary register is shared by all the other 16-bit registers. See "Accessing 16-bit Registers" on page 109.

Your pointer may be some place... why not in timer0 area... locking the serial comm port.

HTH


Go Up