Stránka 1 z 2

Jak na více pulsů "přes sebe" (procesor + timer)

Napsal: 27 srp 2014, 13:32
od Ruprecht
Potřebuju procesorem generovat stejně dlouhé pulsy na několika výstupech. Pulsy se mohou překrývat.
Dekóduju sériovou linku a když zpráva souhlasí, má se vygenerovat puls na příslušném výstupu. Do třech pulsů bych si poradil individuálním spouštěním interních timerů, ale potřebuju víc výstupních pulsů.
Tedy pokud spustím volně běžící timer a puls má trvat např. 25 tiků, při začástku pulsu uložím hodnotu timeru a při ">(timer+25)" puls ukončím. Do přetečení je to jednoduché (timer+25), problém mám po přetečení (při 8bit timeru např. 250+25=20). Jak se to "standardně" jednoduše řeší?
Mě napadají různé věci (nějaký flag v přerušení od přetečení, ale pak se komplikuje porovnávací matematika), jak to udělat co nejjednoduššeji?
Dík

Napsal: 27 srp 2014, 15:13
od hakamusai
Nešlo by nastavit timer tak,aby od spuštění do přetečení trval jeden puls? V přerušení se ošetří flag,podle potřeby nastaví výstup a přičte counter (podle toho kolik je třeba ).

Napsal: 27 srp 2014, 20:10
od jiriS
Timer/Counter Compare Match
Porovnání hodnoty čítače s přednastavenou hodnotou v registru vygeneruje přerušení. Hodnotu samozřejmě musíš do registru uložit včas- před přetečením, a správnou, ale to by neměl být problém. Spíše je problém, že pokud timer nepřeteče, informace se neuloží do registru.
Pro úplnost- píšu o ATMEL, TINY nebo MEGA, mají i dva registry Compare.
Jiné mají několik čítačů.
Další možnost- číst periodicky hodnotu timeru a porovnávat ji programově, ale to je náročnější na čas.
Další možnost- generuješ první impuls- ukončení přetečním, máš generovat další. Přečteš stav timeru, odečteš dobu do přeteční od celkové doby impulsu. Při přerušení, ve kterém uknčíš první impuls, zapíšeš do timeru hodnotu, kdy odečteš vypočtený rozdíl od čísla 255. Tak ti dlší přetečení přijde ve správnou dobu.
Jirka
P.S.: Snad jsem to vysvětlil tak, aby to bylo pochopitelné.

Napsal: 27 srp 2014, 20:34
od ZdenekHQ
Nevím, jestli to napíšu přesně, ale dělám na něčem podobným.

Každej puls má svoji proměnnou-čítač, všechny se zvýší o 1 v přerušení (u mě je 10ms) - pokud nedosáhnou 255, pak se zastaví.

Na začátku pulsu se patřičný čítač resetuje, generuje se na výstupu procesoru začátek pulsu, po načítání nastaveného času se generuje příznak pro hlavní program, který puls resetuje. Jde to obsloužit přímo i v přerušení.

Takhle mě běží třeba 10 nezávislých časovačů, co umí časy i v sekundách, je se čítají desítky, stovky a tisíce ms.

V případě 10ms je to hračka, když mám půl mikrosekundy na cyklus. Pokud by ty šířky pulsu byly na úrovni pár strojových cyklů, nebude to samozřejmě fungovat.

Napsal: 27 srp 2014, 20:42
od ZdenekHQ
MImochodem, kdyby jsi chtěl jít až na časy pár desítek period oscilátoru, dá se použít externí čítač s autoresetem, třeba 4017 či 4060 s tím, že po načítání periody se zastaví. Spustí se opět vynulováním, což je jen úzký puls na výstupu procesoru.

P.S. Pokud vynechávám či pletu písmena, je to tím, že mám palec v obvaze. Není nad to se říznout ve správný okamžik....

Napsal: 27 srp 2014, 21:54
od jiriS
Nešikovný maso musí pryč :)

Napsal: 27 srp 2014, 23:34
od ZdenekHQ
Jojo, jodisol + papírovej kapesník + elektrikářská páska + mikrotenovej pytlík. Jediný řešení, když mě dovezou půl prasete (50kg) a já se říznu při prvním tahu dobře nabroušeným nožem, protože do té doby jsem trávil týdny u počítače a ruce se nějak zpomněly "přepnout". Ale už je hotovo. Sorry za OT.

Napsal: 29 srp 2014, 11:15
od mtajovsky
ZdenekHQ píše: ... Každej puls má svoji proměnnou-čítač, všechny se zvýší o 1 v přerušení (u mě je 10ms) - pokud nedosáhnou 255, pak se zastaví.
...
Na začátku pulsu se patřičný čítač resetuje, generuje se na výstupu procesoru začátek pulsu, po načítání nastaveného času se generuje příznak pro hlavní program, který puls resetuje. Jde to obsloužit přímo i v přerušení.
Tohle děláte v zásadě správně. Obvykle se to dělá s následujícími pravidly:
- časovací bloky se obsluhují v přerušení od vybraného řídícího HW timeru
- nastavení časovacího bloku se děje ne nulováním jeho čítače, ale jeho nastavením podle požadované doby vypršení v nějaké synchronizované funkci setTimer(u16 time_out)
- čítače časovacích bloků se v přerušovací rutině dekrementují a po dosažení 0 se nastaví flag vypršení času nebo se rovnou volá dedikovaná rutina. Ta potom ale (pozor) běží na úrovni přerušení.
- není-li dedikovaná rutina, hlavní program na nastavení flagu příslušně reaguje a funkci setTimer() volá až tehdy, když potřebuje nastavit nový časový interval

Je samozřejmé, že setTimer() a kontrola flagů by se měla dělat se zakázaným přerušením od řídícího timeru.

Napsal: 29 srp 2014, 12:57
od jiriS
Ano, moožností je povícero, záleží také na dalších okolnostech.

Napsal: 29 srp 2014, 16:17
od ZdenekHQ
Čítání od nuly používám pro případ, že by bylo potřeba generovat nějakou sekvenci pulsů v návaznosti na stavu čítače, tak aby se mě to nepletlo. Ono při vývoji je hromada jiných problémů a jak je jich moc, spadne to jak domek z karet.

Napsal: 29 srp 2014, 19:32
od termit256
Nepises jak dlouhe maji byt ty pulzy a jak presne ma byt dodrzena jejich delka. To je pro reseni pomerne zasadni

Napsal: 30 srp 2014, 16:53
od Ruprecht
Délka pulsů 1ms +-100us

Napsal: 30 srp 2014, 17:09
od hakamusai
Pro jakej procesor to je? 1ms puls i prodleva ? Kolik pulsů ? Kolik výstupů ? Jak se pulsy mají překrývat ?

Napsal: 30 srp 2014, 17:58
od Ruprecht
Nějaké 8bit AVRko, třeba tiny2313.
Pulsy se generují po dekódování sériové linky (pokud přijatá zpráva souhlasí, okamžitě na příslušném výstupu začne puls, který má trvat 1ms). Výstupů je dvanáct. Zprávy mohou přijít např. 300us po sobě, tzn. první ještě trvá, druhý započne (nebo taky mohou přijít s hodinovým rozestupem nebo jednou za den, ale to není podstatné). Každý z nich je dlouhý 1ms, jen mají jiné začátky.

Napsal: 30 srp 2014, 19:19
od hakamusai
Ajjj,s AVR poradit nedovedu.:(