Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • ok1kvk.cz/content
  • isbl/content
  • david.gerner/content
3 results
Select Git revision
Show changes
Showing
with 478 additions and 633 deletions
content/articles/2011/a1-contest-2011/2011_a1.png

130 B

+++
title = "A1 Contest 2011"
perex_e = "
Za nezvykle krásného počasí jsme se zúčastnili ukončení letošní 2m závodní sezóny. Více o našem závodění se dočtete uvnitř článku.
tags = ["Závody", "VHF", "Rozbité články"]
published = "2011-11-10T07:55:23.000Z"
author = "Michal, OK1WMR"
perex_e = "
Za nezvykle krásného počasí jsme se zúčastnili ukončení letošní 2m závodní sezóny. Více o našem závodění se dočtete uvnitř článku.
"
tags = ["Článek"]
+++
Za nezvykle krásného počasí jsme se zúčastnili ukončení letošní 2m závodní sezóny. Více o našem závodění se dočtete uvnitř článku.
Za nezvykle krásného počasí jsme se zúčastnili ukončení letošní 2m závodní sezóny. Více o našem závodění se dočtete uvnitř článku.
Po fiasku v [A1 Contestu v loňském roce](index.php/zavody/vkv/464-a1-contest-2010) jsem se obával, co nám připraví letošní rok. Antény jsme společně s Jirkou UBO a Vencou VKQ připravili již s týdenním předstihem. Zbývalo jen dodělat kotvy k 19m stožáru k napevno připraveným kotevním bodům a vše bylo hotovo. To jsme však nechali až na dobu před závodem.
Na Blaťák jsem vyrazil už v pátek dopoledne. Po příjezdu mě čekalo první překvapení v podobě nádherného inverzního počasí. Ve Varech bylo pošmourno a mlhavo, nahoře naopak jasno a krásně. Jako obvykle jsem nejdříve zatopil, aby bylo teplo, až přijedou kluci. Pomalu jsem vybaloval co bylo třeba a připravoval na instalaci ostatních potřebných věcí pro závod. Lehce po obědě dorazil Jirka UBO s Vencou VKQ. Po krátké debatě jsme se vrhli do dokončovacích prací na nových kotvách pro 19m stožár. Po asi 1,5h práce byl stožár v pracovní poloze a všechny antény tedy připraveny. Mezitím se k nám připojil i druhý OP náš starý dobrý kamarád [Pavel OK1AW](http://ok1aw.pksprava.cz/).
......@@ -27,6 +24,6 @@ No nic, závod jsme nakonec dokončili bez úhony s konečným skóre 425 QSO a
Protože A1 Contest byl poslední velký VKV závod v roce, tak jsme ihned po závodě začali s balením a s pracemi na zazimování pro letošek již nepotřebných ANT. Nebylo toho málo a tak jsme skončili již za hluboké tmy a kolem půl osmé večer vyrazili k domovu.
Závěrem chci všem poděkovat za QSO a těšíme se NSL v [další sezoně](https://www.google.com/calendar/embed?src=fsnnu8ruqf7ikf8glvqv21fb70@group.calendar.google.com&ctz=Europe/Prague&gsessionid=OK).Značka: **OL7C - JO60JJ - 1044m A.S.L.
**Závod: [A1 ontest 2011](http://vkvzavody.moravany.com/zavody/a12011/index.php) - [předběžné výsledky](http://www.vhfcontest.net/getlog/gentxtsql.php?zavod=54&country=1)**144 MHz - 425 QSO - 138 645 pts**![mapa dosažených spojení](/upload/ok1wmr/obrazky/2011_a1.png)..Vybavení:ANT: 18el. M2@19m, 4x10el. DK7ZB@14m, 8x4el. DK7ZB
**Závod: [A1 ontest 2011](http://vkvzavody.moravany.com/zavody/a12011/index.php) - [předběžné výsledky](http://www.vhfcontest.net/getlog/gentxtsql.php?zavod=54&country=1)**144 MHz - 425 QSO - 138 645 pts**![mapa dosažených spojení](2011_a1.png)..Vybavení:ANT: 18el. M2@19m, 4x10el. DK7ZB@14m, 8x4el. DK7ZB
RIG: IC756PROIII + TRV Sitno + 3xPA (GU43b,2xGI7b,RE025XA).SW: [Win-Test](http://www.win-test.com/)
[![](/web/images/phocagallery/zavody/2011/2011_11_a1/thumbs/phoca_thumb_m_1%20-%20panorama.JPG)](index.php/fotogalerie/category/101-)[![](/web/images/phocagallery/zavody/2011/2011_11_a1/thumbs/phoca_thumb_m_12%20-%20OK1FIK.JPG)](index.php/fotogalerie/category/101-)[![](/web/images/phocagallery/zavody/2011/2011_11_a1/thumbs/phoca_thumb_m_14%20-%20OK1FIK%20-%20griluje.JPG)](index.php/fotogalerie/category/101-)[Fotogalerie](index.php/fotogalerie/category/101-)[.](index.php/fotogalerie/category/72-)
\ No newline at end of file
[![](/web/images/phocagallery/zavody/2011/2011_11_a1/thumbs/phoca_thumb_m_1%20-%20panorama.JPG)](index.php/fotogalerie/category/101-)[![](/web/images/phocagallery/zavody/2011/2011_11_a1/thumbs/phoca_thumb_m_12%20-%20OK1FIK.JPG)](index.php/fotogalerie/category/101-)[![](/web/images/phocagallery/zavody/2011/2011_11_a1/thumbs/phoca_thumb_m_14%20-%20OK1FIK%20-%20griluje.JPG)](index.php/fotogalerie/category/101-)[Fotogalerie](index.php/fotogalerie/category/101-)[.](index.php/fotogalerie/category/72-)
+++
title = "AVR - LED panel - #1 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_001.c == LED_001.pdf == LED_001.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-02-04T06:03:27.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_001.c == LED_001.pdf == LED_001.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_001.c == LED_001.pdf == LED_001.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;amp;amp;amp;gt;</style>
---
```
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;amp;amp;amp;gt;</style>
```c
/*Mikrokontrolér ATmega8 je vlastně malý počítač s vlastním procesorem o pracovní frekvenci až 16 MHz, RAM pamětí 1KB, a obdobou HDD - 512 Bajtů EEPROM a 8 KB Flash. Mikrokontrolér má oddělenou paměť pro program a data. Vlastní program mikrokontroléru se zapisuje do paměti Flash (8 KB).Do této paměti se dá zapisovat pouze při programování mikrokontroléru.Paměť EEPROM slouží k ukládání dat při běhu programu. Ukládají se do ní data, která nechceme ztratit při restartu mikrokontroléru. Do paměti EEPROM lzezapisovat i při programování mikrokontroléru.*//*ATmega8 obsahuje také mnohé periferie, například:- 3 čítače/časovače (Slouží k načítání impulzů, nebo k přesnému časování operací)- šestikanálový A/D převodník s 10 bitovou přesností- analogový komparátor- seriové kanály (USART, SPI)- a další...*//*Potřebný SW:Pro práci s mikrokontroéry Atmel budeme potřebovat následující software:- AVR Studio (vývojové prostředí) http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725- WinAVR (přidá do AVR studia překladač jazyka C) http://winavr.sourceforge.net/download.html- eXtreme Burner- AVR (SW pro nahrávání námi vytvořených programů do mikrokontroléru) http://extremeelectronics.co.in/avr-tutorials/gui-software-for-usbasp-based-usb-avr-programmers/- usbasp-windriver.2009-02-28.zip (Ovladače USB programátoru) http://www.fischl.de/usbasp/*//*Vlastní instalace:Doporučuji nejdříve nainstalovat AVR Studio a pak teprve WinAVR. Protožeprogramu WinAVR může vadit mezera v názvu složky "Program files" je lepší oba tyto programy nainstalovat do složky např: "C:\Programy".Dále je potřeba stáhnout a rozbalit ovladače pro USB programátor, a poté připojit do USB portu samotný programátor. Po připojení programátoru se windows se pokusí neúspěšně nainstalovat ovladače pro tento hardware. - Vybereme "zpět", pak "instalovat ze seznamu či vybraného umístění" a do pole "Při hledání zahrnout i toto umístění" zadáme cestu do složky, kam jsme předtím rozbalili usbasp-windriver.2009-02-28.zip.Nakonec už zbývá jen nainstalovat program eXtreme Burner- AVR.*//*Práce s AVR Studio:- Vytvoření nového projektu:Po spuštění se AVR studio zeptá, zda má vytvořit nový, otevřít existujícíprojekt. Vybereme "New Project"Poté se zeptá, jaký typ projektu (překladač) má vytvořit. Vybereme AVR GCC (má logo GNU - obrázek pakoně). Jakmile je vybrán překladač, altivují se textová pole, do kterých napíšeme název projektu. Pro lepší přehlednost doporučuji zaškrtnout "Create folder". Ve spodní části okna můžeme zadatcestu, kam se má projekt uložit.V dalším okně se nás AVR Studio zeptá na debugger a typ mikrokontroléruvybereme "AVR simulator" a "ATmega8". Po stisknutí tlačítka "Finish" otevřeAVR Studio s prázdným projektem.*//*Nyní se můžeme pokusit napsat první program, který rozsvítí LED diody.Abychom však dokázali rozsvítit ledku, musíme se seznámit s tím, jak se v programu přistupuje k jednotlivým nožičkám mikrokontroléru. Mirokontrolér ATmega8 disponuje třemi vstupně výstupním porty (PB, PC, PD).Port je vlastně sada osmi nožiček, které mohou sloužit jako vstup (napříkladod tlačítka), nebo výstup (rozsvítí ledku, nebo sepnou tranzistor).Led diody v naší aplikaci "ATmega8 - LED panel" jsou připojeny k portu PB napiny (nožičky) 0, 1, 2, 3, 4, 5, 6 a 7.K pinům se v programu přistupuje tak, že se nejříe nataví, které nožičky majísloužit jako vstup (0) a které jako výstup (1). Toto nastavení se provádí pomocí DDR registru. Takže pokud budeme například chtít, aby na portu "D" byly nožičky0, 1, 5 a 7 použity jako vstup a ostatní nožičky (2, 3, 4 a 6) sloužily jako výstupy, použijeme registr DDRD (DDRD je DDR registr portu "D"). Do tohoto registru zapíšeme jedničky na pozice, kde mají být výstupy a nuly tam, kde budou vstupy. Takže číslo, které potřebujeme nahrát do registru DDRD je:01011100 (nultá nožička je první číslo zprava (0-čtení), první nožička je druhé číslo zprava (0-čtení), druhá nožička je třetí číslo zprava (1-zápis),atd.)Nyní potřebujeme tedy nějak do DDRD zapsat binární číslo 01011100\. Protože01011100 je v desítkové soustavě 92 lze to zařídit takto:DDRD = 92;Protože se ale nechceme zdržovat převodem binárních čísel do desítkové soustavy, můžeme číslo zapsat i takto:DDRD = 0b01011100;Předponou 0b říkáme, že následující znaky jsou číslo v binárním tvaru. Podobněpředpona 0x znamená, že následující znaky jsou číslo v šestnáckové soustavě.Pokud píšeme číslo v desítkové soustavě, žádná předpona se nepíše.Zpět však k našemu problému. Nyní již víme, jak nastavit nožičky jako vstupy nebo výstupy a zbývá nám už jen na správný pin zapsat "1", aby se rozsvítilaledka. K tomu slouží "výstupní" registr PORT. Jméno registru se odvozuje stejnějako u registru DDR (PORTB je výstupní registr portu B).Stejným způsobem se do něj i zapisuje. Na nožičky,kde chceme, aby se rozsvítila dioda, zapíšeme jedničky. Takže když budu napříkladchtít rozsvítit tři diody připojené (přez odpor) k pinům 0, 1 a 3 portu "B" zapíšeme:PORTB = 0b11110100;Tímto způsobem jdou nastavit (zapnout) dokonce i ty nožičky, které jsou v registru DDR nastaveny jako vstup, Takže se objeví +5V na všech nožičkáchu kterých je v registru PORT zapsaná jednička. Rozdíl je akorát v tom, že u nožiček, které jsou nastaveny jako výstup, se použije "silný" výstupní tranzistor, zatímco u nožiček nastavených jako vstup se použije jen malý pull-up tranzistor, který na rozsvícení ledky nestačí.Můžeme si to vyzkoušet v následujícím programu:*//*Poznámka:Zelený text je komentář. Komentář na program nemá žádný vliv. Slouží jen k okomentování a zpřehlednění programu. Uvozuje se buďto "//" (jednořádkový - ukončuje ho konbec řádku) nebo víceřádkový: začátek: /* a konec: *//*Jak již bylo napsáno, ledky jsou na našem "ATmega8 - LED panel" jsou připojenyk pinům 0 až 7 portu B. Takže budeme potřebovat registry DDRB a PORTB."Program" by mohl vypadat třeba takto:*/#include <avr/io.h> //Nejprve si nahrajeme knihovnu, ve které jsou definovány //registry DDR a PORT - samotný jazyk C tyto registry neznáint main(void) //hlavní funkce - každý program musí mít alespoň tuto funkci{ //do těchto závorek se uzavírá tělo hlavní funkce (náš program)DDRB = 0b10101010; // Každá druhá ledka bude nastavena jako výstupPORTB = 0b00001111; // První 4 LED zapneme (1 = svítí)} //konec hlavní funkce (a programu vůbec)/*Náš první "program" je hotov. Nyní již stačí jen program přeložit pomocítlačítka "build" na horní liště, nebo pomocí nabídky "Build" -> "build"a nebo pomocí klávesy F7\. Tím dojde k vytvoření HEX souboru, který můžemenahrát do mikrokontroléru. Program nahrajeme tak, že připojíme programátor k počítači a isp kabel programátoru připojíme k desce "ATmega8 - LED panel". Poté spustíme program eXtreme Burner- AVR. Stiskneme tlačítko "Open" a zadáme cestu do složky ...\Default v našem projektu (stejná cesta, jako jsme zadávali při vytvořeníprojektu v AVRstudiu).Vybereme HEX soubor a dáme "Otevřít". Program eXtreme Burner- AVR napíše, žeúspěšně načetl soubor.Nyní je třeba vybrat správný typ mikrokontroléru z nabídky "Chip" (vyberemeATmega8)Teď už stačí jen nahrát program do mikrokontreoléru výběrem "FLASH" z nabídky"Write"Pokud vše dopadlo správně, měla by nyní na našem "ATmega8 - LED panel" svítitdruhá a čtvrtá ledka. Svítí jen ty ledky, kde byla zapsána "1" pomocí "silného"tranzistoru - tedy ty, kde je zapsána "1" jak v registru DDR, tak i v registru PORT.*///Pro radioklub OK1KVK naspal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - #2 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_002.c == LED_002.pdf == LED_002.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-04-06T04:33:14.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_002.c == LED_002.pdf == LED_002.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_002.c == LED_002.pdf == LED_002.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;amp;gt;</style>
---
```
```c
/*V minulém "programu" se nám podařilo rozsvítit vybrané Led diody. Protože sevšak nejednalo o program v pravém slova smyslu, ale o pouhé jednorázové nastavení pinů, pokusíme se nyní toto nastavení v průběhu času pomocí programuměnit. Vytvoříme program, který bude ledky střídavě rozsvěcet a zhasínat.*//*Protože už Led diody nebudou svítit stále, ale pouze určitý čas, budemepotřebovat čekací funkce z knihovny "delay.h" která se nachází v adresáři"util". Tuto knihovnu načteme do programu příkazem:#include <util/delay.h>*//*Blikání je periodická činnost, a bylo by neúčelné vypisovat do nekonečna program typu:rozsviť;čekej;zhasni;čekej;rozsviť;čekej;...Takovýto program by byl velice objemný, a dokázal by bliknout pouze tolikrát,kolikrát bychom mu to napsali. My však chceme, aby ledky blikaly stále.K tomuto účelu se hodí takzvaná nekonečná smyčka. Nekonečná smyčka jeprogramová konstrukce, která zajistí nekonečné opakování instrukcí ve svémtěle.Možnosti jak zapsat nekonečnou smyčku jsou dvě:Buďto jako cyklus for:for(;;){opakované příkazy;}Nebo jako cyklus while:while (1){opakované příkazy;}Použití je víceméně libovolné, protože AVR GCC oba cykly překládá stejně.*///Náš program by tedy mohl vypadat takto:/*Funkce čekání z knihovny delay.h potřebuje vědět, na jaké frekvenci procesorpoběží, protože musí vypočítat, kolik cyklů má procesor počkat, než bude pokračovat dál. Tuto informaci očekává v konstantě "F_CPU", a my jí tedy musíme nadefinovat:*/#define F_CPU 1000000UL // 1 MHz (základní frekvence)#include <avr/io.h> //Nahrajeme zase knihovnu vstupů a výstupů (PORT, DDR)#include <util/delay.h> //Nahrajeme knihovnu čekacích funkcí/* Je vhodné si předem nadefinovat konstanty, které se později objeví v programu.Když pak budeme chtít program upravovat, nemusíme jej celý prohledávat, alestačí pouze přepsat tyto konstanty na začátku.*/#define CEKANI 500 //konstanta "CEKANI" má hodnotu 500 (500 milisekund) #define STAV1 0b01000101 //ledky které budou svítit nejdřív (1 = svítí)#define STAV2 0b10111010 //ledky, které budou svítit potom.int main (void) //jako vždy - hlavní funkce{DDRB = 0b11111111; //Piny 0 - 7 budou výstupnífor (;;) // Nekonečná smyčka { PORTB = STAV1; //Pošleme konstantu STAV1 na nožičky - rozsvítí se LED _delay_ms (CEKANI); //Čekání tolik milisekund, kolik je v konstantě CEKANI PORTB = STAV2; //Rozsvítíme jiné ledky... _delay_ms (CEKANI); //...a opět čekáme (funkce z knihovny delay.h) } // ...a zase na začátek! (cyklu for)} //konec programu - sem se program nikdy nedostane. Bude běhat pořád v //cyklu for./*Po nahrání programu do přípravku "ATmega8 - LED panel" budou střídavě blikat LED diody tak, jak je to definováno v konstantě STAV1 a STAV2\. Čas mezi jednotlivými změnami stavu je definován v konstantě CEKANI. Tyto konstanty lze libovolně měnit..*///Pro radioklub OK1KVK naspal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - #3 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_003.c == LED_003.pdf == LED_003.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-04-07T04:33:14.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_003.c == LED_003.pdf == LED_003.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_003.c == LED_003.pdf == LED_003.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;amp;amp;gt;</style>
---
```
```c
/*
V minulém programu se nám podařilo rozblikat řadu LED diod pomocí cyklu,
čekání a dvou konstant (STAV1 a STAV2) které nám určovaly, jaké ledky mají
svítit. Problém je v tom, že po napsání první konstanty musíme vytvořit tu
druhou přesně opačně (kde byly jedničky, budou nuly, a naopak), protože jinak
by nám některé ledky buďto vůbec nesvítily, nebo by svítily stále. Nyní se
proto pokusíme vytvořit podobný program jako minule, který ale bude potřebovat
čekání a dvou konstant (STAV1 a STAV2) které nám určovaly, jaké ledky mají
svítit. Problém je v tom, že po napsání první konstanty musíme vytvořit tu
druhou přesně opačně (kde byly jedničky, budou nuly, a naopak), protože jinak
by nám některé ledky buďto vůbec nesvítily, nebo by svítily stále. Nyní se
proto pokusíme vytvořit podobný program jako minule, který ale bude potřebovat
nadefinovat pouze jeden stav a druhý si vypočte sám.
K tomuto účelu se přesně hodí takzvaný bitový komplement. bitový komplement je
K tomuto účelu se přesně hodí takzvaný bitový komplement. bitový komplement je
operace, při níž se z jedniček stanou nuly, a naopak.
*/
/*
Teď ještě vědět, jak takovou operaci zapsat.
Na tomto místě se hodí uvést tabulku operátorů jazyka C, mezi které patří
Na tomto místě se hodí uvést tabulku operátorů jazyka C, mezi které patří
i náš bitový komplement.
*/
/*
Operátory v C:
+ sčítání
+ sčítání
- odčítání
* násobení
/ dělení
/ dělení
% modulus (zbytek po celočíselném dělení)
++ inkrementace (zvětšení o 1)
-- dekrementace (zmenšení o 1)
......@@ -89,7 +77,7 @@ Nyní se tedy pokusíme napsat program:
#include <avr/io.h> //Knihovna vstupů a výstupů (PORT, DDR)
#include <util/delay.h> //Knihovna čekacích funkcí
#define CEKANI 500 //kolik milisekund budou ledky svítit
#define CEKANI 500 //kolik milisekund budou ledky svítit
#define STAV1 0b01010101//které ledky se budou střídat
int main (void)
......@@ -100,17 +88,17 @@ for(;;)
{
PORTB=~PORTB; //Zapíšeme na portB bitový komplement původní hodnoty
//Vyměníme ledky - ty které svítily zhasnou, a naopak
_delay_ms (CEKANI); //Čekání
_delay_ms (CEKANI); //Čekání
}
}
/*
/*
Pozorní si jistě všimli, že se konstrukce programu zjednodušila.
Po nahrání programu do přípravku "ATmega8 - LED panel" budou střídavě blikat
LED diody tak, jak je to definováno v konstantě STAV1, rychlostí určenou
Po nahrání programu do přípravku "ATmega8 - LED panel" budou střídavě blikat
LED diody tak, jak je to definováno v konstantě STAV1, rychlostí určenou
v konstantě CEKANI. Tyto konstanty lze libovolně měnit...
*/
//Pro radioklub OK1KVK naspal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - #4 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_004.c == LED_004.pdf == LED_004.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-04-08T04:33:14.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_004.c == LED_004.pdf == LED_004.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_004.c == LED_004.pdf == LED_004.htm
.
.
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;gt;</style>
---
```
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;gt;</style>
```c
/*
Minule jsme si ukázali, jak blikat ledkou pomocí bitového komplementu (~).
Nyní bychom se mohli pokusit vytvořit světelného hada. K tomuto účelu se hodí
Minule jsme si ukázali, jak blikat ledkou pomocí bitového komplementu (~).
Nyní bychom se mohli pokusit vytvořit světelného hada. K tomuto účelu se hodí
bitový posun. Jak bylo minule uvedeno, bitový posun se zapisuje >> nebo <<.
Výsledný program by tedy mohl vypadat:
*/
......@@ -37,63 +29,63 @@ Výsledný program by tedy mohl vypadat:
#include <avr/io.h> //Knihovna vstupů a výstupů (PORT, DDR)
#include <util/delay.h> //Knihovna čekacích funkcí
#define RYCHLOST 10 //Počet kroků za sekundu
#define RYCHLOST 10 //Počet kroků za sekundu
#define DELKA 3 //Délka hada (počet ledek))
int main (void)
{
DDRB = 0b11111111; //piny 0 - 5 budou výstupní
unsigned char n; //nadefinujeme si proměnnou "n", která bude sloužit
unsigned char n; //nadefinujeme si proměnnou "n", která bude sloužit
//k počítání opakování cyklu
PORTB = 0; //zhasneme všechny ledky. (1=svítí a 0=zhasnuto)
for(;;)
{ //hlavní smyčka
for(n=0;n<(8+DELKA);n++) //Smyčka s určitým počtem opakování
for(n=0;n<(8+DELKA);n++) //Smyčka s určitým počtem opakování
//(8 ledek + délka hada, aby nevznikal
//nový had, dokud ten starý nezmizí -
//můžete vyzkoušet, co se stane, když
//nový had, dokud ten starý nezmizí -
//můžete vyzkoušet, co se stane, když
//konstantu DELKA smažete.)
{
if (n<DELKA) //pokud je počet opakování menší než délka hada
{ //musíme přidat další článek hada (rozsvítit led)
//asi takto: 00000001, 00000011, 00000111, atd.
PORTB <<=1; //posuneme hada doleva (bity se posunou doleva a
PORTB <<=1; //posuneme hada doleva (bity se posunou doleva a
//vpravo se objeví 0.
//např: 00001111 po odrotování do leva: 00011110
PORTB ++; //přičteme 1 (rozsvítíme další článek):
PORTB ++; //přičteme 1 (rozsvítíme další článek):
//00011110 + 1 = 00011111 (hadovi přibyl článek)
}
}
else //pokud není počet opakování menší než délka hada
{ //-to znamená, že hada už jsme nakreslili..
PORTB <<=1; //...tak pouze posuneme doleva
PORTB <<=1; //...tak pouze posuneme doleva
//(vpravo se automaticky doplní nula)
// např: 00111110 (had je zakončen, a příště už bude
// např: 00111110 (had je zakončen, a příště už bude
//jen "lézt": 01111100, 11111000, 11110000, atd.
} //jinak by nám had pořád přirůstal, až by svítily
//všechny ledky
_delay_ms (1000/RYCHLOST); //Čekání (1000 ms = 1 sekunda) - rychlost
//je tedy počet kroků za sekundu
_delay_ms (1000/RYCHLOST); //Čekání (1000 ms = 1 sekunda) - rychlost
//je tedy počet kroků za sekundu
} //konec těla cyklu - a znovu na začátek :-)
//až se cyklus provede 8x (počet ledek) + počet ledek na hada
//- to znamená, že had už vyleze "mimo ledky"
// (10000000 -> 00000000) - všechny ledky jsou zhasnuté
//až se cyklus provede 8x (počet ledek) + počet ledek na hada
//- to znamená, že had už vyleze "mimo ledky"
// (10000000 -> 00000000) - všechny ledky jsou zhasnuté
//- cyklus se ukončí (provedl se "(8+DELKA)" krát)
} // konec nekonečné smyčky for(;;) program skočí zpátky na začátek
// a vše se opakuje.
} //konec funkce main (sem se sice program nikdy nedostane, ale funkce musí
} //konec funkce main (sem se sice program nikdy nedostane, ale funkce musí
//být ukončená, jinak by hlásil překladač chybu
/*
V tomto programu jsme použili proměnnou (n), podmíněný blok (if) a smyčku s
V tomto programu jsme použili proměnnou (n), podmíněný blok (if) a smyčku s
určitým počtem opakování (for(n=0;n<8;n++)).
*/
/*
......@@ -124,7 +116,7 @@ Podmíněný blok slouží k větvení programu. Používá se tehdy, když pot
provést nějaké příkazy jen tehdy, když platí nějaká podmínka.
Podmínka je výraz, který když je pravdivý, vykoná se blok1 a když pravdivý
není, vykoná se blok2.
Pokud obsahuje blok1 nebo blok2 více příkazů, uzavírají se do složených
Pokud obsahuje blok1 nebo blok2 více příkazů, uzavírají se do složených
závorek "{}".
*/
/*
......@@ -136,11 +128,11 @@ tělo cyklu
}
Inicializátor je vlastně začátek (odkud má cyklus počítat)
Podmínka je výraz, který když platí, tak cyklus provede další opakování.
Podmínka je výraz, který když platí, tak cyklus provede další opakování.
Pokud výraz přestane platit, cyklus se ukončí a program pokračuje za cyklem.
Inkrement je výraz, který říká, kolik se má přičíst, nebo odečíst s každým
Inkrement je výraz, který říká, kolik se má přičíst, nebo odečíst s každým
opakováním cyklu. My jsme používali: n++, což je totéž jako: n=n+1\. S každým
opakováním cyklu se tedy k proměnné "n" přičte 1\.
opakováním cyklu se tedy k proměnné "n" přičte 1\.
Tělo cyklu je sada příkazů uzavřená do složených závorek "{}" která se při
každém opakování vykoná.
......@@ -151,9 +143,9 @@ for (n=0;n<3;n++)
blok příkazů
}
Náš cyklus tedy začne:
Náš cyklus tedy začne:
n=0\. Otestuje podmínku n<3 = pravda - pokračuje se. K proměnné "n" se
n=0\. Otestuje podmínku n<3 = pravda - pokračuje se. K proměnné "n" se
přičte 1 (n++).
A znovu:
n=1 (0+1=1). Podmínka: n<3 = pravda - pokračuje se. Opět se přičte 1 (n++).
......@@ -162,26 +154,26 @@ n=2 (1+1=2). Podmínka: n<3 = pravda - pokračuje se. Zase se přičte 1 (n++).
A nakonec:
n=3 (2+1=2). Podmínka: n<3 = nepravda - konec cyklu.
Je tedy vidět, že se cyklus provedl 3x.
Je tedy vidět, že se cyklus provedl 3x.
*/
/*
Nyní se podíváme, co se stalo s registrem PORTB v našem programu.
Nejprve jsme zhasli všechny ledky tak, že jsme do PORTB zapsali samé nuly
Nejprve jsme zhasli všechny ledky tak, že jsme do PORTB zapsali samé nuly
(0 = 0b00000000).
Poté jsme vstoupili do hlavní smyčky, která neustále spouští cyklus:
"for(n=0;n<(8+DELKA);n++)". Jakmile se tento cyklus provede tolikrát, kolikrát
"for(n=0;n<(8+DELKA);n++)". Jakmile se tento cyklus provede tolikrát, kolikrát
je potřeba, program "propadne" zpět do hlavní smyčky "for(;;)" která jej vrátí
zpět na začátek cyklu "for(n=0;n<(8+DELKA);n++)"
Hlavní smyčka má tedy jediný úkol, a to resetovat náš cyklus
Hlavní smyčka má tedy jediný úkol, a to resetovat náš cyklus
"for(n=0;n<(8+DELKA);n++)".
*/
/*
Na začátku programu jsou definovány konstanty "RYCHLOST" a "DELKA", které
určují rychlost pohybu hada a jeho délku. Rychlost je dána počtem kroků za
Na začátku programu jsou definovány konstanty "RYCHLOST" a "DELKA", které
určují rychlost pohybu hada a jeho délku. Rychlost je dána počtem kroků za
sekundu (1 - 1000) a délka je dána počtem svítících ledek. (0 - kolik chcete).
*/
//Pro radioklub OK1KVK naspal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - #5 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_005.c == LED_005.pdf == LED_005.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-04-09T04:33:14.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_005.c == LED_005.pdf == LED_005.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_005.c == LED_005.pdf == LED_005.htm
.
.
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;gt;</style>
---
```
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;gt;</style>
```c
/*
V minulém programu jsme si ukázali, jak používat proměnnou, jak vytvářet cykly s
určitým počtem opakování (for) a jak používat podmínku (if).
......@@ -32,56 +24,56 @@ Umíme už tedy rosvěcet a zhasínat ledky v námi zvoleném pořadí.
*/
/*
Naše dosavadní programy mají ale jeden velký nedostatek. Pokud jsme chtěli něco
Naše dosavadní programy mají ale jeden velký nedostatek. Pokud jsme chtěli něco
změnit (délku hada, rychlost), museli jsme v programu upravit potřebné konstanty,
program zkompilovat a znovu nahrát do mikrokontroléru. Hodilo by se nám proto, aby
bylo možné tyto konstanty měnit přímo za běhu programu bez nutnosti jej upravovat
program zkompilovat a znovu nahrát do mikrokontroléru. Hodilo by se nám proto, aby
bylo možné tyto konstanty měnit přímo za běhu programu bez nutnosti jej upravovat
a znovu nahrávat.
Potřebujeme tedy, aby program nějakým způsobem zjistil, že jsme se rozhodli některou
konstantu změnit, a změnil jí sám.
K tomuto účelu můžeme použít tlačítka. Jakmile program zjistí, že jsme stiskli
K tomuto účelu můžeme použít tlačítka. Jakmile program zjistí, že jsme stiskli
tlačítko, změní konstantu, a pokračuje dál.
Nyní tedy potřebujeme v programu nějakým způsobem zjistit, že je stisknuté tlačítko.
*/
/*
Náš přípravek ATmega8_LED_start_2 má 3 tlačítka. Jedno je použito jako reset (resetuje
mikrokontrolér) a dvě jsou volná pro všeobecné použití. Tato dvě tlačítka jsou
připojena k pinům PD2 a PD3\.
mikrokontrolér) a dvě jsou volná pro všeobecné použití. Tato dvě tlačítka jsou
připojena k pinům PD2 a PD3\.
Zkusíme pomocí jednoho tlačítka (třeba PD2) prodlužovat hada z minulého příkladu
Budeme tedy potřebovat nastavit port PD2 jako VSTUP a nějakým způsobem pak zjistit,
Budeme tedy potřebovat nastavit port PD2 jako VSTUP a nějakým způsobem pak zjistit,
jaká je jeho hodnota. Nastavení PD2 jako vstup, by se provedlo pomocí registru DDRD
(registr DDR portu D) tak, že by se na příslušné místo (2\. bit) zapsala "0". Protože
(registr DDR portu D) tak, že by se na příslušné místo (2\. bit) zapsala "0". Protože
však po resetu mikrokontroléru jsou všechny I/O porty nastaveny na "0" - tedy vstup,
nemusíme nic nastavovat.
Otázkou tedy pouze je, jak z portu číst. K tomuto účelu jsou v mikrokontroléru
Otázkou tedy pouze je, jak z portu číst. K tomuto účelu jsou v mikrokontroléru
registry PIN. Registr PIN se podobně jako registry PORT a DDR označuje písmenem portu
(PINA, PINB, PINC...). Protože tlačítko je připojeno k portu "D", budeme potřebovat
(PINA, PINB, PINC...). Protože tlačítko je připojeno k portu "D", budeme potřebovat
PIND. PIND je stejně jako ostatní registry osmibitový (obsahuje 8 jedniček a nul).
Během chodu programu se do tohoto registru automaticky ukládá hodnota všech nožiček
daného portu.
Pokud je na nožičce napětí 0 - 0,8 V, objeví se v registru PIN na příslušném místě "0".
Pokud však je k nožičce připojeno napětí mezi 2 a 5 V, je příslušný bit registru PIN
nastaven na "1".
Tlačítka jsou na našem "ATmega8_LED_start_2" zapojeny tak, že pokud není tlačítko
stisknuto, je na příslušnou nožičku mikrokontroléru přivedeno 5 V.Pokud je tlačítko
Tlačítka jsou na našem "ATmega8_LED_start_2" zapojeny tak, že pokud není tlačítko
stisknuto, je na příslušnou nožičku mikrokontroléru přivedeno 5 V.Pokud je tlačítko
stisknuto, je na nožičce 0 V.
Když tedy chceme zjistit, zda je stisknuto tlačítko PD2, musíme se podívat do registru
PIND, zda je třetí bit vynulován (3 bit proto, že se nožičky i bity počítají od "0"
- 0, 1, 2, (třetí pozice)).
Abychom zjistili stav jednoho bitu z celého registru, musíme si jej takzvaně
"vymaskovat". Vymaskovat znamená, že provedeme nějakou početní operaci, která nám
odstraní ostatní (nepotřebné) bity. Zůstane nám tak osmibitové číslo, kde budou
všechny bity "0" jen náš požadovaný bit zůstane nezměněn ("0" nebo "1"). Nyní můžeme
Abychom zjistili stav jednoho bitu z celého registru, musíme si jej takzvaně
"vymaskovat". Vymaskovat znamená, že provedeme nějakou početní operaci, která nám
odstraní ostatní (nepotřebné) bity. Zůstane nám tak osmibitové číslo, kde budou
všechny bity "0" jen náš požadovaný bit zůstane nezměněn ("0" nebo "1"). Nyní můžeme
zjistit, zda je tento registr větší než "0" (bit byl "1"), nebo ne (bit byl "0").
Vymaskování se dá provést pomocí logického součinu (&). Logický součin porovná dvě
Vymaskování se dá provést pomocí logického součinu (&). Logický součin porovná dvě
proměnné tak, že postupně porovnává bity které leží na stejných místech a do výsledku
zapisuje "1" pouze tehdy, pokud byly jedničky na tomto místě v obou proměnných.
Například:
proměnná1: 10001101 (dekadicky: 141)
proměnná2: 01101011 (dekadicky: 107)
Výsledek: 00001001 (dekadicky: 9)
Výsledek: 00001001 (dekadicky: 9)
Když tedy chceme zjistit jestli je nastaven třetí bit, provedeme to takto:
......@@ -98,7 +90,7 @@ nebo:
vysledek = maska & promenna
Nyní tedy umíme zjistit stav napětí na nožičkách mikrokontroléru (registr PIN) a
vymaskovat si potřebnou nožičku (bitový součin - &). Můžeme se tedy pustit do psaní
vymaskovat si potřebnou nožičku (bitový součin - &). Můžeme se tedy pustit do psaní
programu:
*/
......@@ -130,24 +122,24 @@ for(;;)
{
if (n<delka) //pokud jsme rozsvítili méně ledek než je délka hada
{
PORTB <<=1; //přidáme článek hada (bity se posunou doleva a
PORTB <<=1; //přidáme článek hada (bity se posunou doleva a
//vpravo se doplní "0"
PORTB ++; //přičteme "1" (nastavíme nultý bit na "1")
}
}
else //pokud není počet opakování menší než délka hada
{ //to znamená, že hada už jsme nakreslili..
PORTB <<=1; //pouze posuneme bity (hada) doleva a doplní se nula...
}
_delay_ms (1000/RYCHLOST); //Čekání (1000 ms = 1 sekunda)
_delay_ms (1000/RYCHLOST); //Čekání (1000 ms = 1 sekunda)
//V tuto chmíli proběhlo vykreslení jednoho kroku hada a proběhlo čekání.
//Než ale program necháme skočit na začátek, a nakreslit další krok hada
//zkusíme se podívat, jestli někdo zrovna teď nemačká tlačítko:
if (PIND&0b00000100) //pokud je 3\. bit nastaven na "1"
{ //(tlačítko není stisknuté)
if (PIND&0b00000100) //pokud je 3\. bit nastaven na "1"
{ //(tlačítko není stisknuté)
; //nic nedělej a jdi dál (; = prázdný příkaz)
}
else //pokud není 3\. bit nastaven na "1" (někdo drží tlačítko)
......@@ -156,9 +148,9 @@ for(;;)
//Teď by se ale mohlo stát, že jsme už hada prodloužili příliž.
//Musíme tedy zjistit, jestli už had není delší než DELKA_MAX
if(delka>DELKA_MAX) //Pokud je tedy délka větší než maximum, které
if(delka>DELKA_MAX) //Pokud je tedy délka větší než maximum, které
{ //jsme si na začátku programu nastavili...
delka=DELKA_MIN; //...zkrátíme hada na minimum a můžeme zase
delka=DELKA_MIN; //...zkrátíme hada na minimum a můžeme zase
} //prodlužovat.
}
} //...a znovu na začátek smyčky
......@@ -167,12 +159,12 @@ for(;;)
} //konec funkce main
/*
Tento program by měl po nahrání do mikrokontroléru vytvořit "světelného hada",
o délce definované konstantou DELKA_MIN. Had se bude pohybovat rychlostí udanou
konstantou RYCHLOST. Po stisku tlačítka se had příští kolo objeví o jeden článek
Tento program by měl po nahrání do mikrokontroléru vytvořit "světelného hada",
o délce definované konstantou DELKA_MIN. Had se bude pohybovat rychlostí udanou
konstantou RYCHLOST. Po stisku tlačítka se had příští kolo objeví o jeden článek
delší.
*/
//Pro radioklub OK1KVK naspal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - #6 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_006.c == LED_006.pdf == LED_006.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-04-10T04:33:14.000Z"
author = "Vašek Král"
perex_e = "Další pokračování série o programování. Tentokrát se podíváme na přerušení, funkce a další. Nakonec bude ukázka programu."
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_006.c == LED_006.pdf == LED_006.htm
.
.
* * *
Kompatibilní zapojení: LED panel s ATmega8
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;gt;</style>
---
```
/*
V minulém programu jsme si ukázali, jak pomocí tlačítka ovlivňovat běh programu.
V minulém programu jsme si ukázali, jak pomocí tlačítka ovlivňovat běh programu.
Tento program však měl jeden velký nedostatek. Když jsme totiž pomocí konstanty
"RYCHLOST" zvýšili rychlost běhu hada, zvýšila se zároveň i rychlost, kterou program
"četl" zda je stisknuté tlačítko. Pokud jsme tedy nastavili rychlost kupříkladu na
`RYCHLOST` zvýšili rychlost běhu hada, zvýšila se zároveň i rychlost, kterou program
"četl" zda je stisknuté tlačítko. Pokud jsme tedy nastavili rychlost kupříkladu na
20 kroků za sekundu, tak program také 20x za jednu vteřinu zjišťoval, jestli
někdo nedrží stisknuté tlačítko. Pak se stalo, že během jednoho stisku tlačítka
(který trvá asi 0,5 vteřiny) program 10x zjistil, že je tlačítko stisknuté a
prodloužil hada. Při vyšších rychlostech bylo tedy téměř nemožné přesně nastavit
někdo nedrží stisknuté tlačítko. Pak se stalo, že během jednoho stisku tlačítka
(který trvá asi 0,5 vteřiny) program 10x zjistil, že je tlačítko stisknuté a
prodloužil hada. Při vyšších rychlostech bylo tedy téměř nemožné přesně nastavit
délku hada.
Potřebovali bychom tedy, aby se tyto dva děje (běh hada a testování tlačítka)
odehrávaly nezávisle na sobě. Tento problém lze vyřešit pomocí časovače.
Časovač je zařízení, které běží nezávisle na běhu programu a jednou za určitý čas
vygeneruje přerušení. Přerušení je vlastně takové upozornění pro procesor, že je
vygeneruje přerušení. Přerušení je vlastně takové upozornění pro procesor, že je
třeba něco udělat. Jakmile procesor obdrží požadavek o přerušení, tak dokoná právě
rozdělanou instrukci, a "odskočí si" udělat co je potřeba. Poté co vykoná vše
rozdělanou instrukci, a "odskočí si" udělat co je potřeba. Poté co vykoná vše
potřebné, se program opět vrátí k rozdělané práci a pokračuje v normálním běhu.
Pro nás to znamená, že náš program může být kdykoli v jakémkoli místě přerušen.
Z tohoto důvodu je potřeba obsluhu přerušení (to co má program vykonat, když jej
Pro nás to znamená, že náš program může být kdykoli v jakémkoli místě přerušen.
Z tohoto důvodu je potřeba obsluhu přerušení (to co má program vykonat, když jej
časovač přeruší) psát co nejkratší, aby co nejméně ovlivňovala běh hlavního programu.
*/
/*
Mikrokontrolér ATmega8 má zabudované dva osmibitové a jeden šestnáctibitový
čítač/časovač. Čítače/časovače se nazývají proto, že se dají použít nejen k přesnému
časování programu, ale také mohou sloužit jako čítač vnějších impulzů.
Časovač funguje tak, že je do něj přiveden hodinový signál, který si lze představit
časování programu, ale také mohou sloužit jako čítač vnějších impulzů.
Časovač funguje tak, že je do něj přiveden hodinový signál, který si lze představit
jako obdélníkové pulzy. Časovač s každým pulzem zvýší hodnotu ve svém registru o 1.
Vlastně funguje jako čítač hodinového signálu (počítá pulzy). Nejdůležitější ale je,
že jakmile tento čítač dojde ke své maximální hranici (přeteče), vyvolá přerušení,
že jakmile tento čítač dojde ke své maximální hranici (přeteče), vyvolá přerušení,
vynuluje se, a počítá zase od začátku. Maximální hodnota, ke které může čítač dojít,
je dána velikostí jeho registru. Pro osmibitový čítač je to číslo 255 a pro
16\. bitový je to číslo 65535\.
Toto číslo se nachází v registru TCNT. Podle čísla použitého časovače se pak mění
koncovka jeho názvu - TCNT0 = časovač 0, TCNT1 = časovač 1 a TCNT2 je časovač 2.
Pokud tedy chceme nastavit čas, za jaký nám registr časovače přeteče a vyvolá
přerušení, stačí pouze do registru TCNT zapsat nějaké číslo. Časovač pak nepočítá od
je dána velikostí jeho registru. Pro osmibitový čítač je to číslo 255 a pro
16\. bitový je to číslo 65535\.
Toto číslo se nachází v registru `TCNT`. Podle čísla použitého časovače se pak mění
koncovka jeho názvu - `TCNT0` = časovač 0, `TCNT1` = časovač 1 a `TCNT2` je časovač 2.
Pokud tedy chceme nastavit čas, za jaký nám registr časovače přeteče a vyvolá
přerušení, stačí pouze do registru `TCNT` zapsat nějaké číslo. Časovač pak nepočítá od
nuly, ale od tohoto čísla, a přeteče tedy dřív.
Jako zdroj hodinového signálu většinou slouží vlastní hodinový signál procesoru.
Protože však hodinový signál procesoru kmitá miliónkrát za vteřinu (1 MHz),
přetekl by časovač téměř 4 000x za jednu vteřinu. Protože však potřebujeme nastavit
mnohem delší časy, musíme použít takzvanou předděličku.
Protože však hodinový signál procesoru kmitá miliónkrát za vteřinu (1 MHz),
přetekl by časovač téměř 4 000x za jednu vteřinu. Protože však potřebujeme nastavit
mnohem delší časy, musíme použít takzvanou předděličku.
Předdělička je zařazená mezi zdrojem hodinového signálu a samotným časovačem.
Jak již její název napovídá, předdělička slouží k tomu, aby hodinový signál pro
Jak již její název napovídá, předdělička slouží k tomu, aby hodinový signál pro
časovač vydělila nějakým číslem. Funguje to tak, že například předdělička osmi
propustí každý osmý impulz, předdělička 64 propustí každý 64\. impulz, atd.
K řízení časovače a předděličky se používá registr TCCR (opět na konci opatřen
K řízení časovače a předděličky se používá registr `TCCR` (opět na konci opatřen
číslem časovače). Podívejme se nyní, jak se nastavuje například časovač 0:
*/
/*
TCCR0 = 0 - čítač je vypnut
TCCR0 = 1 - čítač je zapnut, a pracuje přímo s hodinovým signálem (bez předděličky)
TCCR0 = 2 - čítač je zapnut s předděličkou osmi (hodinový signál/8)
TCCR0 = 3 - čítač je zapnut s předděličkou 64
TCCR0 = 4 - čítač je zapnut s předděličkou 256
TCCR0 = 5 - čítač je zapnut s předděličkou 1024
*/
/*
Nyní tedy umíme zapnout časovač a nastavit mu předděličku (TCCR). Dokážeme také
TCCR0 = 0 - čítač je vypnut
TCCR0 = 1 - čítač je zapnut, a pracuje přímo s hodinovým signálem (bez předděličky)
TCCR0 = 2 - čítač je zapnut s předděličkou osmi (hodinový signál/8)
TCCR0 = 3 - čítač je zapnut s předděličkou 64
TCCR0 = 4 - čítač je zapnut s předděličkou 256
TCCR0 = 5 - čítač je zapnut s předděličkou 1024
Nyní tedy umíme zapnout časovač a nastavit mu předděličku `TCCR`. Dokážeme také
jemně nastavit čas, za který nám časovač přeteče. To děláme pomocí registru časovače
(TCNT), do kterého nahrajeme hodnotu, od které má začít počítat.
`TCNT`, do kterého nahrajeme hodnotu, od které má začít počítat.
Jediné co tedy potřebujeme ještě udělat, je povolit přerušení od časovače. Musíme
vlastně procesoru říct, aby toto přerušení akceptoval. Implicitně je totiž
vlastně procesoru říct, aby toto přerušení akceptoval. Implicitně je totiž
mikrokontrolér nastaven tak, že všechna přerušení (kromě resetu) ignoruje. Atmega8
má totiž 19 různých možných zdrojů přerušení jako: reset, čítače, vnější přerušení,
A/D převodník, sériové kanály a další. Všechna tato zařízení mohou vyvolat přerušení.
K povolování nebo zakazování přerušení od časovačů slouží registr TIMSK.
Nastavením některých bitů v registru TIMSK na "1" lze povolit přerušení od
K povolování nebo zakazování přerušení od časovačů slouží registr `TIMSK`.
Nastavením některých bitů v registru `TIMSK` na "1" lze povolit přerušení od
jednotlivých časovačů:
*/
/*
bit TIMSK: časovač: vektor:
0 časovač 0 ISR(TIMER0_OVF_vect)
2 časovač 1 ISR(TIMER1_OVF_vect)
6 časovač 2 ISR(TIMER2_OVF_vect)
Nakonec je ještě potřeba nastavit 7\. bit registru SREG. Tento bit slouží ke globálnímu
| bit TIMSK | časovač | vektor |
| --------- | --------- | -------------------- |
| 0 | časovač 0 | ISR(TIMER0_OVF_vect) |
| 2 | časovač 1 | ISR(TIMER1_OVF_vect) |
| 6 | časovač 2 | ISR(TIMER2_OVF_vect) |
Nakonec je ještě potřeba nastavit 7\. bit registru `SREG`. Tento bit slouží ke globálnímu
povolení nebo zakázání všech přerušení najednou.
*/
/*
Vektor je místo, kam program přeskočí, když je aktivováno přerušení. Zápis je
Vektor je místo, kam program přeskočí, když je aktivováno přerušení. Zápis je
následující:
ISR(TIMER0_OVF_vect)
{
příkazy obsluhy přerušení;
}
ISR(TIMER0_OVF_vect)
{
příkazy obsluhy přerušení;
}
Po provedení příkazů obsluhy přerušení se program vrátí zpět na místo, odkud byl
přerušen, a pokračuje v normální činnosti.
*/
/*
Nyní bychom se tedy mohli pustit do psaní programu, ale jak již bylo minule patrné,
čím delší program píšeme, tím je méně přehledný.Proto je lépe si jej rozložit na
čím delší program píšeme, tím je méně přehledný.Proto je lépe si jej rozložit na
jednotlivé dílčí problémy, a ty pak zapsat pomocí funkcí.
Například program:
*/
/*
...
PORTB = 0xff; //nastav všechny bity portu "B" na "1"
waitms(5); //počkej 5 milisekund
PORTD = 0b00000001; //nastav nultý bit portu "D" na "1"
waitms(2); //počkej 2 milisekundy
PORTD = 0b00000010; //nastav první bit portu "D" na "1"
PORTB = 0x00; //nastav všechny bity portu "B" na "0"
waitms(5); //počkej 5 milisekund
...
*/
/*
...
PORTB = 0xff; //nastav všechny bity portu "B" na "1"
waitms(5); //počkej 5 milisekund
PORTD = 0b00000001; //nastav nultý bit portu "D" na "1"
waitms(2); //počkej 2 milisekundy
PORTD = 0b00000010; //nastav první bit portu "D" na "1"
PORTB = 0x00; //nastav všechny bity portu "B" na "0"
waitms(5); //počkej 5 milisekund
...
Tento program by šel přepsat jednodušeji a přehledněji takto:
*/
/*
...
zapni_portb(); //nastav všechny bity portu "B" na "1" a počkej 5 milisekund
prepni_portd(); //přepni první a druhý bit portu "D" s prodlevou 2 milisekundy
vypni_portb(); //nastav všechny bity portu "B" na "0" a počkej 5 milisekund
...
*/
/*
...
zapni_portb(); //nastav všechny bity portu "B" na "1" a počkej 5 milisekund
prepni_portd(); //přepni první a druhý bit portu "D" s prodlevou 2 milisekundy
vypni_portb(); //nastav všechny bity portu "B" na "0" a počkej 5 milisekund
...
Program je nyní jednodušší. Řada příkazů byla nahrazena jednoduchými funkcemi.
Aby však program mohl fungovat, musíme tyto funkce nadefinovat. Definice funkce
se provádí tak, že napíšeme hlavičku funkce (jméno funkce a typy hodnot, které
funkce přijímá, popřípadě vrací. Definice funkce vypadá takto:
typ_navratove_hodnoty nazev_funkce (definice proměnných, které funkce přijímá)
{
tělo funkce
}
typ_navratove_hodnoty nazev_funkce (definice proměnných, které funkce přijímá)
{
tělo funkce
}
Protože nyní pro náš příklad nepotřebujeme předávat žádné parametry, napíšeme místo
návratové hodnoty a přijímaných hodnot slovo "void".
Definice našich nových funkcí je tedy následující:
*/
/*
void zapni_portb(void) //hlavička funkce "zapni_portb"
{ //začátek těla funkce
PORTB = 0xff; //nastav všechny bity portu "B" na "1"
waitms(5); //počkej 5 milisekund
} //konec těla funkce
*/
/*
Nyní máme nadefinovanou funkci "zapni_portb". Pokud tedy v hlavním programu
napíšeme:
zapni_portb();
//spustí se tato funkce, a provede příkazy ve svém těle:
PORTB = 0xff; //nastav všechny bity portu "B" na "1"
waitms(5); //počkej 5 milisekund
//po provedení těchto příkazů se program vrátí zpět a pokračuje dalším příkazem,
//tedy:
prepni_portd()
//Tuto funkci zatím ale nemáme definovanou. Její definice by vypadala takto:
*/
/*
void prepni_portd(void) //hlavička
{
PORTD = 0b00000001; //nastav nultý bit portu "D" na "1"
waitms(2); //počkej 2 milisekundy
PORTD = 0b00000010; //nastav první bit portu "D" na "1"
}
*/
/*
Podobným způsobem by se nadefinovala i funkce "vypni_portb". Tento program by se
void zapni_portb(void) //hlavička funkce "zapni_portb"
{ //začátek těla funkce
PORTB = 0xff; //nastav všechny bity portu "B" na "1"
waitms(5); //počkej 5 milisekund
} //konec těla funkce
Nyní máme nadefinovanou funkci "zapni_portb". Pokud tedy v hlavním programu
napíšeme `zapni_portb()` spustí se tato funkce, a provede příkazy ve svém těle:
PORTB = 0xff; //nastav všechny bity portu "B" na "1"
waitms(5); //počkej 5 milisekund
po provedení těchto příkazů se program vrátí zpět a pokračuje dalším příkazem,
tedy `prepni_portd()`
Tuto funkci zatím ale nemáme definovanou. Její definice by vypadala takto:
void prepni_portd(void) //hlavička
{
PORTD = 0b00000001; //nastav nultý bit portu "D" na "1"
waitms(2); //počkej 2 milisekundy
PORTD = 0b00000010; //nastav první bit portu "D" na "1"
}
Podobným způsobem by se nadefinovala i funkce "vypni_portb". Tento program by se
pak choval stejně, jako původní program bez funkcí.
*/
/*
Nyní se podíváme na to, jak by se zapisovala funkce, která přebírá a předává
parametry:
Mějme proměnné "cislo1", "cislo2" a "vysledek":
unsigned char cislo1, cislo2, vysledek;
unsigned char cislo1, cislo2, vysledek;
Nyní si představme, že v programu budeme potřebovat vykonat tuto operaci:
vysledek = (cislo1 + cislo2) * cislo1; //do proměnné "vysledek" se uloží součet
//proměnných "cislo1" a "cislo2" vynásobený
//proměnnou "cislo1"
vysledek = (cislo1 + cislo2) * cislo1; //do proměnné "vysledek" se uloží součet
//proměnných "cislo1" a "cislo2" vynásobený
//proměnnou "cislo1"
Tuto operaci můžeme nahradit funkcí:
vysledek = funkce_vypocet();
vysledek = funkce_vypocet();
Protože však potřebujeme, aby tato funkce počítala s nějakými proměnnými ("cislo1"
Protože však potřebujeme, aby tato funkce počítala s nějakými proměnnými ("cislo1"
a "cislo2") musíme jí tyto proměnné předat jako parametry:
vysledek = funkce_vypocet(cislo1, cislo2);
vysledek = funkce_vypocet(cislo1, cislo2);
Tento příkaz by se nyní vykonal následovně:
Program zjistí, že má něco přiřadit do proměnné "vysledek" jde tedy do prava, a
Program zjistí, že má něco přiřadit do proměnné "vysledek" jde tedy do prava, a
narazí na funkci s parametry. Zapamatuje si tedy tyto 2 parametry ("cislo1", "cislo2")
a přeskočí do funkce "funkce_vypocet()". Této funkci předá oba parametry a funkci
vykoná. Na konci funkce obdrží jedno číslo (návratovou hodnotu). Tuto hodnotu si
a přeskočí do funkce "funkce_vypocet()". Této funkci předá oba parametry a funkci
vykoná. Na konci funkce obdrží jedno číslo (návratovou hodnotu). Tuto hodnotu si
zapamatuje, a skočí zpátky k našemu příkazu:
vysledek = funkce_vypocet(cislo1, cislo2);
vysledek = funkce_vypocet(cislo1, cislo2);
Nyní již má ale funkci vypočtenou, a má v paměti uloženou její návratovou hodnotu.
Nahradí tedy původní zápis: "funkce_vypocet(cislo1, cislo2)" pouze návratovou
Nahradí tedy původní zápis: "funkce_vypocet(cislo1, cislo2)" pouze návratovou
hodnotou a vznikne:
vysledek = navratova_hodnota;
vysledek = navratova_hodnota;
Tento příkaz pak vyřeší jako prosté přiřazení - zapíše do proměnné "vysledek"
Tento příkaz pak vyřeší jako prosté přiřazení - zapíše do proměnné "vysledek"
návratovou hodnotu funkce.
Takže příkaz:
vysledek = funkce_vypocet(cislo1, cislo2);
vysledek = funkce_vypocet(cislo1, cislo2);
se vykoná stejně jako příkaz:
vysledek = (cislo1 + cislo2) * cislo1;
*/
/*
vysledek = (cislo1 + cislo2) * cislo1;
Nyní si ale musíme naší funkci ještě nadefinovat:
Napíšeme zase hlavičku funkce, a blok příkazů do těla funkce:
char funkce_vypocet(char vstup1, char vstup2);
{
char vystup; //nadefinujeme si výstupní proměnnou (sem budeme ukládat výsledek)
char funkce_vypocet(char vstup1, char vstup2);
{
char vystup; //nadefinujeme si výstupní proměnnou (sem budeme ukládat výsledek)
vystup = (vstup1 + vstup2) * vstup1; //do proměnné "vystup" vypočteme operaci
vystup = (vstup1 + vstup2) * vstup1; //do proměnné "vystup" vypočteme operaci
return vystup; //a řekneme, že se má jako návratová hodnota použít hodnota
//proměnné "vystup"
}
return vystup; //a řekneme, že se má jako návratová hodnota použít hodnota
//proměnné "vystup"
}
*/
/*
Nyní si rozebereme hlavičku funkce:
Slovo "char" před názvem funkce říká, jakého typu bude návratová hodnota (kolik
Slovo "char" před názvem funkce říká, jakého typu bude návratová hodnota (kolik
místa zabere v paměti - char = 8 bitů) Pak následuje název funkce "funkce_vypocet"
(to je název, pomocí kterého funkci voláme v programu). Za názvem následují v
závorkách parametry funkce.
(to je název, pomocí kterého funkci voláme v programu). Za názvem následují v
závorkách parametry funkce.
Zápis:
char funkce_vypocet(char vstup1, char vstup2);
char funkce_vypocet(char vstup1, char vstup2);
říká, že funkce očekává 2 parametry typu char a vrací číslo typu char.
Tělo funkce je vytvořeno stejně, jako tomu bylo v minulých případech. Jedinou novinkou
je příkaz "return", za který se napíše, co má funkce vrátit. Tento příkaz zároveň
je příkaz "return", za který se napíše, co má funkce vrátit. Tento příkaz zároveň
funkci ukončuje.
*/
/*
Nyní už tedy víme, jak používat časovač a jak rozepsat program do jednotlivých funkcí.
Ještě by se hodila jedna poznámka, a to že každá funkce musí být před svým použitím
definovaná. V opačném případě hlásí překladač chybu, že tuto funkci nezná. Prozatím
to tedy vyřešíme tak, že všechny funkce budeme definovat ještě před hlavní funkcí
("main"). Funkce main (ve které budeme naše nadefinované funkce používat) bude tedy
definovaná. V opačném případě hlásí překladač chybu, že tuto funkci nezná. Prozatím
to tedy vyřešíme tak, že všechny funkce budeme definovat ještě před hlavní funkcí
("main"). Funkce main (ve které budeme naše nadefinované funkce používat) bude tedy
nadefinovaná až jako poslední (na konci zdrojového kódu).
*/
/*
Můžeme se tedy pustit do psaní programu. Náš program by měl umět blikat ledkami v
Můžeme se tedy pustit do psaní programu. Náš program by měl umět blikat ledkami v
různých režimech a rychlostech. Režimy blikání by mohly být:
- jednoduché blikání (svítí nesvítí)
- stroboskopické blikání (rozsvícení ledek na velmi krátkou dobu)
- maják (ledky dvakrát rychle po sobě krátce bliknou)
- běžící světlo (něco podobného, jako měl KIT - světlo běhá zleva
doprava a zprava doleva)
- had (náš starý známý)
Program by se měl ovládat pomocí 2 tlačítek (PD2 a PD3), přičemž jedním tlačítkem by
- jednoduché blikání (svítí nesvítí)
- stroboskopické blikání (rozsvícení ledek na velmi krátkou dobu)
- maják (ledky dvakrát rychle po sobě krátce bliknou)
- běžící světlo (něco podobného, jako měl KIT - světlo běhá zleva
doprava a zprava doleva)
- had (náš starý známý)
Program by se měl ovládat pomocí 2 tlačítek (PD2 a PD3), přičemž jedním tlačítkem by
se měnil režim blikání, a druhým rychlost.
Program by měl fungovat tak, jednotlivé režimy blikání budou uloženy jako samostatné
funkce. Hlavhí smyčka pak zjistí, jaký režim blikání je vybrán, a podle toho spustí
Program by měl fungovat tak, jednotlivé režimy blikání budou uloženy jako samostatné
funkce. Hlavhí smyčka pak zjistí, jaký režim blikání je vybrán, a podle toho spustí
požadovanou funkci. Funkce pak provede jeden krok (posunutí hada, bliknutí, atd.)
a skončí. Čekání mezi jednotlivými kroky bude zajišťovat hlavní smyčka.
Mezitím se bude pomocí časovače0 provádět testování klávesnice, a případné nastavování
Mezitím se bude pomocí časovače0 provádět testování klávesnice, a případné nastavování
proměnných "rychlost" a "rezim".
*/
//Náš program by tedy mohl vypadat takto:
Náš program by tedy mohl vypadat takto:
```c
#define F_CPU 1000000UL // 1 MHz (základní frekvence) kvůli delay.h
#include <avr/io.h> //Knihovna vstupů a výstupů (PORT, DDR, PIN)
......@@ -311,28 +272,28 @@ proměnných "rychlost" a "rezim".
#define RYCHLOST_MIN 2 //Minimální počet kroků (bliknutí) za sekundu
#define RYCHLOST_MAX 100 //Maximální počet kroků (bliknutí) za sekundu
#define POCET_REZIMU 15 //počet režimů (režimů je 5, zbylé režimy slouží k
#define POCET_REZIMU 15 //počet režimů (režimů je 5, zbylé režimy slouží k
//prodlužování hada)
#define BLIKANI 0b00010111 //určuje, které ledky se mají střídat při režimu
#define BLIKANI 0b00010111 //určuje, které ledky se mají střídat při režimu
//jednoduchého blikání
#define STROBO_CAS 10 //(ms) - Určuje, kolik milisekund budou svítit ledky při
#define STROBO_CAS 10 //(ms) - Určuje, kolik milisekund budou svítit ledky při
//strobo efektu. Využívá se i v režimu "maják".
#define MAJAK 50 //definuje, kolik milisekund je mezi dvojicí bliknutí ve funkci
#define MAJAK 50 //definuje, kolik milisekund je mezi dvojicí bliknutí ve funkci
//maják
//Vytvoříme si tzv. globální proměnné (jsou deklarované mimo všechny funkce,
//Vytvoříme si tzv. globální proměnné (jsou deklarované mimo všechny funkce,
//díky čemuž jsou ve všech funkcích "viditelné"
//Běžná proměnná totiž platí jen mezi složenými závorkami {}, mezi kterými byla
//Běžná proměnná totiž platí jen mezi složenými závorkami {}, mezi kterými byla
//vytvořena (to znamená pouze uvnitř funkce).
unsigned char rychlost; //globální proměnná - rychlost blikání
unsigned char rezim; //globální proměnná - režim blikání
unsigned char zmena; //globální proměnná - Sem budeme ukládat informaci, že byl
//právě změněn režim blikání (některé funkce se budou při
//svém prvním spuštění potřebovat inicializovat(nastavit
unsigned char zmena; //globální proměnná - Sem budeme ukládat informaci, že byl
//právě změněn režim blikání (některé funkce se budou při
//svém prvním spuštění potřebovat inicializovat(nastavit
//základní hodnoty)
//Tyto proměnné musejí být globální, protože se nastavují ve vektoru přerušení,
//a čtou se v hlavní funkci. Musejí tedy být přístupné z obou těchto míst.
......@@ -344,20 +305,20 @@ unsigned char zmena; //globální proměnná - Sem budeme ukládat informaci, ž
/*****************************/
ISR(TIMER0_OVF_vect)
{
static unsigned char tlacitko; //statická proměnná - uchovává si hodnotu mezi
static unsigned char tlacitko; //statická proměnná - uchovává si hodnotu mezi
//jednotlivými voláními funkce
//Pro nás slouží jako informace, že minule bylo
//Pro nás slouží jako informace, že minule bylo
//stisknuto tlačítko (abychom předešli nechtěnému
//přečtení jednoho stisku 2x)
TCNT0=157; //Časovač začne počítat od 157 (255-157=98) předdělička je 1024.
//Hodinový kmitočet procesoru je 1MHz. Takže:
//Hodinový kmitočet procesoru je 1MHz. Takže:
//1 000 000 / 1024 / 98 = 10 Hz (klávesnice se kontroluje přibližně
//10x za vteřinu)
if (tlacitko) //pokud bylo minule stisknuto tlačítko...
{
tlacitko=0; //...tak proměnnou "tlacitko" vynulujeme...
return; //...a pro jistotu ukončíme cyklus (uživatel by mohl tlačítko
return; //...a pro jistotu ukončíme cyklus (uživatel by mohl tlačítko
} //stále držet)
if (!(PIND&0b00000100)) //pokud je stisknuté tlačítko 1 (režim)
......@@ -369,8 +330,8 @@ ISR(TIMER0_OVF_vect)
if (!(PIND&0b00001000)) //pokud je stisknuté tlačítko 2 (rychlost)
{
rychlost*=2; //přidáme rychlost (2x zrychlíme je to totéž jako: rychlost<<1;)
tlacitko=1; //uložíme si informaci, že bylo stisknuto tlačítko
rychlost*=2; //přidáme rychlost (2x zrychlíme je to totéž jako: rychlost<<1;)
tlacitko=1; //uložíme si informaci, že bylo stisknuto tlačítko
}
if (rezim>POCET_REZIMU) //pokud jsme již překročili povolený počet režimů...
......@@ -388,14 +349,14 @@ ISR(TIMER0_OVF_vect)
/*****************************/
/*funkce jednoduchého blikání*/
/*****************************/
void blik (void)
void blik (void)
{
if (zmena) //pokud je funkce spuštěna poprvé
{
PORTB= BLIKANI; //nastav do portu "B" počáteční hodnotu
PORTB= BLIKANI; //nastav do portu "B" počáteční hodnotu
zmena=0; //vynuluj proměnnou "zmena" (příště už to nebude poprvé)
}
else //pokud to není poprvé...
else //pokud to není poprvé...
{
PORTB=~PORTB; //do poru "B" dáme jeho bitový komplement - vyměníme "0" za "1"
}
......@@ -413,7 +374,7 @@ void strobo (void)
/*****************************/
/* Maják */
/*****************************/
/*****************************/
void majak (void)
{
for(char n=0;n<2;n++) //cyklus o 2 opakováních:
......@@ -428,13 +389,13 @@ void majak (void)
/*****************************/
/* Běžící světlo */
/*****************************/
/*****************************/
void semtam (void)
{
static unsigned char pozice; //statická proměnná - uchovává si hodnotu mezi
//jednotlivými voláními funkce
//nám bude sloužit jako ukazatel, kde zrovna je ledka
//1-8 = 1.-8\. ledka. 9-15 = 6.-1\. ledka (jede zpátky)
static unsigned char pozice; //statická proměnná - uchovává si hodnotu mezi
//jednotlivými voláními funkce
//nám bude sloužit jako ukazatel, kde zrovna je ledka
//1-8 = 1.-8\. ledka. 9-15 = 6.-1\. ledka (jede zpátky)
if (zmena) //pokud je funkce volána poprvé
{
PORTB=1; //zhasneme všechny ledky a rozsvítíme pouze jednu (PB0)...
......@@ -446,7 +407,7 @@ void semtam (void)
{
PORTB<<=1; //posuň ledku o 1 doleva.
}
else //pozice je větší nebo rovna 8, (už jsme dojeli k levému kraji)
else //pozice je větší nebo rovna 8, (už jsme dojeli k levému kraji)
{
PORTB>>=1; //posuň ledku o 1 doprava (jedeme zase na začátek)
}
......@@ -460,13 +421,13 @@ void semtam (void)
/*****************************/
/* Had */
/*****************************/
/*****************************/
void had (unsigned char delka) //náš starý známý had
{ //Funkce "had" přebírá parametr délka. Při volání funkce tedy
{ //Funkce "had" přebírá parametr délka. Při volání funkce tedy
//můžeme (nebo spíš musíme) zadat délku hada.
static unsigned char pozice; //statická proměnná - ukazatel na pozici hada
//(stejně jako u běžícího světla)
//(stejně jako u běžícího světla)
if (zmena) //pokud je funkce volána poprvé (stejně jako u běžícího světla)
{
......@@ -475,15 +436,15 @@ void had (unsigned char delka) //náš starý známý had
zmena=0; //vynuluj proměnnou "zmena" (příště už to nebude poprvé)
}
//Dosavadní část je vlastně stejná, jako byla použita ve funkci "Běžící světlo"
//Následující část funkce "had" je víceméně stejná, jako v našem minulém programu.
//Následující část funkce "had" je víceméně stejná, jako v našem minulém programu.
if (pozice<delka) //pokud jsme rozsvítili méně ledek než je délka hada
{
PORTB <<=1; //přidáme článek hada (bity se posunou doleva a
PORTB <<=1; //přidáme článek hada (bity se posunou doleva a
//vpravo se doplní "0"
PORTB ++; //přičteme "1" (nastavíme nultý bit na "1")
}
}
else //pokud není počet opakování menší než délka hada
{ //to znamená, že hada už jsme nakreslili..
......@@ -502,18 +463,18 @@ void had (unsigned char delka) //náš starý známý had
/************************************************/
/*****************************/
/** Hlavní funkce **/
/*****************************/
/*****************************/
int main (void)
{
DDRB = 0xff; //Nastavíme port "B" jako výstupní
TIMSK|=1; //nastavíme nultý bit na "1" a ostatní necháme (povolíme přerušení
TIMSK|=1; //nastavíme nultý bit na "1" a ostatní necháme (povolíme přerušení
//od časovače "0")
TCCR0 = 5; //Zapneme časovač "0" s předděličkou 1024.
SREG |= (1<<7); //povolení přerušení (nastavíme 7\. bit registru SREG)
rezim=1; //nastavíme režim blikání na 1\. možnost (jednoduché blikání)
zmena=1; //nastavíme, jako že jsme právě změnili režim (funkce blik bude spuštěna
zmena=1; //nastavíme, jako že jsme právě změnili režim (funkce blik bude spuštěna
//poprvé)
rychlost=RYCHLOST_MIN; //nastavíme rychlost na minimum
......@@ -524,14 +485,14 @@ for(;;) //hlavní smyčka
{ //Tato smyčka bude pouze zajišťovat výběr správné funkce (podle nastaveného
//režimu blikání, a čekání mezi jednotlivými kroky.
//Výběr správné funkce provedeme pomocí příkazu "switch".Switch je vlastně
//Výběr správné funkce provedeme pomocí příkazu "switch".Switch je vlastně
//něco jako vícenásobný "if"
switch (rezim) //budeme rozhodovat podle toho, co je v proměnné "rezim"...
{
case 1: //...v případě že je to číslo "1"...
blik(); //...zavoláme funkci "blik()" (1\. režim)...
break; //...a vyskočíme z příkazu switch (jinak by se provedly všechny
break; //...a vyskočíme z příkazu switch (jinak by se provedly všechny
//následující instrukce - switch by už další podmínky netestoval.
case 2: //...v případě že je to číslo "2"...
......@@ -546,23 +507,22 @@ for(;;) //hlavní smyčka
semtam();//...zavoláme funkci "semtam()"
break;
default: //Pokud nevyhovoval ani jeden z předchozích případů - zbývá už
default: //Pokud nevyhovoval ani jeden z předchozích případů - zbývá už
//jen funkce "had" (5\. a vyšší režim)
had(rezim-4); //zavoláme funkci "had" a jako parametr jí předáme číslo
had(rezim-4); //zavoláme funkci "had" a jako parametr jí předáme číslo
//režimu bez 4\. To znamená, že funkce může obdržet číslo
//jedna až něco, které pak použije k nastavení délky hada
} //konec příkazu switch
} //konec příkazu switch
//úspěšně jsme tedy vybrali jakou funkci má program provést a nyní nám už zbývá
//jen počkat požadovanou dobu, než se program pustí do dalšího kroku:
//úspěšně jsme tedy vybrali jakou funkci má program provést a nyní nám už zbývá
//jen počkat požadovanou dobu, než se program pustí do dalšího kroku:
_delay_ms (1000/rychlost); //Čekání (1000 ms = 1 sekunda)
_delay_ms (1000/rychlost); //Čekání (1000 ms = 1 sekunda)
} //konec hlavní smyčky
} //konec funkce main
//Pro radioklub OK1KVK naspal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - #7 Program"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_007.c == LED_007.pdf == LED_007.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-10-04T04:09:28.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_007.c == LED_007.pdf == LED_007.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_007.c == LED_007.pdf == LED_007.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;gt;</style>
---
```
```c
/*
Nyní již umíme používat příkazy k větvení programu (podmínky) "if" a "switch". Umíme
také rozložit program na jednoduché funkce a používat cyklus "for". Co se týče cyklů,
......@@ -123,7 +111,7 @@ vlastně jeden ze způsobů, jak převést digitální signál (nuly a jedničky
analogový (jas žárovky, výkon motoru, aj.).
*/
/*
Můžeme si tedy vyzkoušet, jak bude regulace jasu fungovat u našeho starého známého
Můžeme si tedy vyzkoušet, jak bude regulace jasu fungovat u našeho starého známého
hada. Program had bude podobný jako v minulých programech, pouze místo příkazů:
PORTB=...;
_delay_ms(...);
......@@ -131,7 +119,7 @@ _delay_ms(...);
zaměníme za funkci:
rozsvit(...).
Funkce "rozsvit()" bude zajišťovat rychlé blikání ledek (viz výše). Délku periody
Funkce "rozsvit()" bude zajišťovat rychlé blikání ledek (viz výše). Délku periody
světla vůči periodě tmy, bude tato funkce přebírat z proměnné "jas".
*/
/*
......@@ -145,37 +133,37 @@ Program by mohl vypadat třeba takto:
#define VZOR 0b00000111 //tato konstanta určuje délku hada
#define DOBA 50 //tato konstanta ovlivňuje rychlost hada
#define DOBA 50 //tato konstanta ovlivňuje rychlost hada
//(čas na jeden krok v ms)
volatile unsigned char jas=64; /*tato proměnná je globální, protože se nastavuje v
přerušení (čtení tlačítek) a zároveň ji potřebujeme číst ve funkci "rozsvit".
volatile unsigned char jas=64; /*tato proměnná je globální, protože se nastavuje v
přerušení (čtení tlačítek) a zároveň ji potřebujeme číst ve funkci "rozsvit".
V této proměnné bude uloženo číslo (0-128), které bude určovat jas ledek.*/
/********************************************/
/* **************************** */
/* * Deklarace funkcí * */
/* **************************** */
/* **************************** */
/********************************************/
/*
Deklarace funkce je vlastně hlavička funkce, se středníkem. Hlavička se píše tak jak
je uvedena v definici. Pomocí deklarace funkce, dáváme překladači najevo, že daná
funkce existuje. Od tohoto místa dále tedy můžeme funkci volat, i když je ve
je uvedena v definici. Pomocí deklarace funkce, dáváme překladači najevo, že daná
funkce existuje. Od tohoto místa dále tedy můžeme funkci volat, i když je ve
skutečnosti nadefinovaná až na konci programu.
*/
void rozsvit(unsigned char co, unsigned char jakdlouho);
/*
Nadeklarujeme si funkci, která zařídí regulaci jasu ledek, jak bylo popsáno výše.
Tato funkce bude přebírat parametry:
"co" = ledky které budou svítit,
"jakdlouho" = jak dlouho budou svítit [ms]
Nadeklarujeme si funkci, která zařídí regulaci jasu ledek, jak bylo popsáno výše.
Tato funkce bude přebírat parametry:
"co" = ledky které budou svítit,
"jakdlouho" = jak dlouho budou svítit [ms]
Dále tuto funkci ovlivňuje globální proměnná "jas", která udává jas
ledek v procentech (0 - 128) */
/********************************************/
/* **************************** */
/* * Hlavní funkce * */
/* **************************** */
/* **************************** */
/********************************************/
int main (void)
......@@ -204,12 +192,12 @@ for(;;)
/********************************************/
/* **************************** */
/* * Definice funkcí * */
/* **************************** */
/* **************************** */
/********************************************/
/*****************************/
/* Rozsvit */
/*****************************/
/*****************************/
void rozsvit(unsigned char co, unsigned char jakdlouho)
{
......@@ -217,7 +205,7 @@ void rozsvit(unsigned char co, unsigned char jakdlouho)
{
for (unsigned char j=1;j<=128;j++)
{
if(jas>=j) //pokud je v proměnné "j" menší číslo než v proměnné "jas"
if(jas>=j) //pokud je v proměnné "j" menší číslo než v proměnné "jas"
PORTB=co; //Rozsvítíme požadované ledky
else //jinak
PORTB = 0; //zhasneme všechny ledky
......@@ -227,7 +215,7 @@ void rozsvit(unsigned char co, unsigned char jakdlouho)
}
/*
Je snahou, aby tato smyčka obsahovala co nejméně příkazů, protože vykonání
každého příkazu zabere procesoru nějaký čas.
každého příkazu zabere procesoru nějaký čas.
Jeden cyklus tedy netrvá pouze 128 * 7 us = 896 us, nýbrž o něco déle.
*/
}
......@@ -238,38 +226,38 @@ void rozsvit(unsigned char co, unsigned char jakdlouho)
ISR(TIMER0_OVF_vect)
{
TCNT0=157; //Časovač začne počítat od 157 (255-157=98) předdělička je 1024.
//Hodinový kmitočet procesoru je 1MHz. Takže:
//Hodinový kmitočet procesoru je 1MHz. Takže:
//1 000 000 / 1024 / 98 = 10 Hz (klávesnice se kontroluje přibližně
//10x za vteřinu, neboli jednou za cca 100 ms)
if (!(PIND&0b00000100)) //pokud je stisknuté tlačítko 1 (jas+)
{
if (jas==0) //pokud je jas "0"
jas=1;
jas=1;
else //pokud jas není "0"
{
if(jas<128) //pokud je menší než 128 (maximální jas)
jas<<=1; //zvýšíme jas na dvojnásobek (bitový posun doleva)
/*
Proměnná "jas" tedy může nabývat hodnot:
/*
Proměnná "jas" tedy může nabývat hodnot:
0, 1, 2, 4, 8, 16, 32, 64 a 128
*/
}
TCNT0=60; //Časovač začne počítat od 60 místo 157 (počítá do 255), takže
TCNT0=60; //Časovač začne počítat od 60 místo 157 (počítá do 255), takže
}
if (!(PIND&0b00001000)) //pokud je stisknuté tlačítko 2 (jas-)
{
jas>>=1; //snížíme jas na polovinu (bitový posun doprava)
TCNT0=60; //Časovač začne počítat od 60 místo 157 (počítá do 255), takže
TCNT0=60; //Časovač začne počítat od 60 místo 157 (počítá do 255), takže
//příští čtení tlačítka bude za cca 200 ms místo původních 100 ms.
}
}
//Pro radioklub OK1KVK naspal Vašek Král
//Pro radioklub OK1KVK napsal Vašek Král
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - Příklad - Časovač s přerušením"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Casovac-preruseni.c == LED_Casovac-preruseni.pdf == LED_Casovac-preruseni.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-06-22T18:01:10.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Casovac-preruseni.c == LED_Casovac-preruseni.pdf == LED_Casovac-preruseni.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_Casovac-preruseni.c == LED_Casovac-preruseni.pdf == LED_Casovac-preruseni.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;gt;</style>
---
```
```c
/*
Popis:
Vybrané ledky budou blikat cca 2x za vteřinu
Ledky které mají takto blikat jsou vybrány konstantou "LED" a čas svícení je dán
děličkou časovače a šířkou jeho registru.
V tomto příkladu bude použit čítač/časovač "0" který má šířku registru 8 bitů
V tomto příkladu bude použit čítač/časovač "0" který má šířku registru 8 bitů
to znamená že počítá do 255.
Čítač bude mít zapnutou děličku hodinového signálu s dělitelem 1024.
Výsledná frekvence tedy bude 1 000 000/1024/255 = 3,8 Hz - při každém přetečení
Výsledná frekvence tedy bude 1 000 000/1024/255 = 3,8 Hz - při každém přetečení
budeme negovat stav ledek, takže se rozsvítí a zhasnou přibližně 2x za sekundu.
Přetečení čítače způsobí přerušení, ve kterém bude negován stav ledek.
......@@ -69,7 +57,7 @@ while (1) // Nekonečná smyčka (dokud 1 = pořád)
//- zde by mohl být program, který nebude zdržován blikáním
}//Konec cyklu "while (1)" - program skočí zpět na jeho začátek
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - Příklad - Časovač"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Casovac.c == LED_Casovac.pdf == LED_Casovac.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-06-22T17:57:11.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Casovac.c == LED_Casovac.pdf == LED_Casovac.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_Casovac.c == LED_Casovac.pdf == LED_Casovac.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;amp;amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;amp;amp;amp;gt;</style>
---
```
```c
/*
Popis:
Vybrané ledky budou blikat cca 2x za vteřinu
Ledky které mají takto blikat jsou vybrány konstantou "LED" a čas svícení je dán
děličkou časovače a šířkou jeho registru.
V tomto příkladu bude použit čítač/časovač "0" který má šířku registru 8 bitů
V tomto příkladu bude použit čítač/časovač "0" který má šířku registru 8 bitů
to znamená že počítá do 255.
Čítač bude mít zapnutou děličku hodinového signálu s dělitelem 1024.
Výsledná frekvence tedy bude 1 000 000/1024/255 = 3,8 Hz - při každém přetečení
Výsledná frekvence tedy bude 1 000 000/1024/255 = 3,8 Hz - při každém přetečení
budeme negovat stav ledek, takže se rozsvítí a zhasnou přibližně 2x za sekundu.
Přetečení čítače je signalizováno nultým bitem registru "TIFR"
......@@ -63,13 +51,13 @@ while (1) // Nekonečná smyčka (dokud 1 = pořád)
else //pokud není nultý bit "0" - časovač časovač už přetekl
{
PORTB = ~PORTB; //vyměň na portu "B" všechny nuly za jedničky a naopak
TIFR=TIFR | 0b00000001; //Nuluj příznak přetečení v registru TIFR
TIFR=TIFR | 0b00000001; //Nuluj příznak přetečení v registru TIFR
//(zapsáním "1" -poněkud nelogické, ale je to tak)
}
} //Konec cyklu "while (1)" - program skočí zpět na jeho začátek
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - Příklad - LEDka"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Ledka.c == LED_Ledka.pdf == LED_Ledka.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-06-22T17:36:40.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Ledka.c == LED_Ledka.pdf == LED_Ledka.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_Ledka.c == LED_Ledka.pdf == LED_Ledka.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;gt;</style>
---
```
```c
/*
Popis:
Vybrané ledky budou blikat s periodou cca jedné sekundy (0,5 s svítí a 0,5s
Vybrané ledky budou blikat s periodou cca jedné sekundy (0,5 s svítí a 0,5s
jsou zhaslé)
Ledky které mají takto blikat jsou vybrány konstantou "LED" a čas svícení je
Ledky které mají takto blikat jsou vybrány konstantou "LED" a čas svícení je
nastaven konstantou "CEKANI"
*/
#define F_CPU 1000000UL // 1 MHz -základní frekvence
//(definice je nutná pro funkce z knihovny "delay.h"
//->musí se vypočítat, kolik hodinových taktů má procesor
#define F_CPU 1000000UL // 1 MHz -základní frekvence
//(definice je nutná pro funkce z knihovny "delay.h"
//->musí se vypočítat, kolik hodinových taktů má procesor
//čekat, aby čekal požadovanou dobu)
#include <avr/io.h> //Vlož knihovnu vstupů a výstupů (PORT, DDR)
#include <util/delay.h> //vlož knihovnu čekacích funkcí (_delay_ms() )
#define CEKANI 500 //Nadefinuj konstantu "CEKANI" s hodnotou 500
#define CEKANI 500 //Nadefinuj konstantu "CEKANI" s hodnotou 500
//(500 milisekund)
#define LED 0b00111100; //Ledky, které mají blikat (prostřední 4)
......@@ -59,10 +47,10 @@ while (1) // Nekonečná smyčka (dokud 1 = pořád)
_delay_ms (CEKANI); //Čekej tolik milisekund, kolik je v konstantě CEKANI
PORTB = 0; //Zhasni všechny ledky
_delay_ms (CEKANI); //Opět čekej
_delay_ms (CEKANI); //Opět čekej
} //Konec cyklu "while (1)" - program skočí zpět na jeho začátek
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - Příklad - Tlačítko s přerušením"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Tlacitko-preruseni.c == LED_Tlacitko-preruseni.pdf == LED_Tlacitko-preruseni.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-06-22T17:46:58.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Tlacitko-preruseni.c == LED_Tlacitko-preruseni.pdf == LED_Tlacitko-preruseni.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_Tlacitko-preruseni.c == LED_Tlacitko-preruseni.pdf == LED_Tlacitko-preruseni.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;gt;</style>
---
```
```c
/*
Popis:
Při stisku tlačítka se rozsvítí vybrané ledky. Po uvolnění tohoto tlačítka ledky
opět zhasnou.
Při stisku tlačítka se rozsvítí vybrané ledky. Po uvolnění tohoto tlačítka ledky
opět zhasnou.
Ledky které se mají rozsvěcet jsou vybrány konstantou "LED".
Tlačítka jsou připojena k portu "D" K tlačítkům jsou připojeny "pull up" rezistory
na 5 V, takže pokud není stisknuté tlačítko, je na daném pinu 5 V (log. 1).
Tlačítka jsou připojena k portu "D" K tlačítkům jsou připojeny "pull up" rezistory
na 5 V, takže pokud není stisknuté tlačítko, je na daném pinu 5 V (log. 1).
Při stisku tlačítka se daný pin uzemní a je na něm tedy 0 V (log 0).
Tlačítko je připojeno k pinu PD2 (INT0).
......@@ -49,7 +37,7 @@ Při stisku tlačítka bude vyvoláno přerušení ve kterém dojde k rozsvícen
/********************Obsluha přerušení***********************/
ISR(INT0_vect) //obsluha vnějšího přerušení 0
{
PORTB = LED; //Rozsviť vybrané ledky (zhasnou se v hlavní smyčce)
PORTB = LED; //Rozsviť vybrané ledky (zhasnou se v hlavní smyčce)
//až přestane být voláno přerušení
}
......@@ -67,12 +55,12 @@ while (1) // Nekonečná smyčka (dokud 1 = pořád)
{
PORTB = 0; //zhasni všechny ledky (rozsvicují se v přerušení)
//Pokud není stisknuté tlačítko, program v hlavní smyčce neustále
//Pokud není stisknuté tlačítko, program v hlavní smyčce neustále
//zhasíná ledky.
} //Konec cyklu "while (1)" - program skočí zpět na jeho začátek
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
```
\ No newline at end of file
```
+++
title = "AVR - LED panel - Příklad - Tlačítko"
perex_e = "
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Tlacitko.c == LED_Tlacitko.pdf == LED_Tlacitko.htm
.
.
"
tags = ["Článek"]
tags = ["Technické články", "Programování", "C/C++", "Rozbité články"]
published = "2011-06-22T17:43:52.000Z"
author = "Michal, OK1WMR"
perex_e = "Kompatibilní zapojení: LED panel s ATmega8"
+++
Kompatibilní zapojení: LED panel s ATmega8
Ke stažení: LED_Tlacitko.c == LED_Tlacitko.pdf == LED_Tlacitko.htm
.
.
Kompatibilní zapojení: LED panel s ATmega8
* * *
Ke stažení: LED_Tlacitko.c == LED_Tlacitko.pdf == LED_Tlacitko.htm
<title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&amp;amp;lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&amp;amp;gt;</style>
---
```
```c
/*
Popis:
Při stisku tlačítka se rozsvítí vybrané ledky. Po uvolnění tohoto tlačítka ledky
opět zhasnou.
Při stisku tlačítka se rozsvítí vybrané ledky. Po uvolnění tohoto tlačítka ledky
opět zhasnou.
Ledky které se mají rozsvěcet jsou vybrány konstantou "LED".
Tlačítka jsou připojena k portu "D" K tlačítkům jsou připojeny "pull up" rezistory
na 5 V, takže pokud není stisknuté tlačítko, je na daném pinu 5 V (log. 1).
Tlačítka jsou připojena k portu "D" K tlačítkům jsou připojeny "pull up" rezistory
na 5 V, takže pokud není stisknuté tlačítko, je na daném pinu 5 V (log. 1).
Při stisku tlačítka se daný pin uzemní a je na něm tedy 0 V (log 0).
Tlačítka jsou připojena k pinům PD2 a PD3.
......@@ -54,16 +42,16 @@ Stavy na portu "D" jsou tedy následující:
int main (void) //hlavní funkce
{
unsigned char prom; //nadefinujeme si proměnnou typu unsigned char se jménem "prom"
//to znamená, že v paměti RAM vznikne místo (8 bitů) kam můžeme
//to znamená, že v paměti RAM vznikne místo (8 bitů) kam můžeme
//ukládat data
DDRB = 0xff; //(0xff = 0b11111111) -> Piny 0 - 7 portu "B" budou výstupní
DDRD = 0; //Port "D" bude vstupní (tlačítko je připojeno k portu "D")
while (1) // Nekonečná smyčka (dokud 1 = pořád)
{
prom=PIND; //do proměnné "prom" uložíme stav na portu "D"
prom=PIND; //do proměnné "prom" uložíme stav na portu "D"
//(tam kde je 5 V bude "1" a kde je 0 V bude "0")
prom=prom&0b00000100; //vymaskujeme pouze tlačítko "1"
prom=prom&0b00000100; //vymaskujeme pouze tlačítko "1"
//(pokud bylo na PD2 5 V bude výsledek 0b00000100
//jinak bude výsledek "0"
......@@ -78,7 +66,7 @@ while (1) // Nekonečná smyčka (dokud 1 = pořád)
} //Konec cyklu "while (1)" - program skočí zpět na jeho začátek
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
}//konec funkce main() - sem se program nikdy nedostane
//(závorka tu však musí být jinak by překladač nahlásil chybu)
```
\ No newline at end of file
```
content/articles/2011/avr-led-panel-s-atmega8/01.jpg

130 B

+++
title = "AVR - LED panel s ATmega8"
perex_e = "Tato konstrukce slouží k prvnímu seznámení s mikroprocesory od firmy Atmel. Jde o jednoduché zapojení, kde jsme na jeden port připojili LED diody. Na jednoduchých příkladech programů budeme postupně pronikat do tajů jednočipů. Více uvnitř článku.
.
tags = ["Technické články", "Konstrukce", "Konstrukce s mikroprocesorem", "Rozbité články"]
published = "2011-01-29T04:13:39.000Z"
author = "Michal, OK1WMR"
perex_e = "Tato konstrukce slouží k prvnímu seznámení s mikroprocesory od firmy Atmel. Jde o jednoduché zapojení, kde jsme na jeden port připojili LED diody. Na jednoduchých příkladech programů budeme postupně pronikat do tajů jednočipů. Více uvnitř článku.
.
"
tags = ["Článek"]
+++
Tato konstrukce slouží k prvnímu seznámení s mikroprocesory od firmy Atmel. Jde o jednoduché zapojení, kde jsme na jeden port připojili LED diody. Na jednoduchých příkladech programů budeme postupně pronikat do tajů jednočipů. Více uvnitř článku.
.
Tato konstrukce slouží k prvnímu seznámení s mikroprocesory od firmy Atmel. Jde o jednoduché zapojení, kde jsme na jeden port připojili LED diody. Na jednoduchých příkladech programů budeme postupně pronikat do tajů jednočipů. Více uvnitř článku.
.
Zde můžete najít články a výukové programy s popisem, které budeme zkoušet na tomto zapojení.
......@@ -17,19 +18,19 @@ Zde můžete najít články a výukové programy s popisem, které budeme zkou
| **PŘÍKLADY:
**[LED_Ledka.c](index.php/koutek-avr/90-koutek-uprocesoru/493-avr-led-panel-piklad-ledka)[](index.php/technika-a-bastelni/90-koutek-uprocesoru/472-2-prvni-program-rozsvitime-led)[LED_Tlacitko.c](index.php/koutek-avr/90-koutek-uprocesoru/494-avr-led-panel-piklad-tlaitko)[](index.php/technika-a-bastelni/90-koutek-uprocesoru/472-2-prvni-program-rozsvitime-led)[LED_Tlaciko-preruseni.c](index.php/koutek-avr/90-koutek-uprocesoru/495-avr-led-panel-piklad-tlaitko-s-peruenim)[](index.php/technika-a-bastelni/90-koutek-uprocesoru/472-2-prvni-program-rozsvitime-led)[LED_Casovac.c](index.php/koutek-avr/90-koutek-uprocesoru/496-avr-led-panel-piklad-asova)[](index.php/koutek-avr/90-koutek-uprocesoru/481-avr-led-panel-5-program)[LED_Casovac-preruseni.c](index.php/koutek-avr/90-koutek-uprocesoru/497-avr-led-panel-piklad-asova-s-peruenim)[](index.php/technika-a-bastelni/90-koutek-uprocesoru/472-2-prvni-program-rozsvitime-led) |
![](/upload/ok1wmr/clanky/avr/01_led_panel/01.jpg)Schéma:
[![schema](/upload/ok1wmr/clanky/avr/01_led_panel/sch_m.png)](../upload/ok1wmr/clanky/avr/01_led_panel/sch.png).
![](01.jpg)Schéma:
[![schema](sch_m.png)](../upload/ok1wmr/clanky/avr/01_led_panel/sch.png).
Plošný spoj:
![pcb](/upload/ok1wmr/clanky/avr/01_led_panel/pcb.png).
![pcb](pcb.png).
.
PDF verze: [schéma](../upload/ok1wmr/clanky/avr/01_led_panel/LED_panel_sch.pdf), [plošný spoj 1:1 (100x105mm)](../upload/ok1wmr/clanky/avr/01_led_panel/LED_panel_pcb.pdf), [osazovací plán](../upload/ok1wmr/clanky/avr/01_led_panel/LED_panel_osaz.pdf)Eagle 5.9: [SCH](../upload/ok1wmr/clanky/avr/01_led_panel/LED_panel.sch) a [BRD](../upload/ok1wmr/clanky/avr/01_led_panel/LED_panel.brd) + doporučená [Pájovo](http://paja-trb.unas.cz/elektronika/eagle.html) knihovna součástek [#PaJa_22.lbr](http://www.blueboard.cz/dcounter.php?hid=rm06m8vf666uus7u41ktn4b0xu9rrc&down=true&url=http://paja-trb.unas.cz/elektronika/eagle/paja_lbr_413.zip)Seznam použitých součástek:R1,R13,R14 - 10K - velikost 0207R3-R10 - 150R - velikost 0207R2,R11,R12 - 100R - velikost 0207
C1,C2,C3 - 100nF/50V keramika X7R- RM 5mmC4 - 22uF/6,3V elektrolyt - RM 5mmIC1 - ATmega8 - DIL28 - mikroprocesorLED0-LED7 - 5mm LED zelená
Krabička - konstrukční krabička s bočnicemi - SE100x105mm + 2x FEF100 + 4x vrut M3x25
.
* * *
---
.....[http://krouzek.radioklub.cz](http://krouzek.radioklub.cz/)
........
* * *
\ No newline at end of file
---
content/articles/2011/avr-led-panel-s-atmega8/pcb.png

130 B