so I went through a video online, it explained that if the prescalar value is set by TCCR1B |= B00000100; which is 256.
and to achieve 500ms 500ms/16us. I want to acheive a timer duration of 40s. hense i used 1024 prescalar TCCR1B |= B00000101; and set the value to 40000ms/64us = 39062
but i cant achieve a duration of 40s. what have i done wrong? and how should i approach to make the timer longer for 40s or more.
1. Do you want to see that TC1's COMPA flag becomes active in every 500 ms? This is what I see in your ISR code.
2. In Normal Mode operation of TC1, the TCNT1 always continuously compares its content with OCR1A and OCR1B Registers and the corresponding flags OCF1 and OCF1B are set when equality occurs (Fig-1). If local interrupt enable bits are active, these flags can generate interrupts for the MCU.
Figure out how many overflows of the timer gives you 40 seconds. Set up a timer overflow interrupt that increments a counter each interrupt, when it reaches the number you calculated set a bool variable (flag) in the interrupt. In your code you are polling this flag, when it is 1 you know 40 seconds have expired.
So you can just program a timer to give you a 1 second period. Then at each overflow 1 second has elapsed. At each interrupt increment a counter variable and compare it to 40. When it reaches 40 set a flag.
Can't be done. The maximum count you can specify in a 16-bit counter is 65536. 16 MHz / 65536 = 244.144 Hz / 1024 prescale = 0.238422 Hz = 4.19 seconds.
If you want to time longer intervals you have to count overflows of your timer. You could set your timer for 4 seconds (Set TOP to 62499 and prescale to 1024) and count 10 overflows to get a 40-second interval.
thankyou so much, i made adjustments as you told, it works perfectly
bool LED_STATE = true;
int tuneC[]={80,100,110,90,150,130,120,170,160,130,100,140,180,200,190,200,210};
int durC[]={300,300,300,300,300,300,600,300,300,300,300,150,150,300,150,150,200};
int i,j,n=17; //n is inialitsed to the number o fnotes in tune 1.
int tmp;
void setup() {
pinMode(13, OUTPUT); //Set the pin to be OUTPUT
cli(); //stop interrupts for till we make the settings
TCCR1A = 0; //initialize timer1
TCCR1B = 0;
TCCR1B |= 0b00000100; //256 prescaler
TIMSK1 |= 0b00000001; //enable overflow interrupt
sei(); //Enable back the interrupts
}
void loop() {
}
ISR(TIMER1_OVF_vect) //timer overflow ISR: update counter
{
i++; if(i==40){
//buzzerC();
LED_STATE = !LED_STATE; //Invert LED state
digitalWrite(13,LED_STATE); //Write new state to the LED on pin D5
i=0;
}
}
void buzzerC() {
DDRE = (1<<DDE4);
TCCR3A = (1<<COM3B1)|(1<<WGM31);
TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS32);
for (i=0;i<n;i++){
ICR3=tuneC[i];
OCR3A=tuneC[i]/2;
TCNT3=0;
for (j=0;j<durC[i];j++){_delay_ms(1);}
}
ICR3=0;OCR3B=0;TCNT3=0;
}
bool LED_STATE = true;
int tuneC[]={80,100,110,90,150,130,120,170,160,130,100,140,180,200,190,200,210};
int durC[]={300,300,300,300,300,300,600,300,300,300,300,150,150,300,150,150,200};
int i,j,n=1; //n is inialitsed to the number o fnotes in tune 1.
int tmp;
void setup() {
pinMode(13, OUTPUT); //Set the pin to be OUTPUT
cli(); //stop interrupts for till we make the settings
TCCR1A = 0; // Reset entire TCCR1A to 0
TCCR1B = 0; // Reset entire TCCR1B to 0
/*set the prescalar to the desired value by changing the CS10 CS12 and CS12 bits. */
TCCR1B |= B00000101; //Set CS12 to 1 so we get prescalar 1024
/*enable compare match mode on register A*/
TIMSK1 |= B00000010; //Set OCIE1A to 1 so we enable compare match A
OCR1A = 39062; //Finally we set compare register A to this value
sei(); //Enable back the interrupts
}
void loop() {
}
ISR(TIMER1_COMPA_vect){
TCNT1 = 0; //First, set the timer back to 0 so it resets for next interrupt
//buzzerC();
LED_STATE = !LED_STATE; //Invert LED state
digitalWrite(13,LED_STATE); //Write new state to the LED on pin D5
}
void buzzerC() {
DDRE = (1<<DDE4);
TCCR3A = (1<<COM3B1)|(1<<WGM31);
TCCR3B = (1<<WGM33)|(1<<WGM32)|(1<<CS32);
for (i=0;i<n;i++){
ICR3=tuneC[i];
OCR3A=tuneC[i]/2;
TCNT3=0;
for (j=0;j<durC[i];j++){_delay_ms(1);}
}
ICR3=0;OCR3B=0;TCNT3=0;
}
You can setup timer overflow for 4s and add incrementing the counter in the IRQ. When the counter is reach the 10 - you will obtain desired 40secs interval
Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.
Repeated cross-posting can result in a suspension from the forum.
In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.