Jag använder Microchip Studio (dvs. f.d. Atmel Studio) att programmera i, men eftersom Arduinon har bootloader och UART-interface så programmerar jag den med avrdude. Datablad till Atmega328P här.
Det var något år sedan jag gjorde något nytt för AVR, så jag har väl glömt något. Lusläser databladet, men kan inte få interrupt att funka, varken i Microchip Studios egna simulator eller i Arduinon. Timern snurrar i alla fall, ser jag när jag läser av den. Koden i interruptet nedan nås alltså aldrig. Jag har även testat att använda TIMER1_COMPA_vect istället för overflow (och då satt biten OCIE1A i TIMSK1 istället för TOIE1), men utan resultat. Vad fattas?
Det jag gör i interruptet är att toggla lysdiodutgången PB5 (vanlig röd LED), samt sätta på eller stänga av Timer0 som ger en 38kHz utsignal på OC0A.
Kod: Markera allt
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
CLKPR = (1 << CLKPCE);
CLKPR = (1 << CLKPCE);
//MCUCR = (1 << IVCE);
//MCUCR = (1 << IVSEL);
DDRD = (1 << DDD6); // D6 = output
PORTD = 0;
DDRB = (1 << DDB5); // B5 = output (LED)
// Generate 38kHz signal
OCR0A = 16000000UL / 38000UL / 2;
TCCR0B = (1 << CS00); // FCPU
TCCR0A = (1 << COM0A0) | (1<< WGM01); // Toggle OC0A on Compare match (non PWM mode)
// Generate 1 bit signal (436µs bitlength)
PRR = 0; // PRTIM1
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS10);
OCR1A = 16000000UL / 2294UL + 1; // 3488;
TIMSK1 = (1 << TOIE1);
sei();
while(1)
{
}
}
ISR(TIMER1_OVF_vect)
{
static uint8_t toggling;
if (toggling)
{
TCCR0A = (1<< WGM01); // Toggle OC0A on Compare match (non PWM mode)
PORTB = 0;
toggling = 0;
}
else
{
TCCR0A = (1 << COM0A0) | (1<< WGM01); // Toggle OC0A on Compare match (non PWM mode)
PORTB = (1 << PORTB5);
toggling = 1;
}
}