Přerušení UART Atmega8

Dobrý den, v programování jsem silný začátečník a potřeboval bych poradit.Potřebuji vložit do svého programu přerušení od sériové komunikace a nedaří se mi to rozchodit.V HW problém není-přijímání i vysílání funguje bez problemu,ale pokud vložím přerušení nic se neděje. Programuji v AVR Studio 5. Nevidí někdo v přiloženém kódu kde dělám chybu?Děkuji za odpověď.

#include <avr/io.h>
#include <avr/interrupt.h>

int main (void)
{
UCSRA = 0x00;

  UBRRH = 0x00;  // nastaveni rychlosti pro krystal 1MHz

  UBRRL = 0b00001100;	//12 4800baud

  UCSRB = 0b00011000;  // povolit vysilani a prijem

  UCSRC = 0b10000110;  // ramec dat:  8 datovych, 1 stop bit, bez parity

UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)
sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed

for (;:wink: // Loop forever
{
// Do nothing - echoing is handled by the ISR instead of in the main loop
}
}

 ISR(USART_RXC_vect)

{
char ReceivedByte;

ReceivedByte = UDR; // Fetch the recieved byte value into the variable “ByteReceived”

UDR = ReceivedByte; // Echo back the received byte back to the computer
}

Tvůj program je vpořádku, chyba je jinde. Přidej si do programu blikátko, ať víš, jesli mcu žije a má správnou frekvenci.[code]#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
#include <util/delay.h>

void main (void)
{
DDRB |= 1<<PB0;
UBRRL = 12; // 4800 Bd @ 1MHz
UCSRB |= 1<<RXCIE | 1<<RXEN | 1<<TXEN;

sei();

for(;;)
{ 
	PORTB ^= 1<<PB0;
	_delay_ms(500);
} 

}

ISR(USART_RXC_vect)
{
UDR = UDR;
}[/code]
Taky si zkontroluj rychlost protějšku a vyzkoušej loopback bez procesoru.

Procesor žije,ostatní programy funguji bez problemu,ovládám např. servo pomocí znaků,ale bez přerušení(Kód níže).Ten funguje bez problemu i zpracování řetězce,které jsem s Vámi řešil v jiném fóru - ovládám 3 serva pomocí UART, problém je v tom,že je potřebuji ovládat i potenciometry(přes ADC),ale dohromady to nefunguje kvůli tomu, že program čeká na přijetí z UART a neprovádí se AD převod.Z toho důvodu tam musím vložit přerušení UART, které mi nefunguje.Frekvence CPU je nastavena 1 Mhz (bity CKSEL3:0 - 0001) a nastaveno 4800Bd jak v programu tak v Hyperterminálu. V dalších verzích už je kostrbata fce delay nahrazena avr\delay.h

#include <avr\io.h>

void delay(unsigned int k) //cekaci smycka
{
unsigned int i;
i=0;
for(i = 0; i <= k; i++);
}

// get char

unsigned char uart_getc( void )

{

/* Wait for data to be received */

while ( !(UCSRA & (1<<RXC)) );

/* Get and return received data from buffer */

return UDR;

}

// send char

void uart_putc(unsigned char data )

{

while ( !( UCSRA & (1<<UDRE)) )

;

UDR = data;

}

int main()
{
unsigned int j;
j=1630;

DDRB=0b00000010; // nastaveni PB1 na vystup
ICR1=20000;
TCCR1A=0b10000010;//zapnuti PWM
TCCR1B=0b00000010;	//preddelicka
PORTD=0b11000000; //zaapne pull up na PD6,7
DDRD=0x00; // zapne vstup PD6,7	
DDRC=0b11111100;	//zapne vstup PC

OCR1A=j;	//nastav servo na 0
delay(30000);

char znak;



  /***** inicializace uart  *****/

  UCSRA = 0x00;

  UBRRH = 0x00;  // nastaveni rychlosti pro krystal 1MHz

  UBRRL = 0b00001100;	//12 4800baud

  UCSRB = 0b00011000;  // povolit vysilani a prijem

  UCSRC = 0b10000110;  // ramec dat:  8 datovych, 1 stop bit, bez parity



while(1)
{
		//prijeti z PC a vraceni
		znak=uart_getc();

        uart_putc(znak);

	if (znak == 'o' )
		{	
			if(j <= 1680)
			{	j=j + 1;
				delay(1500);
			}
			else ;
		}
	else OCR1A=j	;
	if (znak== 'p')
		{	
			if(j >= 1570)
				{	j=j - 1;
					delay(1500);
				}
			else	;
			
			
		}
	else OCR1A=j;

};

return 0;

}

