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 (; // 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>
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;
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).
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().
Tak 5tiletej překladač jsem opravdu nečekal . Se divim, že vůbec megu8 znal.
Každopádně tohle je poslední verze winavr, další už nebude. Již je to nahrazeno avr-toolchainem, který si distribuuje přímo atmel.