katedra Informatiky, VŠB-TU Ostrava, FEI, 2014
Návody do cvičení pro předmět
Architektury počítačů a paralelních
systémů
Ing. Petr Olivka, email: [email protected]
Ing. David Seidl, Ph.D., email: [email protected]
1
Část I
Programování mikropočítače
2
Kapitola 1
Teoretický úvod
1.1
Úvod k mikropočítačům
V oblasti mikroprocesorové techniky je dnes ve světě několik hlavních výrobců. Stejně jako u procesorů pro osobní počítače jsou hlavními světovými
výrobci firmy AMD a Intel, tak v oblasti mikropočítačů se nejčastěji setkáme s mikropočítači PIC firmy Mikrochip a mikropočítači firmy Atmel.
Samozřejmě že je možné setkat i s mikropočítači jiných výrobců, jako například Freescale (bývalá morotola) nebo Zilog. Výrobky prvních dvou výrobců
jsou nejvíce využívané a s jejich mikropočítači je možné se setkat v mnoha
profesionálních i amatérských konstrukcí.
V první části cvičení z předmětu APPS budeme pracovat s mikropočítačem firmy Atmel ATmega32. Mikropočítač je součástka, která v sobě
sdružuje jednak samotnou výpočetní jednotku CPU, paměťi RAM, programovou a datovou FLASH paměť a také několik vstupně/výstupních bran
(pinů) a další periférie.
ATmega je celá řada mikropočítačů firmy Atmel s procesorovým jádrem
AVR, která je následníkem předešlé řady procesorů 8051. Mikropočítače
AVR byly již od začátku navrhovány tak, aby pro ně bylo možné jednoduše
vyvíjet programy v programovacím jazyku C, což je dnes dominantní způsob,
jakým se pro mikrokontroléry vyvíjí software.
1.2
Atmel AVR mikropočítač ATmega32
Nedílnou součástí této dokumentace jsou i technické manuály výrobce, a to
buď ve zkrácené verzi ATmega32-sum.pdf, nebo podrobný ATmega32.pdf.
Podrobné informace o tomto procesoru je pak možné najít především na
stránce výrobce http://www.atmel.com.
3
Pro práci ve cvičeních potřebujete znát jen základní informace. Procesor
samotný obsahuje řadu periférií, jako jsou časovače, čítače, řadiče různých
rozhraní, analogově digitální převodníky a pod. Pro práci ve cvičeních budete potřebovat ovládat vstupně výstupní porty procesoru. Použitý procesor
ATmega32 je vybaven čtyřmi vstupně výstupními porty. Jsou označeny PA,
PB, PC a PD.
Každá periférie kterou procesor využívá, tedy i vstupně výstupní porty, je
konfigurována pomocí registrů. Registr je místo v paměti procesoru. Každý
registr má svou pevně definovanou adresu v adresním prostoru, která je
v hlavičkových souborech vždy pro jednoduchost pojmenována konkrétním
jménem.
Každý ze čtyř portů procesoru se konfiguruje pomocí tří registrů. PORTx,
DDRx, PINx kde x označuje konkrétní port A,B,C nebo D.
∙ DDRx - při zápisu log.1 na konkrétní bit tohoto registru určíme, že
daný pin bude výstupní a opačně při log.0 bude vstupní.
∙ PORTx - Když je pin definován jako výstupní, určuje registr PORTx
logickou hodnotu výstupu na konkrétním pinu.
Když je některý pin definovaný jako vstupní a v registru PORTx je
pro tento pin definována log. 1, je tento pin udržován v klidovém stavu
na logické hodnotě 1. To je zařízeno připojením vnitřního tzv. pullup rezistoru. Při log.0 zapsané do registru PORTx je pull-up rezistor
deaktivován.
∙ PINx - Pokud je port nastaven jako vstupní, lze pomocí registru PINx
zjistit aktuální stav na příslušném pinu portu. Registr PINx je určen
pouze pro čtení.
Ve cvičeních se bude pracovat pouze s těmito registry.
1.3
Výukový vývojový AVR-KIT
Programy které se budou během cvičení vyvíjet, budou spouštěny na procesoru ATmega32, který je součástí výukového AVR-KITu. Výukový AVRKIT je deska plošných spojů, která je osazena samotným procesorem, dvěma
paticema ZIF, čtyřmi tlačítky které jsou připojeny na PORTD procesortu,
dvěma LED diodama taktéž připojenýma na PORTD procesoru a tlačítkem reset. Další součástky umístěné na desce plošných spojů jsou pomocné
obvody, určené ke komunikaci s PC a programování procesoru ATmega32.
Schéma AVR-KITu je na obrázku 1.1.
4
VCC
PA0
PA1
PA2
PA3
PA4
PA5
PA6
PA7
40
39
38
37
36
35
34
33
(T0/XCK)PB0
(T1)PB1
(AIN0/INT2)PB2
(AIN1/OC0)PB3
(SS)PB4
(MOSI)PB5
(MISO)PB6
(SCK)PB7
31
30
32
AGND
AVCC
AREF
(ADC0)PA0
(ADC1)PA1
(ADC2)PA2
(ADC3)PA3
(ADC4)PA4
(ADC5)PA5
(ADC6)PA6
(ADC7)PA7
9
RESET
GND
GND
1
2
PIND5
1
GND
VCC
R3
PD5
R2
PD4
R6
GND
VCC
PIND4
PIND3
2
PIND2
1
R5
R1
PD3
PD2
RESET
Sériová linka do PC
PD0
PD1
IC1
RESET
C0
C1
C2
C3
C4
C5
C6
C7
C8
C9
C10
C11
12
XTAL2
VCC
GND
13
XTAL1
VCC VCC
GND GND
PD0
PD1
PD2
PD3
PD4
PD5
PD6
PD7
11
10
GND
VCC
GND
ZIF-R
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
PC0
PC1
PC2
PC3
PC4
PC5
PC6
PC7
2
VCC
PD7
PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
B0
B1
B2
B3
B4
B5
B6
B7
B8
B9
B10
B11
1
2
3
4
5
6
7
8
R4
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
(SCL)PC0
(SDA)PC1
(TCK)PC2
(TMS)PC3
(TDO)PC4
(TDI)PC5
(TOSC1)PC6
(TOSC2)PC7
VCC
VCC VCC
GND GND
22
23
24
25
26
27
28
29
RESET
PA0
PA1
PA2
PA3
PA4
PA5
PA6
PA7
PC0
PC1
PC2
PC3
PC4
PC5
PC6
PC7
(RXD)PD0
(TXD)PD1
(INT0)PD2
(INT1)PD3
(OC1B)PD4
(OC1A)PD5
(ICP)PD6
(OC2)PD7
R7
GND
ZIF-L
14
15
16
17
18
19
20
21
PD6
VCC
AT-MEGA32
PD0
PD1
PD2
PD3
PD4
PD5
PD6
PD7
PIND6
1
GND
2
GND
PIND7
1
2
GND
.
Obrázek 1.1: Zapojení AVR-KITu
V každém ze cvičení budete mít k AVR-KITu připojen modul, kterým
se ke vstupně výstupním branám, připojí vždy jiné periférie. Bude se jednat
o LED diody, segmentový LED displej, teploměr a expandér pro sběrnici
I2 C, případně ještě další moduly. Konkrétní zapojení modulů ke vstupně
výstupním portům procesoru je uvedeno v popisu každé úlohy.
1.3.1
Programování AVR-KITu
Pro programování výukového AVR-Kitu je určen program avrkit.exe. Program je součástí archívu avrkit.zip (viz dále) a je možné spustit s následujícími parametry:
5
>avrkit.exe -h
Usage: AVRKIT [options] [file.hex]
-h
-d
-e
-l
-n
-s
-t
-v
-x
show this help
serial port device (def: ’COM1’)
erase AVR flash only
list available COM ports
no terminal mode after programming
show AVR flash only
terminal mode only
verify AVR flash memory only
show HEX file only
Without options this program upload HEX file to AVR flash.
Program očekává jako parametr HEX soubor, který obsahuje strojové
instrukce programu pro mikroprocesor.
AVT-KIT se v operačním systému jeví jako sériový port. Program avrkit.exe
zadaný bez parametru posílá data na COM1. Je-li AVR-KIT připojen jako
jiný sériový port, je možné ho definovat pomocí parametru -d. Dostupné
sériové porty lze vylistovat pomocí parametru -l.
Příklad nahrání testovacího programu demoleds.hex, za předpokladu že
AVR-KIT se v systému jeví jako COM3, bude vypadat následovně:
avrkit.exe -d COM3 demoleds.hex
1.3.2
Postup při programování mikropočítače AVR-KITu
Před započetím programování je nutné mikropočítač uvést do stavu kdy je
ochoten přijímat nový program. Toho se docílí stlačením tlačítka PIND4,
poté stlačením a uvolněním tlačítka RESET. Procesor se poté uvede do
módu kdy očekává data z PC (aktivuje se tzv. BOOTLoader) a přijatá data
zapisuje do programové paměti FLASH. Tento mód signalizuje mikropropočítač rozsvícenou LED diodou připojenou na PIND2.
Poté co se program nahraje je nutné opět procesor restartovat stlačením
a uvolněním tlačítka RESET. Procesor začne vykonávat nahraný program.
Po ukončení programování procesoru programem avrkit.exe zůstane
program aktivní a je připraven vypisovat data, které bude mikropočítač
zapisovat na sériový port pomocí funkce printf. Nechcete-li tuto funkci programu avrkit.exe využívat je ji možné vypnou parametrem -n.
Pro vyznavače nekomerčních operačních systémů je k dispozici i program
avrkit.lin pro OS Linux.
6
1.4
Vývojové prostředí Atmel Studio
Pro vývoj software je na webových stránkách firmy Atmel volně k dispozici
program Atmel Studio, který je určen pro OS Windows. S tímto plnohodnotným vývojovým prostředím je možné vyvíjet programy pro všechny procesory řady AVR. Program Atmel Studio využívá pro překlad volně šířený
překladač pro mikropočítače AVR avr-gcc (je to varianta volně šířeného překladače gcc). Tento překladač je k dispozici nejen pro OS Windows ale i pro
OS Linux.
Od Atmel Studia můžete očekávat všechny pokročilé vlastnosti na které
jste zvyklí z obdobných vývojových prostředí. Atmel Studio je založeno na
základech MS Visual Studio.
Pro práci ve cvičeních je pro vás připravena skupina projektů v archivu
avr-kit.zip, která se v Atmel Studiu označuje jako „Solution“.
1.4.1
Obsah avr-kit.zip
Po rozbalení archívu vznikne adresář s následujícím obsahem:
./avrkit.exe
./avr-kit.avrsln
./avrkit
./leds
./lcd
./i2c
./demo
->
->
->
->
->
->
->
Program pro programování AVR Kitu
Skupina projektů pro Atmel Studio
Adresář s knihovnou avrkit
Adresář s projektem pro LED diody
Adresář s projektem pro LCD displej
Adresář s projektem pro sběrnici i2c
Příklady pro jednotlivá cvičení
Obsah adresáře avrkit:
./avrkit.c
./avrkit.h
-> Zdrojový kód knihovny avrkit
-> Hlavičkový soubor knihovny avrkit
Obsah adresáře leds:
./leds.avrgccproj
./main-leds.c
./Debug
./Release
->
->
->
->
Projekt Atmel Studia
Zdrojový kód programu i2c
Adresář pro výstupní soubory
Adresář pro výstupní soubory
7
Obsah adresáře lcd:
./lcd.avrgccproj
./main-lcd.c
./lcd-lib.c
./lcd-lib.h
./Debug
./Release
->
->
->
->
->
->
Projekt Atmel Studia
Zdrojový kód programu pro LCD
Zdrojový kód funkcí pro LCD displej
Hlavičkový soubor funkcí pro LCD
Adresář pro výstupní soubory
Adresář pro výstupní soubory
->
->
->
->
->
->
->
->
Projekt Atmel Studia
Zdrojový kód programu i2c
Zdrojový kód funkcí pro sběrnici I2C
Hlavičkový soubor funkcí pro I2C
Funkce inicializace radiomodulu
Prototyp funkce inicializace
Adresář pro výstupní soubory
Adresář pro výstupní soubory
Obsah adresáře i2c:
./i2c.avrgccproj
./main-i2c.c
./i2c-lib.c
./i2c-lib.h
./si4735-lib.c
./si4735-lib.h
./Debug
./Release
Obsah adresáře demo:
./demoleds.hex
./demo8x8.hex
./demoi2c.hex
./demolcd.hex
1.4.2
->
->
->
->
Demo
Demo
Demo
Demo
program
program
program
program
pro
pro
pro
pro
LEDky
led displej
sběrnici I2C
LCD displej
Práce v Atmel Studiu
Po rozbalení souboru avr-kit.zip je ve vytvořené složce soubor avr-kit.avrsln,
což je skupina projektů určená pro první část cvičení. Je možné ji otevřít
pomocí menu File > Open > Projects/Solution, nebo kliknutím na ikonu.
Po otevření skupiny projektů se v okně „Solution Explorer“ objeví složky
(projekty) pro jednotlivá cvičení. Bude se zde taky vyskytovat soubor avrkit.c, což je soubor s funkcemi knihovny avrkit.h. Tento soubor prosím nijak
neupravujte.
Projekt lze přeložit pomocí Build > Build Solution, případně klávesou
F7. Poté se ve složce Debug nebo Release daného projektu objeví HEX
soubor, který je určený pro mikropočítač. To, zda jste v režimu Debug nebo
Release se dá ovlivnit pomocí záložky v hlavní liště Atmel Studia.
8
1.5
Překladač AVR GCC - stručný přehled
Překladač AVR GCC je volně šířený překladač jazyka C. Tento překladač
využívá volně šířené knihovny jazyka C AVR Libc. Jedná se o standardní
překladač jazyka C a při psaní programů můžete využívat všechny základní
programátorské konstrukce jazyka C. Tento překladač je standardně používaný překladač ve volně šířeném vývojovém prostředí Atmel Studio.
1.5.1
Datové typy
V programech můžete používat následující datové typy:
∙ signed char -128 ÷ 127
∙ signed short, signed int -32768 ÷ 32767
∙ signed long -2147483648 ÷ 2147483647
∙ unsigned char 0 ÷ 255
∙ unsigned short, unsigned int 0 ÷ 65535
∙ unsigned long 0 ÷ 4294967295
Požadujeme-li typ bezznaménkový, musíme uvádět klíčové slovo unsigned.
Pro znaménkové proměnné je slovo signed nepovinné.
1.5.2
Zápis čísel
Je možné použít následující zápisy čísel:
Dekadický
int i
= 10578;
char ch = -10;
float f = 13.54;
Hexadecimální
int i
= 0x12B7;
char ch = 0xF1;
Binární
int i
= 0b1101001010010110;
char ch = 0b10001101;
9
Oktalový
int i
= 0737;
char ch = 015;
Je potřeba si uvědomit, že 10 = 0xA = 0b1010 = 012. Jedná se o zápis
jednoho čísla v různých číselných soustavách.
1.5.3
Aritmetické, logické a bitové operátory jazyka C
Aritmetické +, -, *, /, %
První čtyři operátory viz základní škola. Operátor modulo % vrací zbytek
po celočíselném dělení. Tedy 11 % 2 = 1, 13 % 5 = 3, 31 % 31 = 0.
Zkrácený zápis aritmetických operátorů v jazyce C:
x++,
x--,
x +=
x -=
x *=
x /=
x %=
++x
--x
y
y
y
y
y
x
x
x
x
x
x
x
=
=
=
=
=
=
=
x
x
x
x
x
x
x
+
+
*
/
%
1
1
y
y
y
y
y
Logické &&, ||, !
Logický součin
lež && lež
lež && pravda
pravda && lež
pravda && pravda
=>
=>
=>
=>
Logický součet
lež || lež
lež || pravda
pravda || lež
pravda || pravda
lež
lež
lež
pravda
Logická negace
!lež
=> pravda
!pravda => lež
Kde pravda je číslo nenulové a lež je číslo nula.
10
=>
=>
=>
=>
lež
pravda
pravda
pravda
Bitové &, |, ^, ~, <<, >>
Bitový součin
0 & 0 => 0
0 & 1 => 0
1 & 0 => 0
1 & 1 => 1
Bitový součet
0 | 0 => 0
0 | 1 => 1
1 | 0 => 1
1 | 1 => 1
Bitový exclusive or
0 ^ 0 => 0
0 ^ 1 => 1
1 ^ 0 => 1
1 ^ 1 => 0
Bitová negace
~1 => 0
~0 => 1
Bitový posun
0b01 << 1 => 0b10
0b10 >> 1 => 0b01
Příklady:
5 & 3 = 1 protože 0b101 &
5 | 3 = 7 protože 0b101 |
5 ^ 3 = 6 protože 0b101 ^
~5 = 250 protože ~0b101 =
je 5 osmi bitové
0b011 = 0b001
0b011 = 0b111
0b011 = 0b110
0b11111010, pokud
bezznaménkové číslo
5 << 3 = 40 protože 0b101 << 3 = 0b101000
5 >> 3 = 0 protože 0b101 >> 3 = 0b000000
Zkrácený zápis logických operátorů v jazyce C:
x
x
x
x
x
>>= y
<<= y
&= y
|= y
^= y
x
x
x
x
x
=
=
=
=
=
x
x
x
x
x
>> y
<< y
& y
| y
^ y
11
Často dochází k záměně logických a bitových operátorů log. součtu a
součinu. Příklad časté záměny:
char x = 5;
char y = 2;
if(x && y) {...} //PRAVDA
if(x & y)
1.5.4
{...} //LEŽ
Knihovna avr/io.h
V programech se vkládá jako hlavičkový soubor #include <avr/io.h>.
Tento hlavičkový soubor umožňuje použít všechny registry procesoru jako
proměnné. Při překladu projektu se překladači uvede procesor pro který je
program překládán a překladač dál definuje, který konkrétní hlavičkový soubor pro zvolený procesor se má do projektu vložit. Překladači předává tuto
volbu Atmel Studio dle nastavení v projektu.
Příklad programu, který nastaví port A jako výstupní a všechny piny
nastaví na log.1:
#include <avr/io.h>
int main() {
DDRA = 0xff;
PORTA = 0xff;
}
1.5.5
Knihovna avrkit.h
Tato knihovna je součástí vývojového kitu AVR-KIT. Obsahuje dvě funkce
potřebné pro zastavení běhu programu na požadovaný čas. A dále funkci
pro inicializaci AVR-KITu. Volání této funkce je nutné na začátku každého
programu! Provede inicializaci zařízení a přesměruje textové výstupy na sériovou linku. Prototypy funkcí vypadají následovně:
void avrkit_init( void );
void delay_ms( int ms );
void delay_01ms( int ms );
uchar read_butt( void );
//
//
//
//
12
povinná inicializace AVR kitu
zpoždění v milisekundách
zpoždění v desetinách ms
cteni stavu tlacitek, bity <4-7>
Ukázka použití je uvedena v příkladu programu následující podkapitoly.
1.5.6
Knihovna stdio.h
V programech se vkládá jako hlavičkový soubor #include <stdio.h>. Tento
hlavičkový soubor umožňuje používat obvyklé funkce pro výstup (použitý
vývojový KIT směřuje výstup těchto funkcí na sériovou linku, viz další kapitola).
Příklad programu, který nastaví horní 4 piny portu D jako vstupní a
bude pravidelně každou sekundu vypisovat stav připojených tlačítek AVRKITu.
#include "avrkit.h"
#include <avr/io.h>
#include <stdio.h>
int main() {
avrkit_init();
DDRD = DDRD & 0x0F;
while (1) {
printf( "%03d %02x\n", read_butt(), read_butt() );
delay_ms( 1000 );
}
}
13
Kapitola 2
Návody do cvičení
2.1
2.1.1
LED diody
Zapojení LED na port mikropočítače
Na port mikropočítače je možno zapojit přímo LED diody. Dle schématu na
obrázku 2.1 je vidět, že LED diody se aktivují vždy v úrovní logické 1.
Aby proud protékající jednotlivými diodami nepřekročil přípustnou mez,
LED0
PINC0
PINC1
PINC2
PINC3
PINC4
PINC5
PINC6
PINC7
LED7
Obrázek 2.1: Zapojení LED na port mikropočítače
14
1
0
1
0
1
0
1
0
1
0
0%
30%
50%
90%
100%
T
0
2T
3T
t
Obrázek 2.2: Časový průběh signálů s různou střídou
je každá dioda zapojena v sérii s ochranným odporem. Jednotlivé vývody
PC0-PC7 odpovídají i v uvedeném pořadí osmi datovým bitům datového
portu C mikropočítače.
2.1.2
Řízení jasu
Popis
Úkolem je řízení jasu diod změnou střídy (duty cycle). Častěji je ale používán pojem pulsně šířková modulace (PWM - pulse wide modulation). Jde
o měnící se poměr délky signálu a mezery při konstantní časové periodě.
Vyjadřujeme jej v procentech. Na obrázku 2.2 je příklad několika takových
signálů s odlišnou střídou.
Příklady úkolů ve cvičení
∙ Rozsvítit každou diodu zadaným jasem, jednotlivé hodnoty stačí zadat
do pole.
∙ Diody postupně rozsvítit a postupně zhasnout. Postupně se rozumí
nejprve pomalu rozsvítit první, pak postupně druhou a první zůstává
svítit, atd. A pak postupně pozhasínat.
∙ 4 a 4 diody se rozsvěcují a zhasínají současně. Buď prokládaně, nebo
po čtveřicích.
15
Postup řešení
∙ Rozsvítit vybranou LED diodu.
∙ Rozblikat vybranou LED diodu se střídou 50%.
∙ Najít periodu  = 1/ , tak aby nebylo blikání viditelné.
∙ Řídit jas jedné LED.
∙ Řídit jas dvou LED současně. Nebo zajistit postupné rozsvícení. Časovou periodu rozdělit po jedné  a hledat místa, kdy se mění stavy
LED diod.
∙ Dokončit zadání.
2.1.3
Skládání barev - RGB LED
Popis
V počítačové technice se jako jedna metoda pro vytvoření libovolné barvy
používá tzv. aditivní způsob míchání barev. Máme 3 základní barvy červenou, zelenou a modrou (RGB - red, green, blue). Pomocí těchto 3 základních
barevných složek můžeme vytvořit libovolnou barvu z celého viditelného
spektra. Pro míchání barev je nutno použít princip popsaný v předchozí kapitole o řízení jasu. Ve výsledné barvě je potřebné zastoupení každé základní
barevné složky přímo úměrné zvolené střídě.
PINB0
PINB1
PINB2
PINB4
PINB5
PINB6
B
G
RGB L
R
B
G
RGB H
R
Obrázek 2.3: Zapojení RGB LED
16
Zapojení RGB LED je na obrázku 2.3. Jednotlivé barevné složky jsou
připojeny na výstupy portu B. Dioda označená jako RBG L je připojena na
dolní 4 bity a druhá, označená RGB H na horní bity.
Příklady úkolů ve cvičení
∙ Rozsvítit jednotlivé základní barvy daným jasem.
∙ Plynulý přechod mezi dvěma základními barvami.
∙ Rozsvícení RGB LED barvou zadanou podle HTML standardu #RRGGBB
∙ Plynulý přechod mezi dvěma barvami podle HTML standardu.
Postup řešení
Postup programování stejný jako při řízení jasu.
2.1.4
Řízení frekvence blikání
Popis
Úkolem je blikání diod s určitou frekvencí. Potřebná časová perioda je:  =
1/ . Pozor! Tato perioda se musí rozdělit se střídou 50% na „svití/nesvítí“.
Bude-li zvolená perioda použita pro svícení i zhasnutí, výsledná frekvence
bude poloviční! Je to obvyklá chyba při programování!
Příklady úkolů ve cvičení
Podobné jako při řízení jasu, jen místo jasu se řídí frekvence.
Postup řešení
Hledat společný násobek všech potřebných frekvencí nelze.
Jsou tedy dvě možnosti: můžeme mít tolik čítačů, jako je LED diod a po
každé  se každý čítač inkrementuje a kontroluje na přetečení.
Nebo můžeme mít jeden „nekonečný“ čítač inkrementovaný opět po
každé  a pak celočíselným dělením tohoto čítače periodou pro každou
LED dostaneme zbytky po dělení. Tento zbytek (modulo) bude pro každou LED nula nebo různý od nuly. Při nule nastane změna stavu příslušné
LED (ideální je operace XOR, ale někdo raději provede OR/AND s vhodnou
bitovou maskou).
17
První řešení umožňuje řídit i fázi, druhé je jednodušší. Způsobí ale drobnou asynchronnost při přetečení čítače, která je ale očima nepozorovatelná.
Vybranou metodu řešení pak můžeme aplikovat v následujících krocích:
∙ Rozblikat jednu LED se zadanou frekvencí.
∙ Najít frekvenci, při která není blikání vidět.
∙ Rozblikat dvě diody, každou jinou frekvencí (ne celistvý násobek).
∙ Dokončit zadání.
18
2.2
Multiplexní řízení vícemístného displeje
Vícemístné LED a LCD displeje patří k základním zobrazovacím prvkům
elektronických zařízení. Pro účely cvičení byly vybrány sedmiprvkové LED
displeje. Zapojeno je osm těchto displejů (dále segmentů) vedle sebe.
Zapojení osmi segmentů současně je zobrazeno v elektrickém schématu
na obrázku 2.6. Jde o zapojení 64 LED (ve dvourozměrné matici 8 × 8).
Zjednodušeně můžeme zapojení znázornit obrázkem 2.4 (podrobněji pak dále
na obrázku 2.6). Podle obrázku 2.4 vybírá port B jeden s osmi segmentů.
Port C pak vybírá LED v aktivovaném segmentu. Používáme kladnou řídící
logiku a výběr segmentu i LED se provádí logickou úrovní 1 na příslušných
vybraných pinech portů B a C.
PORT C
LED A-G
Segment 7
Segment 0
PORT B
Obrázek 2.4: Zjednodušené ovládání osmisegmentového displeje
Rozložení a označení LED každého segmentu je na obrázku 2.5, včetně
osmé LED označené jako DP - desetinná tečka (decimal point).
A
F
B
G
C
E
DP
D
Obrázek 2.5: Rozmístění LED jednoho segmentového displeje
Pro lepší pochopení principu činnosti uvádíme i přesnější elektrické schéma
zapojení segmentů displeje na obrázku 2.6. Ze schématu je patrno několik
důležitých technických informací:
19
SEGMENT 7
PINB7
PINC7
DP0
PINC6
G0
PINC5
F0
PINC4
E0
PINC3
D0
PINC2
C0
PINC1
B0
A0
DP1
G1
SEGMENT 1
PINB1
GND
F1
E1
D1
C1
B1
A1
DP7
G7
F7
E7
D7
C7
B7
A7
PINC0
.
SEGMENT 0
PINB0
GND
GND
Obrázek 2.6: Schéma zapojení osmi segmentů
1. Jednotlivé segmenty displeje A-G jsou připojeny na port C a jeho piny
PC0-PC6.
2. Všechny LED jsou zapojeny se společnou katodou. Každá LED se tedy
aktivuje pomocí logické úrovně 1 portu C.
3. Aktivní společná katoda každého segmentu 0-7 se vybírá tranzistorem
NPN, jehož báze se aktivuje log. úrovní 1 pinu portu B v pořadí PB0PB7.
4. Není možné ovládat každou LED samostatně. Lze aktivovat jen LED
pro vybraný segment. Chceme-li zobrazit informaci na více segmentech současně, musí se informace na jednotlivých segmentech střídat.
Hovoříme tedy o tzv. časovém multiplexu.
Příklady úkolů ve cvičení
∙ Zobrazte aktuální datum v různých tvarech a přepínat mezi nimi tlačítkem.
∙ Zobrazte aktuální čas ve tvaru HH:MM:SS a blikajícími oddělovači.
∙ Zobrazte volitelný text do osmi znaků.
∙ Zobrazte „bežící“ text libovolné délky.
20
.
Postup řešení
∙ Nadefinujte si kombinaci LED tak, aby představovaly znaky nebo číslice.
∙ Ověřte na jednom vybraném segmentu, zda se znaky zobrazují správně.
∙ Zobrazte dva různé znaky na dvou segmentech současně. Je třeba využít znalost z předchozího cvičení, kdy lidské oko přestává vnímat
blikání. Zobrazovací časovou periodu je pak potřeba rozdělit mezi dva
segmenty.
∙ Zobrazte rozdílné znaky na všech osmi segmentech.
∙ Dokončete zadaný úkol.
21
2.3
LCD textový displej
Textové LCD displeje jsou v dnešní době součástí mnoha řídících, monitorovacích a diagnostických zařízení. Tyto LCD displeje se vyrábí jako hotové
moduly v mnoha provedeních. Liší se počtem znaků na řádek a počtem
řádků. Odlišné je také barevné provedení displejů a způsob podsvětlení.
Pro ovládání těchto LCD displejů se vyrábí několik řadičů. Není se však
třeba v praxi obávat roztříštěnosti programového ovládání. Výrobci těchto
řadičů mezi sebou dodržují nepsaný standard pro jejich řízení. Nepatrné
odchylky lze nalézt pouze při inicializaci LCD modulů. Pokud se tedy programátor seznámí s řízením jednoho LCD modulu, lze získané zkušenosti
dále aplikovat i na LCD moduly s odlišným rozlišením, nebo moduly jiných
výrobců.
Pro cvičení v předmětu APPS byl vybrán LCD modul BC1602A se 16
znaky na řádek a dvěma řádky, podsvětlený pomocí žlutozelené LED. Výrobcem modulu je firma Bolymin a využívá řadič ST7066U firmy Sitronix.
Fotografie celého modulu i s připojením na AVR-KIT je na obrázku 2.7.
Nedílnou součástí tohoto textu jsou také datové listy výrobce LCD modulu - BC1602A.pdf, popisující podrobně celý modul, jeho konstrukci i
ovládání. Pro práci ve cvičení budou potřeba zejména informace na straně
27 a 29.
Obrázek 2.7: LCD modul
22
2.3.1
Zapojení LCD modulu a popis komunikace
Zapojení LCD modulu je uvedeno na obrázku 2.8. Na schématu je vidět, že
pro připojení LCD modulu slouží 16 pinů. Na obrázku 2.7 jsou tyto piny
vidět nad horním okrajem černého rámečku.
Pro přenos dat slouží 8 datových pinů D0 až D7. Tyto piny jsou připojeny
přímo na port B mikropočítače Atmel.
Pro řízení komunikace slouží piny R/W, RS a E. Pin R/W určuje směr
komunikace. Pinem RS se rozlišuje, zda jsou LCD modulu předávána data,
nebo příkazy. Třetí řídící pin E slouží pro synchronizaci přenosu dat.
Podrobně je synchronní komunikace mezi procesorem a LCD modulem
popsána v datových listech. Pro cvičení však není tuto komunikaci podrobně
studovat. V přiložených zdrojových kódech jsou již připraveny pro komunikaci s LCD modulem 3 funkce. Budou popsány dále v textu.
Kromě datových a řídících pinů je k modulu přivedeno napájení přes
piny VDD a VSS. Kontrast LCD se ovládá pomocí pinu VO. Podsvětlení je
zapojeno zcela odděleně od napájení řídícího obvodu přes piny BLK a BLA.
BACKLIGHT
C
LCD 2x16
BLK
BLA
D7
D6
D5
D4
D3
D2
D1
D0
E
RW
RS
VO
VDD
VSS
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
L
PIND-7
RB
T1
P
GND
+5V
PINB-7
PINB-6
PINB-5
PINB-4
PINB-3
PINB-2
PINB-1
PINB-0
PINC-0
PINC-1
PINC-2
RKRK+
CONTRAST
C
+5V
L
P
RG
R0 4k
R1 2k
GND +5V
GND
R2 1k
GND
PINA-0
PINA-1
PINA-2
Obrázek 2.8: Schéma zapojení LCD modulu
Ovládání podsvětlení a kontrastu
Ze schématu LCD modulu 2.8 je vidět, že u zapojení podsvětlení i u pinu pro
ovládání kontrastu, jsou zapojeny dvoupolohové přepínače. Tyto přepínače
jsou na obrázku 2.7 označeny na horním a spodním okraji LCD modulu
červenými kroužky.
23
Pokud je horní přepínač v poloze vlevo u nápisu BACKLIGHT, je podsvětlení trvale zapnuto. Chceme-li podsvětlení ovládat programově, je nutno
tento přepínač přepnout směrem k nápisu PWM. Podsvětlení pak lze ovládat nejvyšším bitem portu D. Zápisem log. 1 na PIND7 se podsvětlení zapne
a zápisem log. 0 vypne. Pomocí PWM tak můžeme ovládat intenzitu podsvětlení.
Pro ovládání kontrastu jsou k dispozici také dvě možnosti. Pokud nevyžadujeme programové ovládání, stačí přepnout spodní přepínač do polohy
CONTRAST a úroveň kontrastu bude dle pevně přednastavené hodnoty. Při
přepnutí dolního přepínače do polohy D/A je možno kontrast ovládat programově. Jak je vidět ve schématu 2.8, úroveň kontrastu je možno ovládat
pomocí jednoduchého D/A převodníku, realizovaného třemi rezistory R0 až
R2. Tyto rezistory jsou připojeny na 3 piny portu A. Pomocí těchto 3 pinů
tak lze nastavit 8 různých úrovní kontrastu.
2.3.2
Programové ovládání LCD modulu
Pro ovládání LCD displeje jsou připraveny 3 funkce.
void lcd_init( void ) - inicializace LCD modulu.
void lcd_send_cmd( char cmd ) - odeslání příkazu do LCD.
void lcd_send_data( char ch ) - odeslání jednoho znaku do LCD.
První funkci pro inicializaci lcd_init volá programátor vždy na začátku
programu a během činnosti programu se již opakovaně volat nesmí.
Další funkce lcd_send_cmd slouží k řízení LCD modulu. Seznam všech
příkazů je uveden v technické dokumentaci na straně 29. Příkazů je celkem 8
a slouží především pro smazání displeje, nastavení chování kurzoru (velikost,
zobrazení, posun), vypnutí/zapnutí displeje a definování vlastních znaků.
Třetí funkcí lcd_send_data lze odeslat do LCD modulu osmibitovou
ASCII hodnotu znaku, který se má zobrazit. Znak se zobrazí na aktuální
pozici kurzoru. Chování kurzoru je přednastaveno tak, že se po zobrazení
znaku kurzor automaticky posune na následující pozici směrem doprava.
Příklad použití všech funkcí je možno uvést v následující ukázce programu:
24
#include "avrkit.h"
#include "lcd-lib.h"
int main()
{
avrkit_init();
lcd_init();
while ( 1 )
{
lcd_send_cmd( 0x01 );
delay_ms( 1000 );
lcd_send_data( ’5’ );
lcd_send_data( ’$’ );
delay_ms( 1000 );
}
}
// smazani LCD displeje
// pauza 1 sekundu
// zobrazeni znaku
// pauza 1 sekundu
Uvedená ukázka kódu provede v nekonečné smyčce vždy na jejím počátku smazání displeje. Po krátké pauze zobrazí dvojici znaků "5$". Opět
následuje krátké zpoždění a celý postup se opakuje od začátku.
Adresy znaků, pozice kurzoru
V předchozí podkapitole bylo uvedeno, že znaky se vypisují vždy na aktuální
pozici kurzoru. Pro výpis znaků na displej je proto důležité správně nastavit
pozici kurzoru před odesláním znaku na displej.
Pro nastavení pozice kurzoru je možno v dokumentaci najít příkaz 0x80.
K této hodnotě je nutno přidat ještě správnou adresu pozice, na kterou je
potřeba kurzor nastavit. Pořadová čísla (adresy) znaků v řádku jsou uspořádány vzestupně za sebou. Druhý řádek však nenavazuje přímo na řádek
předchozí. Přehledně jsou zobrazeny adresy pozic jednotlivých znaků na obrázku 2.9.
0x00
0x01
0x02
0x03
0x04
0x05
0x06
0x07
0x08
0x09
0x0A 0x0B 0x0C 0x0D 0x0E
0x0F
0x40
0x41
0x42
0x43
0x44
0x45
0x46
0x47
0x48
0x49
0x4A 0x4B 0x4C 0x4D 0x4E
0x4F
Obrázek 2.9: Adresy jednotlivých znaků LCD modulu
Požadujeme-li například nastavení kurzoru na 10. pozici 2. řádku, musíme před výpisem znaku použít příkaz:
lcd_send_cmd( 0x80 | 0x49 );
25
Definice vlastních znaků
LCD modul obsahuje ve své vnitřní paměti font 5×8 (šířka×výška), podle
kterého se zobrazují na displeji jednotlivé znaky. Tento font je uložen v ROM
a nelze jej tedy přepisovat. V dokumentaci je tvar všech znaků vyobrazen
na straně 28.
Řadič displeje však umožňuje uživateli nadefinovat několik vlastních znaků.
V dokumentaci LCD modulu je formát vlastního fontu a jeho uložení v RAM
paměti řadiče popsán na straně 27.
Je možno definovat 8 znaků, jejichž ASCII hodnoty jsou v rozsahu ⟨0, 7⟩.
Pro každý znak je potřeba definovat bitový vzor znaku pomocí 8 bajtů. Pro
8 znaků je tedy celková velikost RAM 64 bajtů. Počáteční adresa fontu pro
každý znak je proto vždy celistvým násobkem čísla 8.
Jak může vypadat definice fontu jednoho znaku, je vidět na obrázku
2.10. Ukázka představuje definice symbolu . Velikost fontu je 5×8, proto
je v každém bajtu trojice horních bitů ignorována.
bit 7
6
5
4
3
2
1
0
0b00000000 / 0x00
0b00000000 / 0x00
0b00011111 / 0x1F
0b00001010 / 0x0A
0b00001010 / 0x0A
0b00001010 / 0x0A
0b00001010 / 0x0A
0b00000000 / 0x00
Obrázek 2.10: Bitová definice fontu jednoho znaku
Jak může nyní programátor přenést svá připravená data představující
font pro jeden znak do LCD řadiče?
Mezi příkazy v dokumentaci LCD modulu na straně 29 je možno najít
příkaz 0x40. Právě tento příkaz nastaví adresu RAM, kam se mají zapisovat
data definující tvar znaku. Hodnotu 0x40 je tedy potřeba rozšířit o adresu
znaku, který chceme předefinovat. Chceme-li například předefinovat znak ,
kde ASCII hodnota  ∈ ⟨0, 7⟩, může kód programu vypadat následovně.
26
....
char z = vybrany_znak_0_az_7;
char font_z[ 8 ] = { ... };
lcd_send_cmd( 0x40 | ( z * 8 ) ); // prikaz pro zapis fontu
for ( int f = 0; f < 8; f++ )
lcd_send_data( font_z[ f ] ); // zapis jednotivych bajtu fontu
lcd_send_cmd( 0x80 | pozice );
// prepnuti zpet na zapis znaku
lcd_send_data( z );
// vypis noveho znaku
....
Po zápisu fontu je důležité přepnout řízení displeje zpět do režimu zápisu znaků. To bylo v předchozí ukázce provedeno přesunem kurzoru na
požadovanou pozici.
Příklady úkolů pro cvičení
∙ Napiště funkci, která vypíše řetězec znaků na požadovanou pozici a
řádek.
∙ Pomalu se posouvající dlouhý text.
∙ Zobrazte aktuální čas ve formátu HH:MM:SS s blikajícími ’:’.
∙ Stopky v obou řádcích, spuštění současně, zastavení každé zvlášť.
∙ Minutovník. Nastavit výchozí čas, spustit, po dosažení času 0 rozblikat
podsvětlení.
∙ Tlačítky regulujte kontrast displeje.
∙ Tlačítky regulujte intenzitu podsvětlení. Využijte PWM integrované v
procesoru.
Úkoly se také mohou dle zadání vyučujících měnit a kombinovat.
27
2.4
Sběrnice I2 C
2.4.1
Popis sběrnice
Sběrnice I2 C byla navržena firmou Philips Semiconductors pro komunikaci
jednočipových mikropočítačů s dalšími číslicovými obvody.
I2 C je obousměrná dvouvodičová sběrnice. Někdy bývá ale nesprávně
označována jako sériová linka. Zkratka I2 C označuje Inter Integrated Circuit
Bus. Český překlad by mohl být meziobvodová sběrnice.
Základní charakteristika
Sběrnice se skládá ze dvou linek. SDA slouží pro obousměrný přenos dat
a SCL linka slouží jako hodinový signál. Obě linky pracují v napěťových
logických úrovních shodně s technologií TTL.
V klidové stavu jsou obě linky v úrovni log. 1. Tento stav je udržovány dvěma zdvihacími (pull-up) rezistory. Výstupy číslicových obvodů jsou
řešeny jako výstup typu otevřený kolektor. Tím je zaručena obousměrnost
linky.
Základní uspořádání systému můžeme vidět na obrázku 2.11. Na sběrnici
může být připojeno více zařízení. Obvykle jedno zařízení označované jako
Master řídí vysílání a příjem zpráv.
Další zařízení, označovaná jako Slave, po výzvě nadřízeným obvodem
data přebírají (receive), nebo odesílají (transmit). Na sběrnici smí být i
více zařízení typy Master, ale taková zapojení již nepředstavují jednoduché
systémy vhodné pro výuku.
Ucc
SCL
SDA
Master
Receive
Transmit
Slave
Receive
Slave
Receive
Transmit
Slave
Transmit
Obrázek 2.11: Uspořádání typického systému se sběrnicí I2 C
28
SCL
SCL
1
SDA
0
SDA
START
a)
STOP
b)
Obrázek 2.12: Průběhy signálů na sběrnici I2 C
Přenos bitů
Přenos bitů probíhá na sběrnici synchronně. Synchronizace se provádí hodinovým signálem SCL. Jeden bit je přenesen vždy v jednom hodinovém
cyklu. Jak vypadá přenos hodnoty 1 a 0 můžeme vidět na obrázku 2.12a. Z
obrázku je patrné, že datové signály se mění vždy jen v době, kdy je signál
SCL v úrovni log. 0. Pokud dochází ke změně signálu SDA v době, kdy ke
úroveň signálu SCL v log. 1, jde o signály řídící.
Řídící signály START a STOP
Vzhledem k počtu vodičů sběrnice I2 C, můžeme definovat jen dva řídící
signály. Těmi jsou signály START (S) a STOP (P). Jak vypadá průběh
těchto signálů můžeme vidět na obrázku 2.12b. Slovní popis je následující:
z klidového stavu, kdy signál SDA i SCL jsou v log. 1 musíme přejít do
komunikačního režimu signálem START. Tím rozumíme přechod signálu
SDA z log. 1 na log. 0 při neměnné hodnotě signálu SCL v log. 1. Pak
teprve musí následovat i přechod signálu SCL z log. 1 na log. 0.
Chceme-li ukončit komunikaci, musíme uvést obě linky SDA i SCL do
klidového stavu. Učiníme tak signálem STOP, který představuje nejprve
nastavení SCL na log. 1 a poté nastavení i SDA na log. 1.
Komunikace po bajtech
Při přenosu dat mezi signály START a STOP není množství přenesených
dat nijak omezeno. Data se ovšem nepřenáší po jednotlivých bitech, ale po
celých bajtech. Průběh celého přenosu je vidět na obrázku 2.13. Z průběhu
signálů a jejich popisu je patrné, že významově nejvyšší bit se přenáší jako
první.
29
Master
SCL
START
Master
SDA
STOP
1
2
3
4
5
6
7
8
D7
D6
D5
D4
D3
D2
D1
D0
Slave
SDA
9
ACK
Obrázek 2.13: Odeslání jednoho bajtu i s potvrzením na sběrnici I2 C
Povrzování
Na obrázku 2.13 je zobrazen nejen přenos jednoho bajtu, ale i další důležitá
součást přenosu informace. Tou je potvrzování. Každý obvod musí příjem
bajtu povrdit bitem ACK, což je log. 0 linky SDA v následujícím hodinovém
cyklu po odvysílání bajtu. Potvrzení může být i NACK, tedy negovaný ACK,
což je hodnota log. 1 linky SDA (master tak naznačuje, že ukončuje přenos
dat).
Všimněte si na obrázku 2.13 chování vysílače (Master) v devátém hodinovém cyklu, kdy se očekává signál ACK od přijímače (Slave). Vysílač nastaví
SDA na log. 1, aby jeho výstup neovlivňoval linku SDA (viz výše informace
o výstupu typu otevřený kolektor). Master musí nastavit SDA do klidového
stavu na log. 1 před příjmem každého bitu od podřízeného obvodu.
Zjednodušené zobrazení
Pro další popis komunikace budeme používat zjednodušené zobrazení, jako
na obrázku 2.14.
Master
P
S D 7 D 6 D 5 D4 D 3 D 2 D 1 D0
Slave
A
Obrázek 2.14: Zjednodušené zobrazení průběhu komunikace na lince I2 C
Adresování
Na sběrnici I2 C může být připojeno více obvodů současně, proto musí mít
každý obvod svou jednoznačnou adresu, aby jej bylo možno „oslovit“.
Každá adresa má osm bitů, které jsou rozděleny podle obrázku 2.15. Bity
označené 0 ÷ 3 jsou dány výrobcem a nelezneme je vždy v technickém
30
H3 H2 H1 H0 A 2 A 1 A 0 RW
Obrázek 2.15: Formát adresy obvodu na I2 C
1
+ 5 V
A 2
A 1
A 0
manuálu daného obvodu. Bity 0 ÷ 2 si při zapojení obvodu nastaví uživatel. Na vývojovém KITu se bity 0 ÷ 2 nastavují pomocí třech přepínačů
dle zapojení na obrázku 2.16. Ze zapojení je patrné, že zapnutý přepínač
znamená logickou úroveň 0. Na uvedený přepínač jsou připojeny oba dále
popisované obvody.
2
A 0
1
2
A 1
1
2
A 2
G N D
.
Obrázek 2.16: Určení adresových bitů A0-A2 pomocí přepínačů
Poslední bit adresy je / . Tímto bitem říkáme, zda následující data
budeme z pohledu řídícího obvodu do příslušného obvodu zapisovat (/ =
0), nebo budeme data číst (/ = 1).
2.4.2
Ověření adresy
Nejjednodušším příkladem komunikace je ověření ( „zaadresování“), zda daný
obvod má skutečně přidělenou adresu dle dokumentace a uživatelského nastavení. Povinností obvodu, který přijme jeden bajt, je příjem potvrdit signálem ACK. Pokud má náš obvod DS1621 adresu 0 ÷2 , pak musí na zaslání
bajtu dle obrázku 2.17 odpovědět. Tím máme jistotu, že obvod komunikuje.
MASTER S
1
0
0
1
DS1621
P
A2 A1 A0 0
A
Obrázek 2.17: Příklad „zaadresování“ I2 C obvodu DS1621
31
2.4.3
8 bitový expandér PCF8574
Nedílnou a nezbytnou součástí následujícího textu je i technický manuál
výrobce PCF8574.pdf.
Pro výukové účely byl obvod PCF8574 vybrán záměrně. Jde o nejjednodušší dostupný obvod pro sběrnici I2 C. Neobsahuje žádné konfigurační
registry a jeho chování nelze nijak měnit. Obsahuje pouze jediný 8 bitový
registr, jehož každý bit je přímo vyveden na právě jeden výstupní pin pouzdra. Hodnotu tohoto registru lze jediným zápisem změnit a lze si aktuální
nastavenou hodnotu i přečíst.
Průběh komunikace s obvodem PCF8574 je znázorněn v manuálu na
straně 10 a 11.
Adresa
Na straně 9 manuálu PCF8574 je uvedena adresa přidělená výrobcem pro
nevyšší 4 bity 0 ÷ 3 adresy obvodu. Je to hodnota 0100b. Zbylé tři bity
adresy 0 ÷ 2 se nastavují přepínači přímo u obvodu na vývojové desce.
Příklad zápisu jednoho bajtu i s určením adresy může vypadat jako na
obrázku 2.18.
MASTER S
0
1
0
0
A2 A1 A0 0
PCF8574
0
1
0
1
1
0
1
P
0
A
A
Obrázek 2.18: Zaslání jednohy bajtu (0b01011010) obvodu PCF8574
Zapojení
Pro možnost vizuální kontroly je na vývojové desce připojeno na vývody
obvodu PCF8574 osm LED podle obrázku 2.19. Každému bitu registru odpovídá jedna LED označená 0-7. Jak je patrno z obrázku, LED se aktivují
logickou úrovní 1.
32
LED0
1
2
SCL
SDA
3
A0 PCF8574
A1
A2
4
5
6
LED7
Obrázek 2.19: Připojení LED k obvodu PCF8574
2.4.4
Digitální teploměr Dallas DS1621
Nedílnou a nezbytnou součástí následujícího textu je i technický manuál
výrobce teploměru DS1621.pdf.
Obvod DS1621 je digitální teploměr, který může pracovat jako teploměr
pro spojité měření teploty, nebo provádět měření teploty na požádání, nebo
pracovat jako termostat s nastavitelnou hysterezí.
Pro výukové účely budeme preferovat použití teploměru pro spojité měření teploty.
Formát teploty
Na straně 4 manuálu DS1621 je uveden digitální formát naměřené teploty.
Jde o devítibitové znaménkové číslo, kde nejnižší bit představuje rozlišení půl
stupně. Protože devíti bity je překročen formát jednoho bajtu, je naměřená
teplota předávána ve dvou bajtech za sebou.
Adresa
Na straně 8 manuálu DS1621 je uvedena adresa přidělená výrobcem pro
nevyšší 4 bity 0 ÷ 3 adresy obvodu. Je to hodnota 1001b. Zbylé tři
33
bity adresy se nastavují instalovanými přepínači přímo na vývojové desce.
Požadovaná hodnota bude zadána přímo na cvičení.
Příkazy pro řízení teploměru
Na straně 10 manuálu DS1621 jsou uvedeny všechny příkazy, kterými se
teploměr ovládá. Stručný přehled s krátkým popisem uvádíme zde:
∙ Příkaz ACh (Access Config) slouží pro nastavení chování teploměru.
Formát konfiguračního slova je na straně 5 manuálu DS1621. Pro
funkci teploměru je důležitý bit označený jako 1SHOT, kterým se určuje, zda teploměr bude měřit teplotu spojitě, nebo na požádání.
Při modifikaci konfiguračního slova by se měl nejprve aktuální stav
přečíst, změnit potřebné bity a poté teprve zapsat.
∙ Příkaz EEh (Start Convert) spustí převod teploty.
∙ Příkaz 22h (Stop Convert) zastaví převod teploty.
∙ Příkaz AAh (Read Temperature) slouží pro čtění teploty. Obdrží-li
obvod tento příkaz, vyšle následně 2 bajty s naměřenou teplotou.
∙ Příkaz A1h (Access TH) registr horního limitu termostatu.
∙ Příkaz A2h (Access TL) registr dolního limitu termostatu.
Podrobnější popis a ostatní příkazy jsou v manuálu výrobce.
Příklad komunikace
Chceme-li předat obvodu nějaký příkaz, například požadavek na spuštění
převodu teploty, zašleme příkaz EEh na požadovanou adresu. Postup je na
obrázku 2.20.
MASTER S
1
0
0
1
A2 A1 A0 0
DS1621
1
1
1
0
1
1
1
P
0
A
A
Obrázek 2.20: Zaslání příkazu Start Convert (EEh) obvodu DS1621
Další přesný popis všech komunikačních možností s obvodem DS1621
naleznete v dokumentaci DS1621 na straně 9.
34
Programátorské rozhraní
Pro komunikaci s obvody na sběrnici I2 C je implementována následující
množina funkcí:
void I2C_Init() - inicializace, signály SDA a SCL jsou nastaveny na 1.
void I2C_Start() - vygenerování sekvence START.
void I2C_Stop() - vygenerování sekvence STOP.
void I2C_Ack() - odeslání ACK.
void I2C_NAck() - odeslání NACK.
char I2C_getAck() - přečtení ACK.
char I2C_Vystup( unsigned char value ) - odeslání bajtu a převzetí ACK.
unsigned char I2C_Vstup() - příjem jednoho bajtu bez potvrzení.
Příklady úkolů ve cvičení
∙ Prostudování dokumentace a připravených programů je součástí přípravy před cvičením.
∙ Prvním úkolem na cvičení bude nastavit obvodu DS1621 požadovanou
tříbitovou adresu.
∙ Programem ověřit, zda je obvod na požadované adrese. Ten musí odpovědět signálem ACK.
∙ Čtení a zápis dat z/do expandéru PCF8574
∙ Nastavit teploměr pro spojitý převod teploty.
∙ Spustit převod teploty, číst aktuální teplotu.
∙ Nastavit obvod DS1621 jako termostat
35
2.4.5
FM/AM radiomodul Si4735
Nedílnou součástí této dokumentace je i programátorská příručka výrobce
FM radiomodulu SI4735-PG.pdf a text normy EN50067.pdf specifikující
systém RDS.
Modul FM rádia obsahuje digitální rádiový přijímač Si4735, který v sobě
zahrnuje vše potřebné pro příjem rádiového signálu v pásmech FM/AM. Ve
cvičení budeme využívat pouze FM pásmo. Tento obvod se běžně používá v
mobilních telefonech jako miniaturní FM přijímač. Součástí FM modulu je
i obvod PCF8574 s osmi LED, popsaný v kapitole 2.4.3. Pro ovládání obou
obvodů bude použita sběrnice I2 C.
Po správném nastavení obvodu rádia je na jeho výstupech k dispozici
zvukový signál, který je dále zesílen v zesilovači a po stisknutí tlačítka je
možné zvuk přehrát v integrovaném reproduktoru. Je také možné připojit
si vlastní sluchátka, jejichž reprodukce již není závislá na stisku tlačítka.
Obrázek 2.21: Schéma zapojení radiového modulu Si4735
Adresa obvodu Si4735 na sběrnici I2 C je 0x22. Za touto adresou se dále
uvádí konfigurační bajt, kterým se obvodu sděluje, jakou akci bude dále
vykonávat. Některé konfigurační bajty je možné doplnit dalšími bajty jako
argumenty. Vše je podrobně popsáno v dokumentaci výrobce.
36
Změna hlasitosti
Pro změnu hlasitosti se využívá příkaz SET_PROPERTY 0x12, který má
jako první argument 0x00 a jako další dvoubajtový argument podpříkaz
RX_VOLUME 0x4000. Dále následuje nulový bajt a poslední bajt určuje
svými pěti bity s nejnižší vahou hlasitost v úrovni 0-63.
Podrobnější informace jsou uvedeny v technické dokumentaci na straně
65 a 117.
Dotaz
0
1
2
3
4
5
0x12
0x00
0x40
0x00
0x00
0b000VVVVV*
*Bity V určují hlasitost
Ladění rozhlasové stanice
Pro naladění obvodu na požadovanou frekvenci je možné využít dvou příkazů. První možností je příkaz FM_TUNE_FREQ 0x20, který obsahuje
další 4 bajty jako argumenty. První a čtvrtý bajt mohou zůstat nulové.
Druhý a třetí bajt obsahuje požadovanou frekvenci vynásobenou stem. Například pro frekvenci 97.3 MHz je nutné zadat hodnotu 9730 a to tak, že do
druhého argumentu se zadá horní byte frekvence a do třetího spodní byte
frekvence.
Bližší informace jsou uvedeny v technické dokumentaci na straně 67-68.
Dotaz
0
1
2
3
4
0x20
0x00
FreqHI
FreqLO
0x00*
*Bližší význam jednotlivých bitů je možné vyčíst z dokumentace
Druhou možností ladění stanic je proces automatického ladění pomocí
příkazu FM_SEEK_START 0x21. Příkaz obsahuje pouze jeden argument,
ve kterém je na místě druhého bitu uvedeno, zda se má po dosažení limitu
rozsahu začne znovu na opačném konci rozsahu - log.1, nebo na konci rozsahu
zastavit - log.0. Na pozici třetího bitu je log.1, pokud se provádí ladění
směrem nahoru a log.0, pokud se ladí směrem dolů.
Odpovědí na příkaz automatického ladějí je jeden byte. Bližší informace
jsou uvedeny v technické dokumentaci na straně 69.
Dotaz
0
2
0x21
0b0000SW00*
* S - ladění nahoru/dolu 0/1
W - na konci rozsahu začne ladění opět z opačného konce intervalu
37
Detekce stavu přijímače
Příkaz FM_TUNE_STATUS 0x22 obsahuje pouze jeden argument, který
je možné ponechat nulový. Po zadání tohoto příkazu je možné vyčíst osm
bajtů. Ve druhém a třetím bajtu lze zjistit aktuálně naladěnou frekvenci.
Ve čtvrtém bajtu je hodnota síly signálu a v pátém bajtu kvalita signálu po
naladění stanice.
Bližší informace jsou uvedeny v technické dokumentaci na straně 70-71.
Dotaz
0
1
0x22
0x00*
*Bližší význam jednotlivých bitů je možné vyčíst z dokumentace
Odpověď
0
1
2
3
4
5
6
7
S1*
S2*
FreqHI
FreqLO
RSSI
SNR
MULT*
CAP*
*Bližší význam jednotlivých bitů je možné vyčíst z dokumentace
Detekce kvality signálu
Příkaz FM_RSQ_STATUS 0x23 obsahuje pouze jeden argument, který je
možné ponechat nulový. Po zadání tohoto příkazu je možné vyčíst osm bajtů.
Ve druhém bajtu je v nejnižším bitu  informace, zda na aktuálně nastavené
frekvenci byla rozpoznána nějaká stanice. Ve čtvrtém bajtu je hodnota síly
signálu a v pátém bajtu kvalita signálu.
Bližší informace jsou uvedeny v technické dokumentaci na straně 72-73.
Dotaz
0
1
0x23
0x00*
*Bližší význam jednotlivých bitů je možné vyčíst z dokumentace
Odpověď
0
1
2
3
S1*
S2*
0bxxxxxxxV*
STBL*
4
RSSI
5
6
7
SNR
MULT*
FREQ*
*Bližší význam jednotlivých bitů je možné vyčíst z dokumentace
Radio Data System (RDS)
RDS je systém, který může doprovázet vysílání rádiových stanic. Slouží k
přenosu datových informací do rádiového přijímače. Mezi tyto informace
patří například název vysílané stanice, název právě přehrávaného pořadu,
alternativní frekvence na kterých vysílá identická stanice, nebo hlášení o
poloze a závažnosti dopravních nehod v okolí.
38
Pro získání jedné skupiny RDS dat z obvodu Si4735 je nutné zadat příkaz
FM_RDS_STATUS 0x24. Tento příkaz je následován jedním bajtem, ve
kterém je podstatný pouze bit I s nejnižší vahou. Bitem I=1 se povolí vnitřní
přerušení pro příjem RDS dat.
Jako odpověď na tento příkaz je přijato 13 bajtů. Ve druhém bajtu je
nejnižším bitem S oznamováno, zda jsou RDS informace synchronizovány.
Bez tohoto bitu nemá smysl další informace zpracovávat! Pro následné zpracování jsou nejdůležitější bajty označené jako BxHI a BxLO kde x je 1 až 4.
Jedná se přímo o bloky dat přenášené v rámci jedné skupiny.
Bližší informace jsou uvedeny v technické dokumentaci na straně 74-76.
Dotaz
0
1
0x24
0b00000SMI*
* bit I zapíná vnitřní přerušení pro příjem RDS,
význam bitů S a M je uveden v dokumantaci
Odpověď
0
1
2
3
4
5
RDS0*
RDS1*
0bxxxxxxxS*
RDS3*
B1HI
B1LO
6
7
8
9
10
11
12
B2HI
B2LO
B3HI
B3LO
B4HI
B4LO
0baabbccdd**
*Bližší význam jednotlivých bitů je možné vyčíst z dokumentace
** Bity aa, bb, cc a dd určují stav jednotlivých bloků
Data v systému RDS se přenášejí ve skupinách. Každá skupina se dále
dělí na čtyři bloky, viz obrázek 2.22. Obsah jednotlivých bloků je dán normou
EN50067. Bity Checkword jsou zpracovány přímo obvodem Si4735 a nejsou
v odpovědi na dotaz 0x24 obsaženy.
Obrázek 2.22: Obecná struktura RDS
Z obrázku 2.22 je patrné, že v prvním bloku každé skupiny je vysílána
39
informace označená jako PI – Program Identification. Jedná se o jedinečné
číslo, které je specifické pro každou rozhlasovou stanici. Druhý blok obsahuje
v bitech A3 až A0 identifikaci skupiny. Dále bit B0, který určuje zdali se
jedná o verzi A nebo B. Bit TP určuje, zdali se aktuálně vysílá dopravní
hlášení. Bity PT4 až PT0 definují typ vysílaného programu (hudba, řeč, aj.).
Význam zbylých bitů v bloku 2 a bitů v bloku 3 a 4 jsou již závislé na typu
skupiny.
Dekódování služby Program Service
Služba Program Service (název stanice) se vysílá ve skupině číslo 0 a to jak
ve verzi A, tak i B, přičemž text v obou verzích se může lišit. Rozložení
jednotlivých bitů ve skupinách A a B je znázorněno na obrázcích 2.23 a
2.24. Pokud je detekována skupina 0, je v bloku 2 na posledních dvou bitech
příznak, které dva znaky z osmiznakového názvu stanice se přenášejí. Název
programu je tedy rozdělen na čtyři dvojice. Samotné znaky jsou vysílány v
bloku 4 v horním a spodním bajtu.
Obrázek 2.23: Skupina 0A
Obrázek 2.24: Skupina 0B
40
Dekódování služby Alternative Frequency
Služba alternativní frekvence je vysílána spolu se službou PS ve skupině 0 a
to pouze ve verzi A. Verze B skupiny 0x00 se liší především ve třetím bloku,
jak je patrné z obrázků 2.23 a 2.24. Ve verzi A jsou na pozici třetího bloku
vysílány alternativní frekvence na pozici horního a dolního bajtu. Hodnota
0b00000001 odpovídá frekvenci 87.6MHz až hodnota 0b110011 odpovídá
frekvenci 107.9MHz.
Dekódování služby Radiotext
Radiotext je obdoba služby PS s tím rozdílem, že znaků je 64. Znaky jsou
rozděleny do čtveřic. Radiotext je vysílán ve skupině s označením 2A. Čtyři
bity s nejnižší vahou v bloku 2 určují, která čtveřice znaků je přenášena.
V blocích 3 a 4 jsou poté přenášeny čtyři znaky.
Obrázek 2.25: Skupina 2A
41
Příklady úkolů ve cvičení
∙ Nalaďte modul FM rádia na požadovanou frekvenci.
∙ Pomocí dvou tlačítek nastavujte úroveň hlasitosti.
∙ Pomocí dvou tlačítek spusťte automatické ladění rádia (nahoru nebo
dolů).
∙ Využijte bargraf připojený k obvodu PCF8574 k indikaci síly přijímaného signálu.
∙ Nalaďte stanici vysílající RDS a zobrazte data přenášená službou Program Service.
∙ Nalaďte stanici vysílající RDS a zobrazte data přenášená službou Radiotex.
∙ Nalaďte stanici vysílající RDS a zobrazte alternativní frekvence na
kterých je vysílána identická stanice.
42
Část II
Programování paralelních
systémů
43
Kapitola 3
Vlákna
3.1
Využití výpočetního výkonu procesorů s více
jádry pomocí vláken (threads)
V posledních letech se díky rozvoji moderních technologií výroby procesorů stalo běžným standardem výrobců, umístit do jednoho pouzdra více
procesorů současně. Výpočetní výkon počítače se takto navyšuje prakticky
tolikrát, kolik jader je celkově v daném počítači nainstalováno. Za tímto
technickým vývojem ale zaostává vývoj programového vybavení počítače.
Programy i operační systémy jsou za technickým vývojem stále pozadu.
Ukázalo se to v posledních 20 letech velmi viditelně několikrát. Jako příklad
vezměme čas, než se 64 bitové operační systémy staly standardem. Firma
AMD představila svůj první 64 bitový procesor v roce 2000. Kdy se dostaly
64 bitové OS na servery a kdy na desktopy? Odpověď snadno naleznete na
internetu.
Problémem současnosti je vývoj programů pro využívání více procesorů
paralelně. V roce 2010 ve svém článku „The Trouble With Multicore“ uvedl
jeden z významných odborníků David Patterson, profesor na katedře informatiky Univerzity v Berkeley i následující odstavec:
„One of the biggest factors, though, is the degree of motivation. In the
past, programmers could just wait for transistors to get smaller and faster,
allowing microprocessors to become more powerful. So programs would run
faster without any new programming effort, which was a big disincentive to
anyone tempted to pioneer ways to write parallel code. The La-Z-Boy era of
program performance is now officially over, so programmers who care about
performance must get up off their recliners and start making their programs
parallel.“
Pokud tedy požadujeme, aby naše programy pracovaly rychleji, není do
44
budoucna jiná cesta, než je psát jako paralelní!
3.1.1
Programování s vlákny
Vlákny rozumíme samostatně (a paralelně) běžící podprogramy jednoho programu (procesu). Tato technologie je v operačních systémech Windows i Unixech implementována již téměř 20 let. Přináší programátorům větší pohodlí
při psaní programů a to bez ohledu na počet procesorů počítače. Teprve však
při dvou a více procesorech mohou vlákna otevřít programátorovi cestu k
využítí vyššího výpočetního výkonu počítače.
Podívejme se, jak využít vlákna v libovolném operačním systému Windows. V programátorské dokumentaci WINAPI rozhraní (např. na stránkách
http://msdn.microsoft.com) můžeme najít následující informace. Každá funkce,
která má být vykonávána jako samostatné vlákno, musí mít tento tvar:
DWORD WINAPI jmeno_funkce( LPVOID par ) { /* tělo funkce */ }
Máme-li takto deklarovanou funkci, můžeme z ní vytvořit vlákno pomocí
funkce CreateThread, která má následující prototyp:
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId );
Ze šesti parametrů funkce můžeme 4 parametry ponechat nastavené jako
0 - lpThreadAttributes, dwStackSize, dwCreationFlags, lpThreadId.
Parametr lpStartAddress je název funkce, kterou chceme spustit jako samostatné vlákno. A lpParameter je parametr, který novému vláknu předáváme. Návratová hodnota je HANDLE nového vlákna, nebo informace o
selhání.
Pro čekání na ukončení vykonávání vlákna použijeme následující funkci:
DWORD WINAPI WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds );
Jako první parametr uvedeme HANDLE vlánka, které jsem si dříve vytvořili. Druhý parametr je maximální čas v milisekundách, po jaký na ukon45
čení vlákna budeme čekat. Pokud chceme počkat, až vlákno opravdu skončí,
zadáme INFINITE.
Příklad programu, který vytvoří jedno vlákno a počká na jeho ukončení
může vypadat následovně:
DWORD WINAPI funkce_vlakno( LPVOID str )
{
printf( "Spustilo se vlakno %s.\n", ( char * ) str );
Sleep( 5000 );
return 0;
}
int main()
{
HANDLE vlakno = CreateThread( 0, 0,
funkce_vlakno, "TESTOVACI", 0, 0 );
WaitForSingleObject( vlakno, INFINITE );
}
Další příklad na využití vláken je uveden v příloze tohoto studijního
materiálu - vlakna.zip. Tento archiv obsahuje ukázku programu, kde se
hledá pomocí dvou vláken maximální prvek v poli. Každé ze dvou vláken
prohledává jen polovinu pole. Výsledný čas hledání je v případě spuštění
na dvou a víceprocesorovém počítači poloviční. Zdrojový kód programu je
velmi jednoduchý a je popsán ve vložených komentářích.
Příprava na cvičení
∙ Seznámit se ukázkovým programem a způsobem měření doby běhu
částí programu.
∙ Zopakovat si nejjednodušší algoritmy třídění - přímý výběr, přímé
vkládání a bublinkové třídění.
∙ Připravit si třídící funkce tak, aby bylo možno třídit sestupně i vzestupně.
∙ Upravit třídící funkce tak, aby bylo možno setřídit jen část pole.
∙ Připravit si třídící funkce pro třídění pole s libovolnými typy prvků int, long, fload, double, ...
∙ Vyzkoušet si vygenerovat libovolně dlouhé pole náhodných čísel.
∙ Vyzkoušet si vytváření vláken.
46
Úkoly ve cvičení
∙ Setřídit určeným algoritmem pole náhodně vygenerovaných čísel.
∙ Setřídit část pole, např. horní a dolní polovinu pole.
∙ Spojit dvě setříděné části pole v jednu posloupnost.
∙ Spustit třídění částí pole paralelně.
∙ Změřit čas třídění.
47
Kapitola 4
CUDA
Návody pro poslední dvě cvičení jsou v samostatném dokumentu na internetových stránkách pro tento předmět.
48
Download

katedra Informatiky, VŠB-TU Ostrava, FEI, 2014 Návody do cvičení