Sida 1 av 1

Timer1 interrupt i Atmega328P (LÖST)

Postat: 30 november 2020, 21:34:09
av jesse
Sitter och försöker göra en fjärrstyrning till min värmepump, med en Arduino Nano och en IR-LED.

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;
	}
}

Re: Timer1 interrupt i Atmega328P

Postat: 30 november 2020, 21:41:07
av jesse
Kan tillägga att eftersom Arduinon har en bootloader så har jag testat med att sätta IVSEL-biten i MCUCR men utan att det gjorde nån skillnad. Den är bortkommenterad i koden ovan. IVSEL väljer mellan två olika interruptverktorer, den ena ligger i bootloadern och den andra i applikationskoden.

Re: Timer1 interrupt i Atmega328P (LÖST)

Postat: 30 november 2020, 22:41:10
av jesse
Lyckades ju fixa det.
Overflow -interrupt funkar fortfarande inte, men jag lyckades få igång TIMER1_COMPA. Vet ej varför det inte funkade innan, kan ju varit något skrivfel bara. Men suttit några timmar med detta nu , då blir man ju lite frusterad.

Men då så, nu ska jag programmera värmepump-fjärrkontroll! :)