ATMEGA8 a interrupt v C – Mikrokontroléry – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

ATMEGA8 a interrupt v C – Mikrokontroléry – Fórum – Programujte.comATMEGA8 a interrupt v C – Mikrokontroléry – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
pavelt
~ Anonymní uživatel
2 příspěvky
14. 10. 2008   #1
-
0
-

Ahoj, prosím o radu s přerušením u ATMegy8. Potřebuji pomocí něho reagovat na přijetí Bytu po UART a tento Byte vyhodnotit. Nejlepší by pro mne bylo předat přijatý Byte z ISR funkce přerušení do hlavní main části, ale netuším, jak to udělat a jestli to vůbec jde. Zde je můj pokusný kód v C:

#include <avr/io.h>

#include <avr/interrupt.h>
#define USART_BAUDRATE 31250
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

char ReceivedByte;

int main (void)
{
DDRB = 0b11111111;
PORTB = 0b00000110;

UCSRB |= (1 << RXEN) | (1 << TXEN);
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);

UBRRL = BAUD_PRESCALE;
UBRRH = (BAUD_PRESCALE >> 8);

UCSRB |= (1<<RXCIE);
sei();

for(;;)
{
/****** UART ******/
//while ((UCSRA & (1 << RXC)) == 0) {};
//ReceivedByte = UDR;
if (ReceivedByte==0xF8)
{
PORTB ^= (0b00000010);
}
/*konec****** UART ******/
}// /for
}// /main

/****** přerušení-UART ******/
ISR(USART_RXC_vect)
{
ReceivedByte = UDR;
/*
if (ReceivedByte==0xF8)
{
PORTB ^= (0b00000010);
}
*/
}
/*konec****** přerušení-UART ******/

Jakmile vyhodnocuji přijatý znak ve funkci přerušení ISR a odtud ovládám port, je vše OK. Když nepoužívám přerušení a použiji po odkomentování část v hlavní smyčce, po odstranění sei(); to taky funguje. Ale když bych potřeboval pomocí ISR(USART_RXC_vect) jen Byte přijmout a zpracovat v hlavní smyčce, funguje to blbě. Přesněji - na vstup znaku to někdy reaguje a někdy ne, někdy jakoby dvakrát po sobě. Jsem začátečník a tak mne to mate, nevím kde je chyba.
Tenhle kód je jen příklad, přijatý Byte musím testovat pomocí mnoha podmínek a na jeho základě řídit další funkce v hlavní nekonečné smyčce.
Díky předem za pomoc.
Pavel

Nahlásit jako SPAM
IP: 82.208.57.–
Reklama
Reklama
KIIV+42
God of flame
14. 10. 2008   #2
-
0
-

no ne ze by to bylo tim ale urcite bych dal u toho receivebyte modifikator volatile ... aby nahodou prekladac nevykutal nejakou zajimavou optimalizaci...

jinak klidne bych udelal v ty smycce trochu upravu ...



for (;;) {
if ( ( UCSRA & ( 1 << RXC ) ) ) {
ReceivedByte = UDR;
if ( ReceivedByte == 0xF8 ) {
PORTB ^= (0b00000010);
}
}
}


jeste bys krom cekani na byte od serioveho portu mohl klidne delat i neco dalsiho...

Nahlásit jako SPAM
IP: 80.250.27.–
Program vždy dělá to co naprogramujete, ne to co chcete...
pavelt
~ Anonymní uživatel
2 příspěvky
14. 10. 2008   #3
-
0
-

Díky, volatile přidám. Ten test na přijetí bytu je dobrý nápad. Proto jsem to chtěl řešit přerušením vyvolaným UARTem. V hlavní smyčce se u čekání na příchod Bytu nesmím zastavit, procesor tam má na starosti hodně další práce a smyčka musí běžet pořád dokola.
Zkusím úpravu bez přerušení podle rady, je to zajímavé, ale stejně bych rád rozchodil to přerušení.
Zkoušel jsem
char volatile ReceivedByte;
funkce přerušení ISR právě díky tomu cosi v proměnné ReceivedByte do hlavní smyčky předává, ale nějak nepravidelně. F8 je na vstup posíláno naprosto pravidelně, řekněme třeba v rytmu 1x za vteřinu a když to přijímám bez přerušení, LED na B portu skutečně změní stav (bliká) přesně v tomhle rytmu. Jakmile přijímám Byte pomocí přerušení, několikrát blikne správně, pak se pozdrží, pak blikne i třeba velmi krátce, prostě na něco reaguje ale na co, to netuším. Z UDR se musí Byte přečíst, aby se vymazal RXC příznak, jinak to prý vyvolá znovu přerušení samovolně, ale tím

