📄 mcs51_list_11_1.asm
字号:
; ========================================================================
;
; Tomasz Starecki: "Mikrokontrolery 8051 w praktyce"
; Wydawnictwo BTC - http://www.btc.pl
;
; ========================================================================
; ========================================================================
; obsluga wyswietlacza LCD, klawiatury, zegara czasu rzeczywistego
; i dowolnego pojedynczego urzadzenia 1-Wire dla plytki DEMO51
;
; modul glowny
; ========================================================================
; === === === === === === === === === === === === === === ===
;
; deklaracje okreslajace parametry istotne dla komunikacji
; pomiedzy modulem glownym i pozostalymi modulami
EXTERN klawiatura
PUBLIC port_klawiatury, klawisz, puszczony, wcisniety, licznik_klawiatury, kb_tick
EXTERN zapisz_znak_LCD, init_LCD, LCD_XY, zapisz_string_LCD
PUBLIC port_danych_LCD, E_LCD, RW_LCD, RS_LCD
EXTERN zegar_RTC
PUBLIC marker_sekundy, f_tick
EXTERN init_1_wire, zapisz_bajt_1_wire, czytaj_bajt_1_wire, RD_wire_bit
PUBLIC wire, brak_urzadzen_1_wire
;
; === === === === === === === === === === === === === === ===
; ============ stale =================
port_klawiatury EQU P0
f_tick EQU 50 ; patrz opis procedury zegara RTC
kb_tick EQU 3 ; obsluga klawiatury co 3*20 ms = 60 ms
T0_int_freq EQU 56 ; dla 12 MHz przerwania T0 - 5kHz
port_danych_LCD EQU P2
; ============ RAM ===================
klawisz EQU 60H
licznik_klawiatury EQU 61H
tick EQU 62H
sec EQU 63H
min EQU 64H
hour EQU 65H
licznik_zegara EQU 66H
temp EQU 67H ; zmienna pomocnicza
; =========== bity ===================
wire EQU P1.4 ; wyprowadzenie obslugujace magistrale 1-Wire
wcisniety EQU 07FH
puszczony EQU 07EH
marker_sekundy EQU 07CH
brak_urzadzen_1_wire EQU 07BH
czeka_na_puszczenie EQU 07AH
E_LCD EQU P3.4; T0 ; wyprowadzenia sterujace wyswietlaczem LCD
RW_LCD EQU P3.5; T1
RS_LCD EQU P3.6; WR
;******************************************
; start i wektory przerwan
;******************************************
ORG 0000H ; restart systemu
JMP inicjalizacja
ORG 0BH ; obsluga przerwania od T0
T0_int:
DJNZ licznik_zegara, koniec_T0 ; obsluga wlasciwa co 20 ms
MOV licznik_zegara, #100
PUSH 0 ; na stos R0 (uzywany jest bank 0 rejestrow)
PUSH B ; i rejestry SFR, ktore moga byc zmienione
PUSH ACC ; przez procedury wywolywane w przerwaniu
PUSH PSW
MOV R0, #tick
CALL klawiatura ; obsluga klawiatury
CALL zegar_RTC ; i zegara czasu rzeczywistego
POP PSW ; odtworzenie schowanych uprzednio na stos rejestrow
POP ACC
POP B
POP 0
koniec_T0:
RETI ; powrot z przerwania
;******************************************
; inicjalizacja i petla glowna programu
;******************************************
ORG 100H
inicjalizacja:
MOV licznik_klawiatury, #1
MOV licznik_zegara, #100
MOV 2FH, #0 ; zerowanie kompletu wskaznikow bitowych
MOV sec, #0
MOV min, #59
MOV hour, #23 ; i wstepne ustawienie zegara RTC
; (zeby widac bylo jak zlicza i przepelnia sie)
CALL init_LCD ; inicjalizacja wyswietlacza LCD
CALL init_1_wire ; i urzadzenia 1-Wire (jesli jest w systemie)
JB brak_urzadzen_1_wire, pisz_brak_1_wire
MOV DPTR, #jest_cos_1_wire ; jesli wykryto urzadzenie 1-Wire
CALL zapisz_string_LCD ; to za chwile bedzie znane ID
MOV A, #033H ; komenda "read ROM"
CALL zapisz_bajt_1_wire
CALL czytaj_bajt_1_wire
CALL pisz_HEX ; ID ukladu dolaczonego do 1-Wire (kod rodziny)
CALL czytaj_bajt_1_wire
CALL pisz_HEX ; i kolejne bajty
CALL czytaj_bajt_1_wire
CALL pisz_HEX
CALL czytaj_bajt_1_wire
CALL pisz_HEX
CALL czytaj_bajt_1_wire
CALL pisz_HEX
CALL czytaj_bajt_1_wire
CALL pisz_HEX
CALL czytaj_bajt_1_wire
CALL pisz_HEX
CALL czytaj_bajt_1_wire
CALL pisz_HEX ; w sumie 16 cyfr HEX
JMP dalej_init
pisz_brak_1_wire:
MOV DPTR, #pusty_1_wire ; jesli nie wykryto urzadzenia 1-Wire
CALL zapisz_string_LCD ; to odpowiedni komentarz na LCD
dalej_init:
; wstepne ustawienia licznika T0 uzywanego przez zegar i klawiature
ORL TMOD, #2 ; praca T0 w trybie 2
; (z automatycznym przeladowywaniem)
MOV TH0, #T0_int_freq ; okresla czestotliwosc przerwan od T0
ORL IE, #82H ; wlaczenie przerwan od licznika T0
SETB TR0 ; uruchomienie licznika T0
; ================= tu koniec inicjalizacji ====================
main_loop: ; petla glowna
JBC marker_sekundy, nowa_sekunda ; jesli minela kolejna sekunda (skok)
JBC puszczony, koniec_czekania_na_puszczenie
JNB wcisniety, main_loop
JB czeka_na_puszczenie, main_loop
; tu wlasciwa obsluga klawiszy
SETB czeka_na_puszczenie ; zeby obsluga pojedynczego wcisniecia
; odbyla sie jednorazowo
MOV A, klawisz ; kod klawisza do ACC
MOV A, #4EH ; kursor LCD na srodek dolnego wiersza
CALL LCD_XY
MOV A, klawisz
CALL pisz_liczbe ; wypisanie kodu klawisza na LCD
MOV A, klawisz
RL A ; kod klawisza *2
MOV DPTR, #tabela_rozgalezien ; obsluga nacisnietego klawisza przez
JMP @A+DPTR ; skok do odpowiedniej procedury
; w tabeli rozgalezien (patrz nieco dalej)
nowa_sekunda: ; jesli minela wlasnie kolejna sekunda, to
MOV A, #40 ; kursor LCD na poczatek dolnego wiersza
CALL LCD_XY
MOV A, hour ; wypisanie na LCD aktualnej godziny
CALL pisz_liczbe
MOV A, #':'
CALL zapisz_znak_LCD
MOV A, min ; minuty
CALL pisz_liczbe
MOV A, #':'
CALL zapisz_znak_LCD
MOV A, sec ; i sekundy
CALL pisz_liczbe
JMP main_loop ; i powrot do petli glownej
koniec_czekania_na_puszczenie:
CLR czeka_na_puszczenie ; jesli klawisz zostal puszczony
MOV A, #4EH ; kursor LCD na srodek dolnego wiersza
CALL LCD_XY
MOV DPTR, #dwie_spacje ; i wymazanie (spacjami) wpisanego wczesniej
CALL zapisz_string_LCD ; kodu klawisza (kt髍y byl wcisniety)
JMP main_loop
tabela_rozgalezien: ; czyli ciag dalszy wlasciwej obslugi poszczegolnych klawiszy
SJMP klawisz_0 ; jak widac, struktura tabeli jest prosta
SJMP klawisz_1 ; jest to po prostu tabela skokow (dwubajtowych, czyli SJMP lub AJMP)
SJMP klawisz_2 ; do etykiet, pod kt髍ymi rozpoczynaja sie
SJMP klawisz_3 ; procedury obslugi poszczeg髄nych klawiszy (patrz dalej)
SJMP klawisz_4
SJMP klawisz_5
SJMP klawisz_6
SJMP klawisz_7
SJMP klawisz_8
SJMP klawisz_9
SJMP klawisz_10
SJMP klawisz_11
SJMP klawisz_12
SJMP klawisz_13
SJMP klawisz_14
SJMP klawisz_15
klawisz_0: ; zmniejsza liczbe godzin na zegarze RTC
CLR EA
MOV A, hour
CJNE A, #0, dec_hour
MOV hour, #23
SETB EA
JMP nowa_sekunda ; zeby odswiezyc wskazanie zegara na LCD
dec_hour:
DEC hour
SETB EA
JMP nowa_sekunda
klawisz_1: ; zwieksza liczbe godzin na zegarze
CLR EA
MOV A, hour
CJNE A, #23, inc_hour
MOV hour, #0
SETB EA
JMP nowa_sekunda
inc_hour:
INC hour
SETB EA
JMP nowa_sekunda
klawisz_2: ; zmniejsza liczbe minut
CLR EA
MOV A, min
CJNE A, #0, dec_min
MOV min, #59
SETB EA
JMP nowa_sekunda
dec_min:
DEC min
SETB EA
JMP nowa_sekunda
klawisz_3: ; zwieksza liczbe minut
CLR EA
MOV A, min
CJNE A, #59, inc_min
MOV min, #0
SETB EA
JMP nowa_sekunda
inc_min:
INC min
SETB EA
JMP nowa_sekunda
klawisz_4: ; analogicznie mozna pisac procedury
klawisz_5: ; odpowiedzialne za realizacje funkcji
klawisz_6: ; przypisanych do pozostalych klawiszy
klawisz_7: ; jak widac w tej chwili klawisze od 4 do 15
klawisz_8: ; sa nieaktywne
klawisz_9:
klawisz_10:
klawisz_11:
klawisz_12:
klawisz_13:
klawisz_14:
klawisz_15:
JMP main_loop ; skutkiem ich wcisniecia jest powr髏 do petli gl體nej programu
; ================================================
; procedury pomocnicze
; wyswietlaja na LCD (dziesietnie / HEX) liczbe 2-cyfrowa
; (jesli dziesietnie to mniejsza od 100)
; ================================================
pisz_HEX:
MOV B, #16 ; dzielenie przez 16 dla HEX
SJMP licz
pisz_liczbe:
MOV B, #10 ; lub przez 10 dla liczb dziesietnych
licz:
DIV AB ; po podzieleniu starsza cyfra w ACC
CALL cyfra_na_ASCII
CALL zapisz_znak_LCD
MOV A, B ; mlodsza w B
CALL cyfra_na_ASCII
CALL zapisz_znak_LCD
RET
cyfra_na_ASCII: ; procedura konwersji cyfry (zapisanej binarnie) na kod ASCII
INC A
MOVC A, @A+PC
RET
kody_ASCII_cyfr:
DB '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
DB 'A', 'B', 'C', 'D', 'E', 'F'
; ==================================================
; deklaracje stringow uzywanych przy obsludze 1-Wire
; ==================================================
jest_cos_1_wire:
DB 'ID: #'
pusty_1_wire:
DB 'Brak urzadzen 1-Wire#'
dwie_spacje:
DB ' #'
END ; koniec modulu gl體nego
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -