## How to use TIMER1_COMPB_vect on AtMega8.

6 posts / 0 new
Author
Message

Hi there!

First of all, I'm sorry if you will find mistakes in my text. English is not my native language.

If you have a simple code, how to work with Timer1_COMPB_vect on AtMega8, I will be a very grateful.

So.

I am trying to understand how to work with Timer1_COMPB_vect and I wrote the code, but my code doesn't work.

My code:

```ISR (TIMER1_COMPB_vect){
cli ();
PORTD ^= (1 << PC0);
//Example code
sei ();
}

int main (void){

DDRC |= (1 << DDC0);
PORTC |= (1 << PC0);

TCNT1 = 0x0000; // Initial value is zero
TCCR1B |= (1 << CS12) | (1 << CS10); // clk / 1024. 8*10^6/1024 = 7812 tics/sec.
OCR1B = 7812; // 1 sec.
TIMSK |= (1 << OCR1B); // Interrup of OCR1B.

sei (); // Global interrrupt.

while (true){}

return 0;

}```

Thanks!

Hello, Feni, and welcome to AVR Freaks -

How do you determine that it does not work?

As a side note, which should not effect how it works, the sei() and cli() in the interrupt at totally not necessary. Those two operations are automatically done by hardware on every ISR call and every ISR return.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Mon. Apr 9, 2018 - 07:14 PM

Please post a complete test program.  Tell your AVR model and clock speed.  Tell your language, brand of toolchain and version.  Tell compile options, and build results.  Are there any warnings?Show your schematic and describe what is connected.

What do you expect to happen?  What >>is<< happening?  How are you testing?

Have you looked at the timer-related articles in the Tutorials forum?

Feni wrote:
TIMSK |= (1 << OCR1B); // Interrup of OCR1B.

Surely that cannot be correct, as OCR1B really isn't anything, but is sometimes used as a shorthand for the register pair OCR1BL and OCR1BH at addresses 0x48 and 0x49. Did you mean OCIE1B?

Feni wrote:
ISR (TIMER1_COMPB_vect){ cli (); PORTD ^= (1 << PC0); //Example code sei (); }

Read the datasheet section on interrupt handling again.  The cli() isn't needed as

When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts
are disabled.

and

The I-bit is
automatically set when a Return from Interrupt instruction – RETI – is executed.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

```ISR (TIMER1_COMPB_vect){
cli ();
PORTD ^= (1 << PC0);
//Example code
sei ();
}```

If you want an interrupt every second then you have to clear the timer in ISR.

```ISR (TIMER1_COMPB_vect){
PORTD ^= (1 << PC0);
TCNT1 = 0;
}```

Edit:

This applies for the original code #1 where nonpwm mode is used.

Last Edited: Tue. Apr 10, 2018 - 09:01 AM

Tell your AVR model and clock speed.

I use AtMega8,  clock speed is 8MHz.

Tell your language, brand of toolchain and version.

I use Atmel Studio 7 in English version

How are you testing?

I'm testing my progects in Proteus 8.6

What do you expect to happen?

Ok. If I write code for TIMER1_COMPA_vect, code works perfectly, but if I change this for  TIMER1_COMPB_vect, it doen't not work.

Code for TIMER1_COMPA_vect:

```ISR(TIMER1_COMPA_vect){
PORTC ^= (1 << PC0);
}

int main (void){
PORTC |= (1 << PC0);
DDRC |= (1 << DDC0);

TCNT1 = 0x0000; // 16-bit timer-counter1. Initial value is zero.
TCCR1B |= (1 << CS12); // clk/256
TCCR1B |= (1 << WGM12); // CTC
TIMSK |= (1 << OCIE1A);

OCR1AH = 0x7F;
OCR1AL = 0xFF; // 32767

sei ();

while (true){}

return 0;

}```

For TIMER1_COMPB_vect doen't works and I can't find a problem.

```ISR (TIMER1_COMPB_vect){
PORTC ^= (1 << PC0);
}

int main (void){
PORTC |= (1 << PC0);
DDRC |= (1 << DDC0);

TCNT1 = 0x0000; // 16-bit timer-counter1. Initial value is zero.
TCCR1B |= (1 << CS12); // clk/256
TCCR1B |= (1 << WGM12); // CTC
TIMSK |= (1 << OCIE1B); // for TIMER1_COMPB_vect

OCR1BH = 0x7F;
OCR1BL = 0xFF; // 32767

sei ();

while (true){}

return 0;

}```

Feni wrote:
doen't works
You still aren't really saying what "doesn't work" means.

Having said that you can't expect B to work exactly like A because of this: You are using mode 4 so "TOP" (the count limit of the timer) is set by the OCR1A register - so in the second program you can't just switch from using OCR1A to OCR1B

I wonder if you might want to explore using mode 12 instead? As you can see, in this mode TOP is set by ICR1 so this would work whether you then used A or B as the output channel.

Also, instead of using PC0 as the output you may want to explore this: The timer can be set to toggle PB1 (channel A) or PB2 (channel B) automatically via the hardware - in this case you souldn't even need the ISR. You just configure the timer and leave it to drive the pin with no further interaction at all (which is the usual use of waveform generation - you only usually resort to toggling pins in ISR when there's some reason you cannot use the pin actually dedicated to the timer)
{"ft_lang_label":"__label__en","ft_lang_prob":0.90089023,"math_prob":0.62890553,"size":3543,"snap":"2020-10-2020-16","text_gpt3_token_len":934,"char_repetition_ratio":0.09578977,"word_repetition_ratio":0.033690657,"special_character_ratio":0.2689811,"punctuation_ratio":0.11731844,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9544021,"pos_list":[0,1,2,3,4,5,6],"im_url_duplicate_count":[null,null,null,null,null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-04-05T03:53:08Z\",\"WARC-Record-ID\":\"<urn:uuid:4f3de921-ee7d-4029-9abe-1b0161cffbd7>\",\"Content-Length\":\"153145\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:3172a1fc-b693-41ab-b71b-95b3adc9cf71>\",\"WARC-Concurrent-To\":\"<urn:uuid:768fe5f6-7c42-4793-b84c-31a521de861c>\",\"WARC-IP-Address\":\"50.112.125.251\",\"WARC-Target-URI\":\"https://www.avrfreaks.net/comment/2443516\",\"WARC-Payload-Digest\":\"sha1:ZJVBMHVYFFDP3OLVHHACMHRK3GKGYCIE\",\"WARC-Block-Digest\":\"sha1:EMTINHGJPCALUV43NLFQO46DCFZJYJ6A\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-16/CC-MAIN-2020-16_segments_1585370528224.61_warc_CC-MAIN-20200405022138-20200405052138-00303.warc.gz\"}"}