⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcs51_list_11_1.asm

📁 source code from Starcki book
💻 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 + -