ISR(USART_RXC_vect)

{
ReceivedByte = UDR;

ho přeci přečtu, tak je vše v pořádku - myslím.
Pavel

Nahlásit jako SPAM
IP: 82.208.57.–
KIIV+42
God of flame
14. 10. 2008   #4
-
0
-

jo pockat tobe nejede to preruseni? tak to si musis jeste hodit nejakou promennou signalizujici ze si neco prijal...

dava se myslim spis volatile unsigned char ...

jinak musis v programu otestovat jestli si neco prijal jinak to nemas jak otestovat... protoze ten bit se po precteni myslim automaticky nuluje...

Nahlásit jako SPAM
IP: 80.250.27.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
14. 10. 2008   #5
-
0
-




volatile unsigned chat prijalsem=0, ReceiveByte=0;


for (;;) {
if ( prijalsem == 1 ) {
if ( ReceivedByte == 0xF8 ) {
PORTB ^= (0b00000010);
}
prijalsem = 0; // aby se neopakovalo toto :D
}
}


.....


ISR(USART_RXC_vect) {
ReceivedByte = UDR;
prijalsem = 1;

}

Nahlásit jako SPAM
IP: 80.250.27.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Anonymní uživatel
~ Anonymní uživatel
0 příspěvků
15. 10. 2008   #6
-
0
-

To KIIV : To je přesně ono! Díky, funguje to bez chyby, jednak jsem tam neměl správně volatile a druhak jsem netestoval přijetí Bytu, resp. pořád jsem ho měl v proměnné v hlavní smyčce. Díky moc za pomoc.
Pavel

Nahlásit jako SPAM
IP: 82.208.57.–
KIIV+42
God of flame
15. 10. 2008   #7
-
0
-

volatile zabranuje aby se kod nejak optimalizoval... hlavne u tech preruseni je to dulezity...

kdyz mas
while ( neco ) {
...
}

ale uvnitr to neco nijak nemenis tak bez volatile se to muze zoptimalizovat tak ze se ani nemusi neco kontrolovat...
ale optimalizace by to hodila do nejakyho z rychlejsich registru a kontroloval by se jen ten... nebo by to uplne vynechala :D
takze by se v dusledku sice neco do toho ulozilo ale nikdy by se to nezkontrolovalo protoze se kontroluje neco jineho

sem to trochu zamotal... volatile rika toto MUSIS VZDY zkontrolovat primo... muze se to totiz behem behu menit i jinde...





Nahlásit jako SPAM
IP: 80.188.94.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Aladinek
~ Anonymní uživatel
3 příspěvky
15. 10. 2008   #8
-
0
-

Zdravím,
já bych ještě trochu upravil kód.
V přerušení od USART bych data ukládal do kruhového burferu.
A v hlavní smyčce bych data vyčítal data je z bufferu. Nemuže aspoň dojít k přepisu dat. A pokud příjde už nový byte od USART, tak se aspoň neztratí.

Nahlásit jako SPAM
IP: 62.159.242.–
KIIV+42
God of flame
15. 10. 2008   #9
-
0
-

To Aladinek : jo to sem si rikal taky ze bude asi idealni :) jen sem mel trochu makacku v praci tak sem se na to poslat to sem vybodl :D

Nahlásit jako SPAM
IP: 80.188.94.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Martingt89
~ Anonymní uživatel
8 příspěvků
17. 10. 2008   #10
-
0
-

Sorry ale nechcelo sa mi citat tie zdlhave keci, ak chces aby si mal premennu funkcnu v celom programe napis jej nazov na zaciatok a daj ju ako volatile cize "unsignech char volatile premenna" a zarucene ta premenna bude v celom programe :)

Nahlásit jako SPAM
IP: 84.47.24.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 5 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý