PIC16F628A-USART nevyvolá přerušení při větším objemu dat

Hezký den! Potýkám se s problémem při příjmu dat po sériovém kanále PIC16F628A. Vše chodí dobře do doby kdy dojde pravděpodobně k přehlcení (alespoň moje teorie). Pokud posílám z PC data pomaleji (s prodlevou) chodí vše jak má. Při “zasypání” kontroléru velkým množstvím přijatých dat už dále nedojde k vyvolání přerušení a program cykluje stále ve smyšce mimo něj. Děkuji za rady :slight_smile:

:arrow_right: administrator: přejmenováno z “PIC16F628A USART preruseni”
PWM led.asm (5.87 KB)

nejsem teda nějakej expert, ale asi takhle.
S prodlevou to funguje proto, že hnedka po přijetí bajtu ho zpracováváte, tak díky prodlevě je na to zpracování čas. Bylo by lepčí nejdříve všechna data přijmout a pak až je zpracovat. Procesor má jen dvoubajtový FIFO zásobník a ten to všecko nestíhá pobírat, je potřeba si udělat vlastní zásobník, větší, všecko tam naskládat a pak pracovat s datama. udělat si nějaký počítadlo podle čeho by se poznalo jestli je komunikace celá a nějakej časovač kerej případně komunikaci ukončí pokud to nebude všecko pod přerušenim.
Tedy alespon takto to řeším já, a jak sem psal, nejsem expert, tak nevím jestli je to postup uplně správný:) tak ještě počkejte na odezvu ostatních:)

Děkuji za rychlou reakci. Data jsou zpracovávána v přerušení. Po přijetí celého slova je vyvolané přerušení a data uložena k pozdějšímu zpracování. Tj podobně jak to píšete Vy. Přijde mi to lepší než čekat až něco přijde “a zdržovat se tím”. Můžu mezitím běhat v hlavní smyčce… i když v tomto programu to zas tolik potřeba není. Mám tento kód použitý i jinde kde je to nutné (a chyba je stejná). Není přímo problém s tím, že by program nestíhal přijmout. On přijímá v pohodě, ale pokud to tam sypu rychle přestane skákat do přerušení i potom co přestanu vysílat data zůstane zaseklý a jakýkoliv další přijatý byte už nevyvolá přávě přerušení. Nemůžu přijít na to proč.

Zvláštní je, že tento stav nastává náhodně… někdy to běží třeba 30s … někdy 1s … jindy 3s … Pokud vysílám data třeba s 350ms přestávkou tak vše chodí dobře. Jde mi jen o to odstranit stav, kdy se zařízení zasekne. Zajimavé je, že pokud přepnu DIP přepínač (zvolím adresu zařízení) dojde k resetu i v zaseklém stavu, ale sériový kanál se nerozběhne. Pouze se vypne PWM modul (jak má).

Než jsem psal sem zkoušel jsem i třeba vyloženě vypnout po začátku skoku přerušení (aby se během přerušení nevyvolalo další přerušení a nepomohlo též) Třeba je chyba i někde v zálohování důležitých registrů při skoku do přerušení… fakt nevím… Opravdu nejsem žádný profík :slight_smile: :slight_smile: … Budu rád za jakýkoliv nápad… Díky!

tohle to samé mi to dělalo ze začátku, je to chyba při příjmu dat. Dochází k přehlcení dvoubajtového zásobníku FIFO a nastaví se příznak přetečení vstupního bufferu a zakáže se příjem dat. Je potřeba zajistit co nejrychlejší vyzvednutí bajtu a jeho uložení a nepracovat s datama okamžitě ale po ukončení celé komunikace. a někde v programu detekovat příznak přetečení vstupního bufferu, pak jak je v datashetu psáno tak vynulovat a znova nastavit bit pro povolení příjmu dat. nebo nějak tak to tam je napsané.

Tak opravdu pomohlo pohlídat přetečení bufferu. Zvláštní, že pokud se přeplní a provedu znovuuvedení do provozu probliknou mi více LED moduly pověšeny na PWM výstupu… nějaká haluz… ale tak to se stejně v normálnim režimu stávat nebude… hlavně, že nedojde k zaseknutí. Kdyby náhodou napadlo čim by mohlo být i tohle… WDT ani BOR to nedělá… Díky

tak dyštak sem hodně aktualizovanej zdroják, z toho se to líp pozná než ze starýho :slight_smile:

Změna je těsně před koncem hned na začátku START
PWM led.asm (5.99 KB)

no, když nastane chyba při příjmu, tak by bylo dobré odstranit zbytky po neúspěšnej komunikaci. v Tomto případě vynulovat RX_CIT. Kdyby tam něco zustalo, tak by při první komunikaci by to po zapsání do PCL mohlo skočit jinam než by mělo, to by teoreticky mohlo způsobovat i to bliknutí LED modulu na PWM.

Myslel jsem, že to pohlídá CRC. Pokud nesedí tak data nejsou použita, ale i tak asi jednou za x přijetí seděl i s jinou hodnotou a opravdu to dělalo… možná začnu použivat nějakej simulátor… člověk do toho nevidí :slight_smile: Moc děkuji za pomoc! Problém byl vyřešen. Pokud budete chtít mám pár věcí na webu včetně zdrojáků, ale každopádně spíš se programovat učím… tak to tak vypadá… www.kaluma.tym.cz. Přeji hezký den a ještě jednou děkuji za pomoc!

Nějak jsem to teda nezkoumal,ale tohle zavaní průserem :smiley:

[code]
MOVF ADRM, W
XORWF ADRM_2, W
BTFSC STATUS, Z
GOTO START

	END[/code]

sakra ale to dost :smiley: až ted mě to došlo :smiley: za GOTO START bude potřeba přidat eště něco, nemůže to skočit na END, to pak ulitně někam do pryč, nebo se to zasekne, nebo se udělá nějaký reset?? nevim jak se to teda bude chovat, ale je to špatně :smiley:

Za END je prazdná flash, což je retlw, a nikde žádný call, tak reset.

No … poradíte nějakej lepší nápad jak provést reset? Není to optimální řešení, ale funguje :smiley: (autor - mezitím jsem si udělal registraci)

Ještě dodatek… beru to tak, že když se neprovede CLRWDT tak se to dřív nebo pozdějc resetne…

Hlidacího psa nuluješ u START. Pokus skočí na END, je to jak jsem psal.

Takže pokud chci vyvolat reset můžu tenhle způsob použít? Nebyl jsem si jistý, když na to ostatní upozornili. Díky

Na reset je nejvhodnější právě WDT. Na to stačí zaseknout procesor nekonečnou smyčkou a reset je za pár okamžiků vyřízen.
Když totiž nechá jet procesor prázdnou flash, je to jakobys jen skočil na začátek. Veškeré nastavení procesoru zůstane nezměněno, což může způsobit nemalé problémy okolnímu HW.

Takhle to vypadá líp a skolabuje to na WDT MOVF ADRM, W XORWF ADRM_2, W BTFSC STATUS, Z GOTO START GOTO $ END