[PIC programování] – 9. díl – bonus
Vítám vás u malého bonusu k devátému dílu.
Napadlo mě, že by někdo chtěl, aby jeho čítač počítal jen do určité hodnoty, např. od 0 do 9. V Assembleru nic jako porovnání čísel nemáme, alespoň ne tak, jak to známe z jiných jazyků, např. z jazyka C.
Abychom porovnali dvě čísla, budeme odčítat! K tomu nám slouží instrukce subwf a sublw. Rovnou ještě pro budoucí účely uvedu instrukce addwf a addlw, kterými naopak přičítáme.
Naše MCU má registr zvaný STATUS. Z tohoto registru umíme vyčíst spoustu důležitých věcí. Nás bude zajímat jeden jediný bit – Zero bit. Tento bit je roven 1, pokud je výsledek operací addwf, addlw, subwf a sublw nulový.
Pokud od registru odečteme nějakou konstantu a výsledek bude nulový, znamená to přece, že hodnota v registru se rovnala konstantě. Zkontrolujeme tedy Zero bit a když bude roven 1, naše čísla se rovnají.
Zde uvádím rovnou celý rozšířený program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
#include "p16f1705.inc" ; CONFIG1 ; __config 0xC9E4 __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF ; CONFIG2 ; __config 0xDEFB __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_OFF & _ZCDDIS_ON & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF #define CITAC .100 R_CITAC equ 0x20 ;dekrementující čítač R_POM equ 0x21 ;univerzální pomocná proměnná R_DISPCITAC equ 0x22 ;hodnota zobrazovaná na displeji org 0 goto START ;====== PODPROGRAMY ============================================================ ;vezme cislo 0 - 15 z registru W a vrátí ;odpovídající segmenty na displeji ;ve formátu: <C4:C3:C2:C1:C0:A2:A1:A0> disp_hex_cislo: andlw 0x0F ;ochrana proti nechtěným hodnotám brw ;(vyšším než 15) retlw b'00100001' ; 0 retlw b'11100111' ; 1 retlw b'00110010' ; 2 retlw b'10100010' ; 3 retlw b'11100100' ; 4 retlw b'10101000' ; 5 retlw b'00101000' ; 6 retlw b'11100011' ; 7 retlw b'00100000' ; 8 retlw b'10100000' ; 9 retlw b'01100000' ; A retlw b'00101100' ; B retlw b'00111001' ; C retlw b'00100110' ; D retlw b'00111000' ; E retlw b'01111000' ; F ;------------------------------------------------------------------------------- ;načte segmenty ve formátu <C4:C3:C2:C1:C0:A2:A1:A0> ;z registru W a přiřadí je do registrů LATA a LATC disp_zobraz: banksel R_POM movwf R_POM andlw b'111' banksel LATA movwf LATA banksel R_POM movfw R_POM lsrf WREG lsrf WREG lsrf WREG banksel LATC movwf LATC return ;====== INICIALIZACE PROGRAMU ================================================== START: ;nastavení vnitřního oscilátoru na frekvenci 4MHz movlw b'01101010' banksel OSCCON ;je třeba vybrat správnou banku movwf OSCCON ;nastavení dekrementujícího čítače movlw CITAC ;čítač začíná na hodnotě .100 banksel R_CITAC movwf R_CITAC ;nastavení timeru 4 banksel T4CON movlw b'1001101' ;1:10 postscaler, tmr on, 1:4 prescaler movwf T4CON movlw .250 movwf PR4 ;nastavení IO pro displej banksel TRISA ;odpovídající segmenty na displeji jsou movlw b'111000' ;výstupy, zbytek jsou vstupy movwf TRISA movlw b'100000' movwf TRISC banksel ANSELA ;všechny piny jsou digitální clrf ANSELA clrf ANSELC banksel LATA ;segmenty nesvítí movlw b'111' movwf LATA movlw b'11111' movwf LATC banksel R_DISPCITAC clrf R_DISPCITAC ;====== HLAVNÍ PROGRAM ========================================================= HLAVNI_SMYCKA: banksel PIR2 ;testujeme timer4 btfss PIR2,TMR4IF goto HLAVNI_SMYCKA ;čítač je platný ;1Hz bcf PIR2,TMR4IF ;vynulování TMR4IF banksel R_CITAC decfsz R_CITAC ;je čítač na nule? goto HLAVNI_SMYCKA ;není, vracíme se zpět na začátek movlw CITAC ;je movwf R_CITAC ;čítač nastavíme na výchozí hodnotu movfw R_DISPCITAC call disp_hex_cislo call disp_zobraz banksel R_DISPCITAC incf R_DISPCITAC movfw R_DISPCITAC ;načtu hodnotu čítače do registru W sublw .10 ;z registru W odečtu 10 btfss STATUS,Z ;je výsledek 0 ? goto HLAVNI_SMYCKA ;není clrf R_DISPCITAC ;je, vynuluji čítač goto HLAVNI_SMYCKA end |
Ještě bych chtěl poznamenat, že pokud bychom chtěli porovnávat, je-li číslo větší/menší než jiné číslo, použijeme bit Carry (STATUS, C). Carry nás informuje, došlo-li k přetečení/podtečení registru. Pakliže se tak stalo (Carry = 1), číslo, které odečítáme, musí být větší. Pokud nedošlo, musí být naopak menší nebo rovno (poté kontrolujeme Zero bit a rozhodujeme, zda je menší nebo rovno).
A to je pro tento bonus vše. Uvidíme se v příštím díle!