| Voltmetr řízený mikroprocesorem |
![]() |
|
| Obr.1 | Obr.2 |
![]() Obr.3 Vnitřní blokové schéma A/D převodníku s postupnou aproximací |
Ux - měřené napětí UK - kompenzační napětí NK - napěťový komparátor PR - posuvný registr MSB - (angl. Most Significant Bit) - nejvýznamnější bit LSB - (angl. Least Significant Bit) - nejméně významný bit |
![]() |
DB0 – DB7 ---------------- dig. výstup z převodníku Vref/2 ------------------- referenční napětí Vin +, Vin - ------------------- difer. napěťové vstupy Clk in, Clk r ----------------- hodinové vstupy INTR --------------------- přerušení do procesoru GND ---------------------- zem RD ----------------------- příkaz pro čtení WR ----------------------- příkaz pro zápis CS ----------------------- povolovací vstup A GND ----------------------- analogová zem D GND ----------------------- digitální zem |
![]() Obr.4 Obvod pro ověření funkce převodníku |
![]() Obr.5 Odporový dělič na vstupu převodníku |
![]() |
Podrobné informace o HDSP 5621 najdete zde. Informace o dalších typech sedmisegmentových displejů najdete zde. |
STOVKY DATA 50H ; určení adres pro pomocné výpočty
DESITKY DATA 51H
JEDNOTKY DATA 52H
ZBYTEK DATA 53H
ORG 0H
JMP START
ORG 0BH ;přerušení čítače/časovače 0
LJMP PRERUS
START: ORG 20H ;vlastní program
MOV R0,#250D ;nastavení počtu cyklů čítače
MOV DPTR,#100H ;pomocná hodnota při výpočtech - displej
MOV TMOD,#00000010B ;nastavení čítače – mód s předvolbou
MOV TH0,#5D ;nastavení předvolby čítače (255 – 250 = 5 µs)
MOV TL0,#5D
SETB ET0 ;povolení přerušení od čítače 0
SETB EA
SETB TR0
KONEC: JMP KONEC ; nekonečná smyčka.
Při běhu nekonečné smyčky je každých 250 µs vyvoláno přerušení. Zpracuje se vstup od A/D převodníku a aktualizuje se údaj na displeji.
PRERUS: DJNZ R0,CYKLUS
MOV R0,#250D
.
.
CYKLUS: RETI
V registru R0 je konstanta, která určuje, jak často se má měnit údaj na displeji. V našem případě je to hodnota 250. Při každém volání se R0 zmenší o jednčku. Pokud je R0 rovno 0, doplní se na výchozí hodnotu a zpracuje se tělo přerušení. Jelikož se přerušení volá každých 250 µs a v registr R0 je hodnota 250, jsou příkazy v přerušení zpracovávány každých 250 * 250 = 62500 µs = 62,5 ms. Vždy po této době se zpracuje vstup a na výstup displeje se přivede aktualizovaný údaj hodnoty napětí.

MOV A,P1
CJNE A,#11111010B,PRVNI ; Otestuje, jestli A =250
LJMP DESET
PRVNI: CJNE A,#11111011B,DRUHY ; Otestuje, jestli A =251
LJMP DESET
DRUHY: CJNE A,#11111100B,TRETI ; Otestuje, jestli A =252
LJMP DESET
TRETI: CJNE A,#11111101B,CTVRTY ; Otestuje, jestli A =253
LJMP EE
CTVRTY: CJNE A,#11111110B,PATY ; Otestuje, jestli A =254
LJMP EE
PATY: CJNE A,#11111111B,NENI_DESET ; Otestuje, jestli A =255
; když ne,skok na NENI_DESET, kde
; pokračují další výpočty a vlastně
; ta nejdůležitější část programu
EE: MOV P0,#10001100B
MOV P2,#00001100B
CYKLUS1: LJMP CYKLUS ;skok na konec cyklu
DESET: MOV P0,#11110011B
MOV P2,#01000000B
LJMP CYKLUS ;skok na konec cyklu
Návěští CYKLUS1 je vlastně meziskok. Některé příkazy, jako CJNE nebo DJNZ, mohou provést skok maximálně o 128 bytů. V našem případě to nestačí a tak je řádek
CYKLUS1: LJMP CYKLUSjen jakýsi odrazový můstek, který tyto příkazy využívají, aby se dostali na konec programu.
NENI_DESET: MOV B,#100D ;rozdělení čísla na stovky, desítky a jednotky
DIV AB
MOV STOVKY,A ; Stovky
MOV A,#10D
XCH A,B
DIV AB
MOV DESITKY,A ; Desítky
MOV JEDNOTKY,B ; Jednotky
A teprve nyní všechny tři proměnné vynásobíme 4 :
MOV A,STOVKY
MOV B,#4D
MUL AB
MOV STOVKY,A ; STOVKY = STOVKY * 4
MOV A,DESITKY
MOV B,#4D
MUL AB
MOV DESITKY,A ; DESITKY = DESITKY * 4
MOV A,JEDNOTKY
MOV B,#4D
MUL AB
MOV JEDNOTKY,A ; JEDNOTKY = JEDNOTKY * 4
Následuje zaokrouhlení a upřesnění hodnoty výsledku. Obvykle se zaokrouhluje nahoru, když je číslo větší než 5 a dolů, pokud je menší. My místo čísla 5 používáme číslo 7. Je to kompenzace nepřesnosti vstupu. Vstup voltmetru je napěťový dělič z odporů. Bohužel odpory a potenciometry se nedají nastavit s nekonečnou přesností. Ne každý se dá nastavit zcela přesně, je to dáno jak technologií, tak ladícími prvky (šroubovací závity a podobně). Proto v praxi, i když s tím počítáme, není diference D = 4, ale v praxi se o několik setin či tisícin liší. U malých čísel to nevadí, ale odchylka postupně narůstá. Proto jsme zvolili mez zaokrouhlování na hodnotě ne rovné polovině 10, ale spíše jedné třetině, tedy 7.
MOV B,#10D
DIV AB
MOV ZBYTEK,A ;v A jsou (JEDNOTKY * 4 ) /10
MOV A,B ;v B je zbytek po dělení 10
CJNE A,#7D,MENSI_NEZ_7 ;skok při nerovnosti, mění příznak přenosu
;C=1 if A < 7, jinak C=0
LJMP VETSI_NEZ_7
A nyní jak a kam se bude zaokrouhlovat podle výsledku :
MENSI_NEZ_7: JNC VETSI_NEZ_7 ;druhé otestování
MOV A,DESITKY
MOV B,ZBYTEK
ADD A,B ;součet desítek a zbytku po operací s jednotkami
MOV B,#10D
DIV AB ;vydělíme deseti – počet desítek v součtu (v reg. A)
MOV JEDNOTKY,B ;druhé číslo výsledku (zbytek dělení) - výstup
MOV B,STOVKY
ADD A,B ;přičte se výsledek předchozího výpočtu
MOV DESITKY,A ;první číslo výsledku po zaokrouhlení - výstup
LJMP VYSTUP ;výsledek na displej
VETSI_NEZ_7: MOV B,ZBYTEK ;zde je zbytek větší nebo roven 7
MOV A,#1D
ADD A,B
MOV ZBYTEK,A ;zbytek = zbytek + 1
MOV A,DESITKY
MOV B,ZBYTEK
ADD A,B ;součet desítek a zbytku
MOV B,#10D
DIV AB ;A = počet desítek v součtu
MOV JEDNOTKY,B ;druhé číslo výsledku
MOV B,STOVKY
ADD A,B ; + počet stovek
MOV DESITKY,A ;první číslo výsledku
V proměnných DESITKY a JEDNOTKY jsou uloženy čísla, která se dostanou na displej ve tvaru :
Rámečky samozřejmě znamenají jednomístný LED displej a ukazují číslo od 0 do 9.
MOV A,DESITKY
MOVC A,@A+DPTR
MOV P0,A
MOV A,JEDNOTKY
MOVC A,@A+DPTR
MOV P2,A
V proměnných DESITKY a JEDNOTKY jsou hodnoty v intervalu 0 – 9. Obsah proměnných se postupně dostane do registru A. Následuje řádek
MOVC A,@A+DPTR
který do registru A dosadí hodnotu na A + DPTR. V registru DPTR je hodnota 100h, proto se do registru A dosadí hodnota A + 100h, která odpovídá kombinaci pro rozsvícení jednotlivých segmentů displeje. Pokud je tedy v A hodnota 0, do A se dosadí hodnota z adresy 100h, která odpovídá číslu 0 atd.
|
![]() |
ORG 100H
DB 01000000B,01110011B,00100100B,00100001B,00010011B
DB 00001001B,00001000B,01100011B,00000000B,00000001B
END
|
Položka |
Množství |
Referenční označení |
Typ |
1 |
1 |
IO1 | ADC0804CN |
2 |
1 |
IO2 | AT89C51 |
3 |
1 |
ST1 | 7805 |
4 |
1 |
ZD1 | BZX 85V010 (Zenerka 10V/1,3W) |
5 |
1 |
Displej | HDSP - 5621 |
6 |
1 |
X1 | krystal 12 MHz |
7 |
3 |
R1,R2,R3 | 10k |
8 |
1 |
R4 | 8k2 |
9 |
15 |
R5 až R19 | 220R |
10 |
1 |
TR1 | trimr 250R (PT10VE250) |
11 |
1 |
TR2 | trimr 25k (PT10VK025) |
12 |
1 |
C5 | 10uF/25V |
13 |
1 |
C1 | 150pF |
14 |
3 |
C2,C6,C7 | 100nF |
15 |
1 |
C8 | 470uF/50V |
16 |
2 |
C3,C4 | 33pF |
17 |
2 |
Vstup 0 až 10V, Ucc 24V | svorkovnice ARK 550/2 |