Vyber tlmivky 10uH pre odrusenie AD prevodnika

Ahoj.

Pro začátek - stíněný ethernet kabel není 5e, ale 6. Kategorie 5e nemá stínění. Ale to je jenom detail.

Díval jsem se do schématu a externí pull-up odpory u tlačítek jsou zbytečné, pokud zapneš interní pull-up odpory v procesoru. Sice s nima nic nezkazíš, ale zbytečně si komplikuješ DPS. Psal jsi, že máš potíže s tím, že při zapnutí světla Ti proběhla nějaká přerušení INT0 a INT1. Dávat vstupní signály na přerušení (obzvlášť tlačítka) je klasická (v podstatě začátečnická) chyba. Ono je to hezký - stiskneš tlačítko a procesor o tom okamžitě ví. Jenže tlačítka (a nejenom ty) trpí zákmity kontaktů. Jedna varianta je ošetřit zákmity přímo v HW, druhá (a mnohem jednodušší) je řešit zákmity tlačítek pomocí SW. Všechny tlačítka obsluhuj v hlavním programu. Pokud něco z toho používáš k probuzení procesoru, pak tam to přerušení nech, ale použij ho jenom k proobuzení procesoru. V programové smyčce si přečti stav vstupu a pokud je stabilní dostatečně dlouho, považuj tlačítko za stisknuté (nebo obecně - považuj vstup za aktivní).

Druhým problémovým bodem máš komunikaci s LED páskem. Pokud máš předem dané časy ke komunikaci, pak nesmíš připustit jakékoliv zpoždění během procesu odesílání dat - říká se tomu “Time critical section”. Máš dvě možnosti :

  1. Na začátku sekvence zakázat přerušení a po odeslání dat ho zase povolit.
  2. Dát sekvenci odeslání dat do přerušení od časovače - prakticky tak zabiješ dvě mouchy jednou ranou.
  • během přerušení se další nezpracuje, až než se stávající dokončí.
  • Data do pásku odesíláš v přesně daných intervalech a přesně víš, jak často dochází ke změně dat v pásku. Lépe se pak časují veškeré efekty atd.

Pokud nastavíš časovač na 10ms a do hlavní smyčky dáš sleep (standby režim), pak 100x za sekundu odešleš data do pásku a 100x za vteřinu načteš vstupy. 10ms je pro procesor moře času - obzvlášť když používáš krystal 14MHz. Pokud je nějaký vstup aktivní, do proměnné pro něj přičteš 1, pokud není aktivní, danou proměnnou vynuluješ. Přesně tedy víš, že pokud je nějaké tlačítko aktivní 10x po sobě (napočítáš do 10), pak je stisknuto 100ms (= 0,1s) a jeho stav se dá prohlásit za aktivní (v prípadě tlačítka se dá prohlásit za stisknuté).

Tenhle princip používám ve všech svých programech. Na začátku nastavím časovač na nějakou hodnotu (obvykle 1 nebo 10ms, případně na kmitočet, který potřebuju pro refresh LED displeje apod.). V hlavní smyčce pak provedu vše potřebné a procesor uspím. Jakmile odčítá časovač, provede se opět jeden cyklus programu. Vše pak řídím příznaky na základě kterých se provádí činnosti, které se neprovádí každý cyklus. Program musí být napsaný tak, aby vždy vše stihnul provést mezi dvěma přerušeními. Delší činnosti je tak potřeba rozfázovat. Stejně tak na čekání. Na vteřinové čekání taky nedáš _delay_ms(1000), ale nastavíš nějaký odpočet a jakmile se odpočet dokončí, tak víš, že jsi čekal tak dlouho, jak jsi potřeboval. Obecně je nutné se funkci delay vyhybat jako čert kříži. a pokud už musíš dát někam delay, tak ho maximálně v rádu mikrosekund. A pokud by delay trval déle, než je doba mezi přerušeními, pak místo delaye činnost rozfázovat s využitím časovače.

Příklad programu s využitím timeru :
Mám 4-místný multiplexovaný 7-segmentový LED displej, tlačítko, LEDku.
Stiskem tlačítka rozsvítím LEDku a zapnu odpočet, po odpočítání času LEDku zhasnu. Při stisku tlačítka během odpočtu čas vynuluju a LEDku shasnu. Obojí musí reagovat pouze na stisk tlačítka, nikoliv na jeho držení. K tomu příklad nějakého dlouhého procesu, který by trval déle, než je čas mezi přerušeními.

Obsluha přerušení od časovače
{
// displej
  Vypnu napájení segmentovky, na datových pinech nastavím hodnotu další segmentovky a aktivuju ji.
// čas
 Pokud je nastavený příznak pro časování
  {
    Zjistím milisekundy
    milisekundy jsou 0 
    {
      zkontroluju čas
      čas je 0
      {
        zhasnu LED
        zruším příznak pro časování
      }
      čas není 0
      {
         odečtu čas a nastavím milisekundy na 1000.
      }
    }
  }
// dlouhý proces
  zkontrolovat odpočet
  pokud není 0
  {
    odečíst 1 
    pokud jsem dopočítal do 0 nastavit příznak pokračuj
  }
}

Program
{
  Nastavím IO piny procesoru
  Nastavím timer na 1ms (=1000Hz) s přerušením
  Načtu hodnoty vstupů a uložím si je jako aktuální i minulé.
  Vynuluju/nastavím časy a příznaky
  Povolím přerušení

  Hlavní smyčka
  {
    Uspím procesor do standby režimu (probudí se přerušením od časovače - tedy pravidelně každou 1 ms)
    Načtu vstupy
    ošetřím zákmity tlačítka
    zkontroluju aktuální stav tlačítka s minulým
    pokud je teď stisknuté a předtím ne
    {
      zkontroluju příznak časování
      časování aktvní
      {
        vymažu příznak časování
        vynuluju čas a milisekundy
        zhasnu LED
      }
      časování není aktivní
      {
        nastavím čas
        nastavím příznak časování
        rozsvítím LED
      }
    }
    uložím aktuální stav tlačítka jako minulý
    dlouhý proces
    {
      zkontroluj příznak pokračuj
      příznak je nastavený
      {
        vynulovat příznak pokračuj
        nastavit čas mezi kroky - pokud je čas mezi kroky vždy stejný, může být tady
        kroky
        {
          1: část 1
               zvýšit krok o 1
               nastavit čas mezi kroky - pokud jsou časy mezi kroky rozdílné
          2: část 2
               zvýšit krok o 1
               nastavit čas mezi kroky - pokud jsou časy mezi kroky rozdílné
          .
          .
          .
          .
          x: část x
               nastavit krok na 1 - konec procesu
               nastavit čas mezi kroky - pokud jsou časy mezi kroky rozdílné
        }
      }
  }
}

Smyslem tohohle je hlavně návod, jak vyhodit tlačítka z přerušení a dát do přerušení od časovače komunikaci s páskem. V klidu pak můžeš reagovat na tlačítka i během probíhajícího efektu.