Jak na více pulsů "přes sebe" (procesor + timer)
Moderátor: Moderátoři
Jak na více pulsů "přes sebe" (procesor + timer)
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
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é.
- ZdenekHQ
- Významný člen
- Příspěvky: 25519
- Registrován: 21 črc 2006, 00:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
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.
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
- ZdenekHQ
- Významný člen
- Příspěvky: 25519
- Registrován: 21 črc 2006, 00:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
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....
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
- ZdenekHQ
- Významný člen
- Příspěvky: 25519
- Registrován: 21 črc 2006, 00:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
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.
- ZdenekHQ
- Významný člen
- Příspěvky: 25519
- Registrován: 21 črc 2006, 00:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
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.