I'm using an ATtiny85 for a simple IR project built on C (an IR remote for a DSLR camera). I generated a 38.4 kHz square signal using Timer 0 in CTC mode and set the output to toggle PB0 every time the timer reaches it's max value OCRA
. I wanted to use the interrupts generated by the timer 0 compare unit to count the number of cycles that it has generated, since the counter reaches it's max two times to generate a full period of the 38.4 kHz square wave, counting two interrupts should indicate a full cycle. The problem: I noticed that every time I called the sei()
function to enable global interrupts, the generated square wave would deform and the ISR associated would never be called. Using an oscilloscope I checked the generated wave on PB0:
Not calling sei() function during setup: The generated square wave looks as expected.
Calling sei() during setup: The generated square wave has some longer pulses.
How did I test this?
I implemented the following test-code that configures Timer 0 as previously described and toggles PB1 every time an interrupt associated with the compare unit of timer 0 is detected:
main.h
#ifndef MAIN_H
#define MAIN_H
#define __AVR_ATtiny85__
#define F_CPU 8000000UL
#endif
main.c
#include "main.h"
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
cli();
DDRB |= _BV(PB0) | _BV(PB1);
PORTB &= ~_BV(PB1);
// Set general register to sync mode for configuration
GTCCR |= _BV(TSM) | _BV(PSR0);
// Default registers
TCCR0A = 0;
TCCR0B = 0;
TCNT0 = 0;
TCCR0A |= _BV(COM0A0) | _BV(WGM01); // Set toggle on match and CTC mode
TCCR0B |= _BV(CS00); // internal clock no-prescaling
OCR0A |= 12; // For app 38,8kHz
TIMSK |= _BV(OCIE0A);
// Enable timer
GTCCR &= ~_BV(TSM) & ~_BV(PSR0);
// Enable global interrupts
sei();
while(1);
}
// Demo interrupt service routine
ISR(TIMER0_COMPA_vect){
PORTB ^= _BV(PB1);
}
To compile the code I used avr-gcc
as follows:
avr-gcc main.c -o main.elf -Wall -Wextra
No warnings where raised from the compiler. Then I used avr-objcopy
to get the hex file:
avr-objcopy -O ihex -j .text -j .data main.elf main.hex
Finally I programmed the IC using avrdude:
avrdude -p t85 -c usbtiny -B 125kHz -U flash:w:main.hex
The fuses are:
avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)
What have I tried?
- Setting the SREG register manually:
Replacing the sei()
line for:
SREG |= 1 << 7;
Does something, but still doesn't work. The generated square wave looks better, but is not as expected and the ISR is not doing anything to the PB1.
- Replacing the ISR operation: I though maybe the port operation was taking to much time, but replacing it with _NOP();
had no effect on the weird behaviour on the generated square wave.
-Tried with other IC: I had another ATtiny85 laying around and behaves the same. Maybe I have two defective ICs?
I don't know if I configured something wrong or when I enable the interrupts using sei()
the IC is getting bombarded with interruptions and not working properly?
Thanks in advance for any tip or reply!