Atmega 64 - povolený watchdog zakáže přerušeni od USART?

Program spusti wdt a prejde do hlavni smycky, kde ve while(1) testuje priznak prijeti urcityho retezce po usartu. Kdyz retezec prijde, tak se z nej vyzobou nejaky data, ktery se dal zpracujou, priznak se shodi a zresetuje se wdt. Kdyz by dlouho nic neprislo, tak by wdt mel shodit procesor. Ale bohuzel to nechodi, vypada to jakovy povoleni wdt zaroven zakazalo preruseni od usartu. Jakmile spusteni wdt vyhodim, tak to chodi dobre. Kde muze bejt problem? Podobnej algoritmus mi na Atmeze32 chodi bez problemu, ale 64 je nejaka zakleta.

:arrow_right: administrator: přejmenováno z "Atmega 64 - problem s watchdogem"

Hoď nám sem kus kódu jesli není tajnej.

Bez zdrojaku odhadujem, ze asi v extremne kratkom case WDT

tajnej neni, zatim, jen trochu chaotickej :slight_smile:
mod kompatibility s Atmegou 103 je vypnutej

#include <avr/wdt.h>
.
(inicializace atp., vynechano)
.
WDTCR=0x0F;

while(1) if (prijateACK!=0xFF)
{
if CHECKBIT(PIND, LED) CLEARBIT(PORTD, LED); else SETBIT(PORTD, LED);

odesli(prijateRoll, prijatePitch, prijateACK); 
prijateACK=0xFF; 		
wdt_reset();			
}

}

jeste dodam - ta promenna prijateACK se meni v obsluze preruseni od USARTU1, funkce odesli posila data po USARTU0 klasicky, bez preruseni. Sei() a povoleni preruseni od prijmu USARTU1 je kousek nad spustenim watchdogu. Watchdog ma periodu asi 2s, ta promenna prijateACK se zmeni kazdejch cca 100ms, kdyz to funguje.

Právě ta inicializace je důležitá. V tomhle není co kontrolvoat.
Jde o nastavení wdt, uart, definice/inicializace proměnných a jejich umístění…

tak celej kod mi to sem odmita dat, takze nastaveni wdt tam je. Pokud vim, tak jinej ridici registr jak WDTCR nema. Usarty :

#define BAUDRATE0 38400 //vystup
#define BAUDRATE1 115200 //snimac

//nastaveni USARTU0 linka ven
myUBRR=F_CPU/16/BAUDRATE0-1;
UBRR0H = (unsigned char)(myUBRR >> 8); // calculate baudrate and set high byte
UBRR0L = (unsigned char)myUBRR; // and low byte
UCSR0B = (1<<TXEN0)|(1<<RXEN0)/|(1<<RXCIE0)|(1<<TXCIE0)/; // enable transmitter and receiver
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // 8 bit character size, 1 stop bit, no parity

//nastaveni USARTU1 snimac
myUBRR=F_CPU/16/BAUDRATE1-1;
UBRR1H = (unsigned char)(myUBRR >> 8); // calculate baudrate and set high byte
UBRR1L = (unsigned char)myUBRR; // and low byte
UCSR1B = (1<<TXEN1)|(1<<RXEN1)/|(1<<RXCIE1)|(1<<TXCIE1)/; // enable transmitter and receiver
UCSR1C = (1<<UCSZ11)|(1<<UCSZ10); // 8 bit character size, 1 stop bit, no parity

vsechny zmineny promenny jsou globalni

jeste jsem zapomel

//povoleni preruseni od prijmu linky 1
SETBIT(UCSR1B, RXCIE1);
sei();

uz je to treti vec ve ktery resim stejnej problem (predtim jsem to nejak ochcal, jednalo se jen o laboratorni zarizeni). Vzdycky to dela jen mega64.

mrknu na to odpoledne když tu někdo něco nenajde dřív. Každopádně u proměnných mi šlo o to, zda mají globální proměnné využívané v přerušení “volatile”.
U vektorů - jesli jsou správný názvy, s nastavením se uvidí.

Kó můžeš přiložit buď jako soubor, nebo ho vkládej do tagu “code”.

nemaji volatile, kontroloval jsem to a neni potreba.
vektory jsou spravne, bez toho watchdogu to normalne chodilo.

Uz jsem to rozhejbal, chyba byla v inicializaci wdt. Kdyz jsem pouzil makro z wdt.h wdt_enable(WDTO_2S); namisto WDTCR=0x0F; tak to chodi. Ale zaboha nemuzu prijit na to proc. :frowning:

tak na to koukam v disasembleru, to makro dela nasledujici:

precte SREG a ulozi do R0
CLI
WDR
nastavi WDCE a WDE ve WDTCR na 1 (WDTCR=0x18)
vrati zpet hodnotu SREG z R0
nastavi WDTCR na 0x0F

coz clovek z datasheetu nevycte. Klicove je asi to CLI.

Volatile je potřeba, jinak se ti může stát, že ti optimalizátor půlku kódu vyhodí. Jednou si možná vzpomeneš :slight_smile:

ja vim, nebylo by to poprvy. Ale davam to tam az kdyz narazim.