Timer1 interrupt i Atmega328P (LÖST)

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
jesse
Inlägg: 9233
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Timer1 interrupt i Atmega328P (LÖST)

Inlägg 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;
	}
}
Senast redigerad av jesse 30 november 2020, 22:41:34, redigerad totalt 2 gånger.
Användarvisningsbild
jesse
Inlägg: 9233
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Timer1 interrupt i Atmega328P

Inlägg 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.
Användarvisningsbild
jesse
Inlägg: 9233
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Timer1 interrupt i Atmega328P (LÖST)

Inlägg 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! :)
Skriv svar