Hned jak se dostanu domů vyzkouším Váš kód a napíšu co to dělá

Vyzkoušel jsem Vámi poskytnutý kod.AVR Studio vypsalo tyto varování:

c:7: warning: return type of ‘main’ is not int' c:22: warning: return type defaults to int’
c:22: warning: type of “USART_RXC_vect” defaults to “int”
c:25: warning: control reaches end of non-void function

Po nahrání začne LED blikat a při odeslání jakéhokoliv znaku přes terminál v závislosti na stavu ve kterém se zrovna nachází buď zůstane svítit nebo zhasne.Znak se nevrací a netuším jestli má program vracet znak nebo ne.

A pokud se loopbackem myslí spojení TX a RX větve na převodníku tak to funguje-znak se vrací.Pro spojení používám konvertor USB-TTL, FTDI jestli to má význam

Program jde přeložit v avr-toolchain-3.0.0.240 i v WinAVR-20100110 (s bezvýznamným varováním “return type of ‘main’ is not `int’”). IDE však mám AVRStudio4.18SP3. Pro jistotu přikládám zkompilovaný hex. Je odzkoušen na hw.
Můžeš zkusit dát krystal, RC oscilátor má totiž toleranci 10%. Obsluha přerušení je loopback - všechno posílá zpět, stejně jako tvoje verze.

Třetí varování(a s ním související 2. a 4.) vzniká např. když je nějaký problém s hlavičkovým souborem pro přerušení.

Pokud bys to chtěl obsluhovat v mainu, tak bys musel funkci pro čtení znaku obalit podmínkou, kde bys nejdřív kontroloval, jesli nějaký znak přišel.

Vkládej prosím zdrojáky do “CODE”, zachová se tam formátování a je to lépe čitelné.
C_pokus.hex (390 Bytes)

Tak Váš přiložený .hex funguje bez problemu,ale dioda má 2x menší frekvenci než kód, který mám od Vás. V kódu od Vás jsem musel změnit #include <util/delay.h> na #include <avr/delay.h> protože to psalo c:4:24: util/delay.h: No such file or directory. Je možné, že toto je ten důvod? Ješte to AVR Studio mám 4.18(asi nějaký zkrat tentokrát na mozku, že jsem uvedl 5).

Co máš za překladač? Dioda by měla blikat rychlostí 1Hz.

To vypadá na nějakou prastarou verzi Winavr.
Odpovídá tomu i to, že _delay_ms() neodměřuje správně.
V těch starých verzích chodil _delay přesně jenom asi do 250 ms při 1 MHz.

Najdi adresář WINAVR… , obsahuje i datum verze,
třeba můj se jmenuje WinAVR-20100110, tj. 10.01.2010.
Můžeš ho stáhnout tady
sourceforge.net/projects/winavr/files/WinAVR/
a přeinstalovat.

Edit:
Podle těch varování ta stará verze nezná ani ISR(). Dřív se pro přerušení používalo SIGNAL().

Děkuji moc, problém vyřešen. Měl jsem nainstalovanou verzi 20050214 a přeinstalace na novější(20100110) to vyřešila. Teď to funguje tak jak má.

Tak 5tiletej překladač jsem opravdu nečekal :laughing:. Se divim, že vůbec megu8 znal. :wink:
Každopádně tohle je poslední verze winavr, další už nebude. Již je to nahrazeno avr-toolchainem, který si distribuuje přímo atmel.

Já jsem to taky nečekal, že bude zrovna v tomto zakopaný pes, ještě jednou díky za pomoc :wink: