ATmega8 - program funguje, ale nevstupuje do přerušení

Ahoj,

mam tu problem s prerusenim u ATmega8. Zatim se peru s casovacem, ale zkousel jsem zavest i externi preruseni a problem prakticky stejny. Zde je kod:

#define __AVR_ATmega8__
//#define __OPTIMIZE__

/*nastaveni pro f_osc 8000000*/
#define F_CPU 8000000

#include <avr\io.h>
#include <avr\interrupt.h>
#include <util\Delay.h> 

int a;

ISR(TIMER1_COMPA_vect)
{	
	//PORTC &= !(1<<PC5);
	//if(PORTC&(1<<PC5))	PORTC &= !(1<<PC5);
	//else	PORTC |= (1<<PC5);	
};

int main(void) 
{
	/*set IO pins*/	
	DDRC |= (1<<DDC5);	//set PC5 as an output
	DDRB |= (1<<PINB1);	//set PB1 as an output


	/*timer setting*/		
	TCCR1A = (1<<COM1A0);						//Output compare toggles OC1A pin
	TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10);	//1puls/1024	
	TIMSK = (1<<OCIE1A);						//interrupt when TCNT1 equals to OCR1A
	OCR1A = 5000;								//set compare register OCR1	
	

	_delay_ms(100);
	PORTC |= (1<<PC5);		
	_delay_ms(100);	
	PORTC &= !(1<<PC5);		
		
	sei();			//interrupt allowed		

	while(1){		
	}; 		
};

Cili mam zavedeny timer1, ktery reaguje na OCR1, a k nemu povoleny pin OC1A. Je zavedene preruseni pri shode s OCR1. Mam tu dve diody, jedna pripichnuta k pinu OC1A (resp. PB1) a druha k pinu PC5. Ve funkci main() po nastaveni vsech registru necham nejprve probliknout diodu PC5 a pak povolim globalni preruseni.

Problem je v tom, ze blikani diody na OC1A funguje perfektne (pri kazde komparacni urovni se zmeni stav na pinu OC1A a dioda sviti, resp. nesviti). Program ale vubec neskoci do preruseni, ale budto se restartuje cely anebo skace na zacatek main() (to spis, protoze stav OC1A se nenuluje. Proste funguje jak ma). Poznam to diky tomu, ze dioda na PC5 problikava pri kazde zmene OC1A, coz nema. Ani obsluha preruseni nijak nefunguje (nyni zde mam jen zakomentovane radky).

Problem pretrval i po vymene cipu (za jiny ATmega8)

Nevite nekdo, cim by to mohlo byt? Peru se s tim uz nekolik dni. Diky moc.
Otas

:arrow_right: administrator: přejmenováno z "ATmega8, přerušení, problém"

Máš nastavenej timer tak, aby se resetoval když dosáhne hodnoty 5000, to dělá. Dál máš nastaveno aby se při každém compare události negoval výstuní OCR bit, to dělá. Při každém compare (5/8 vteřiny) se vyvolá přerušení, pokud odkomentuji jeho obsah, normálně funguje (neguje PC5 ikdyž je ta negace u andu logická místo bitové).
V čem je tady problém?

Mimochodem za ukončujícími závorkami funkcí se nepíše středník, bitová negace se provádí pomocí “~”, OCR registr bys měl nastavit ještě před povolením compare přerušení, jinak se ti jedno vyvolá hned po zavolání sei().
Definice na začátku (#define AVR_ATmega8 a #define F_CPU 8000000) jsou zbytečný, avrstudio je generuje automaticky dle nastavení projektu.

Presne tohle jsem chtel, aby to delalo, ale do toho preruseni neskoci a jakoby se vrati na zacatek main(), protoze to kratke probliknuti, ktere je v kodu pred sei() a nekonecnym cyklem se opakuje a to by nemelo.

Mozna je tedy problem v tom, JAK ten mikroprocesor programuju. Mam programator pres LPT port sestaveny podle rototron.info/default.aspx?Page=USBAVR/USBAVR.aspx. V AVR Studiu v “disconnected mode” (proto ty definice na zacatku) necham zkompilovat program a .hex file nahravam pres BASCOM-AVR. Ten problem je stejny, ikdyz pouziji AVRdude, proto jsem myslel, ze v tomhle problem nebude. Konkretni typ procesoru je ATmega8-16PU. Zapojeni mam v kontaktnim poli.

Jeste doplnim k predchozimu prispevku, ze na strance odkazu, ktery jsem uvedl, je nutne jeste kliknout na link “Parallel ISP programmer” hned v prvni vete.

Jesli jsi připojen nemá na překlad vliv, důležité je nastavení v Project options. Tam musí bejt nastavený procesor a pro věci jako delay() je tam potřeba i frekvence.
Překládám tento kód:

[code]#include <avr\io.h>
#include <avr\interrupt.h>
#include <util\Delay.h>

ISR(TIMER1_COMPA_vect)
{
PORTC &= ~(1<<PC5);
if(PORTC&(1<<PC5)) PORTC &= ~(1<<PC5);
else PORTC |= (1<<PC5);
}

int main(void)
{
/set IO pins/
DDRC |= (1<<DDC5); //set PC5 as an output

/timer setting/
TCCR1A = (1<<COM1A0); //Output compare toggles OC1A pin
TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10); //1puls/1024
OCR1A = 5000; //set compare register OCR1
TIMSK = (1<<OCIE1A); //interrupt when TCNT1 equals to OCR1A

_delay_ms(100);
PORTC |= (1<<PC5);
_delay_ms(100);
PORTC &= ~(1<<PC5);

sei(); //interrupt allowed

while(1)
{
asm(“nop”);
};
}[/code] Připojuji vygenerovaný HEX.
C_pokus.hex (463 Bytes)

Musim podekovat. Problem vyresen. Spatne bylo nastaveni prave v Project -> Configuration options.

Protoze nemam programator, ktery je podporovany AVR studiem, ve wizardu pro otevreni noveho projektu jsem skoncil hned krokem “Create Project”. Druhy krok “Select debug platform and device” jsem neprovadel. Tim se v “Project -> Configuration options” ve vyberu zarizeni “Device” objevilo “atmega128” (nevim, jestli to je defaultni nebo nahodne nastaveni). Ve vlastnim programu jsem specifikaci zarizeni provadel prave onim "#define AVR_ATmega8 ". Po oprave to ted vypada, ze mi preruseni funguje, jak ma.

Jeste jednou diky.
Oťas