kod jest zapewne dosc prosty, ale ma spelniac tylko podstawowe funkcje. celowo pominalem tutaj 'otoczke' programu, czyli wybor trybu pracy, wprowadzanie wartosci temp gornej i dolnej, etc tutaj jest tylko sam kod odpowiedzialny za zmierzenie temp(funkcja termostatu, jako, ze rejestry odpowiedizalne za przechowanie ich wartosci beda rowne zero nie bedzie brana pod uwage). wyswietlanie jkest tez najprostsze jakie moze byc, by wyeliminowac ewentualne bledy z konwersja etc. docelowo ma byc wyswietlane na 4 wyswietlaczach 7 segmentowych. Po zaladowaniu do pamieci i uruchomieniu na diodach systematycznie pojawia sie pewne sekwencje-jednak sa one bledne. po pierwsze w bajcie znaku-ktory powinen byc jednoznaczny albo same jedynki albo same zera pojawiaja sie rozne sekwencje. podobnie w bajcie odczytu temp, wedle niego mam w pokoju 48 stopni:). Jednak po dotknieciu termometru(przytrzymaniu) zmieniaja sie sekwencje wysylane na diody, ale nadal jest cos nie tak, no chyba, ze moje bialko dobrze sobie radzi przy okolo 70 stopniach(najczesciej) lub podobnych. :)
za wszelka pomoc i uwagi bylbym szalenie wdzieczny!!!
wierus
mod517
ORg 1000h
port equ p1.7 ;przypisanie stalych etykiet pewnym zmiennym, w celu ;zwiekszenia ;przejrzystosci programu
skip_rom equ 0cch ;p1.7-port uzyty do komunikacji 1-wire
write_scratch equ 04eh
convert equ 044h
read_scratch equ 0beh
alarm_search equ 0ech
;zerowanie rejestrow potrzebnych do pracy prorgamu;
mov r0, #00h ;mniej znaczacy bajt temperatury
mov r1, #07h ;rej r1 odpowiedzialny bedzie za szybsze wprowadzanie wartosci oraz ;do przesuwania akumulatora
mov r2, #00h ;bardziej znaczacy bajt temperatury-bajt znaku
mov r3, #00h ;pierwsza wartosc alarmowa
mov r4, #00h ;druga wartosc alarmowa
mov r5, #00h ;tryb pracy
mov r6, #00h ;do petli zwalniajacej
mov r7, #00h ;do petli zwalniajacej
mov A, #00h
mov 00, #00h ;start stop mierzenia temp
;/////////////////////////////////////////////////////////////////////
start:
mov a, r3 ;porownujemy wartosci alarmowe, jesli sa rowne tzn, ze ;wybrano tryb termometru(mamy zalozenie
cjne a, 04h, z_alarmem ; ze temp gorna>temp dolnej
lcall reset ;tryb termometru. inicjalizujemy magistrale
lcall obecnosc ;'sluchamy' potwierdzenia obecnosci ukladu
mov a, #skip_rom ;jako, ze do magistrali mamy podlaczony jeden uklad ;mozemy pominac wybor ukladu przy uzyciu
lcall sent ;komendy skip_rom. wysylamy ja do ukladu
mov a,#convert ;wysylamy do ukladu komende rozpoczynajaca pomiar ;temperatury
lcall sent ;jako, ze jest to uklad o zasilaniu zewnetrznym-nie magistrala a ;wiec nie istnieje potrzeba
lcall delay ;podbijania magistrali po komendzie convert, odczekujemy az ;uklad DS odblokuje magistrale
lcall reset ;te same standardowe kroki co powyzej-specyfikacja wymaga ;by kazdorazowo przed wydaniem
lcall obecnosc ;komendy ukladowi inicjowac go i dokonac selekcji ;ukladu ;wykorzystywanego do pracy
mov a, #skip_rom
lcall sent
mov a, #read_scratch ;wykorzystujemy teraz komende odczytu z pamieci ukladu, ;odczyt nastapi od bajtu 0, od lsb
lcall sent ;bit po bicie. nam potrzebne jest tylko odebranie dwoch ;pierwszych bajtow-nie sprawdzamy
lcall read ;poprawnosci przesylu(sumy kontrolnej). odczyt z termometru ;mozna w kazdej chwili
lcall reset ;przerwac przy uzyciu komendy reset, co niniejszym czynimy
lcall wyswietl ;podprogram odpowiedzialny za wyswietlenie wyniku -obecnie ;jedynie najprostsza forma-diody
jmp start
;///////////////////////////////////////////////////////////////////////////
z_alarmem:
lcall reset ;standardowa inicjacja programu
lcall obecnosc
mov a, #skip_rom
lcall sent
mov a, #write_scratch ;komenda zapisu do pamieci ukladu wartosci ;alarmowych ;temperatury, najpierw wartosc gorna
lcall sent ;nastepnie dolna. wysylane bit po bicie, rozpoczynajac od lsb
mov a, r4
lcall sent
mov a, r3
lcall sent
lcall reset ;ta sama procedura co w poprzednim przypadku az do ostatniego ;kroku w ktorym nastepuje
lcall obecnosc ;sprawdzenie wartosci granicznych i ewentualne ;przekroczenie zakresu termostatu
mov a, #skip_rom
lcall sent
mov a,#convert
lcall sent
lcall delay
lcall delay
lcall reset
lcall obecnosc
mov a, #skip_rom
lcall sent
mov a, #read_scratch
lcall sent
lcall read
lcall wyswietl
lcall reset
lcall obecnosc
mov a, #skip_rom
lcall sent
mov a, #alarm_search ;wyslasnie do ukladu komendy sprawdzajacej czy ktorys ;z ukladow nie wystawil flagi swiadczacej o ;przekroczeniu zakresu termostatu. jesli takowy sygnal ;zostal ustawiony
lcall sent ;otrzymamy potwierdzenie. W przypadku jednego ukladu ;podlaczonego do magistrali
lcall read_alarm ;wystarczy jesli odczytamy dwa pierwsze ;bity wyslane ;nam przez uklad, jesli ktorys z nich
;bedzie rowny jeden oznacza to, ze przekroczony zostal ;zakres mierzonej temperatury
cjne a, #00h, alarm ;sprawdzamy czy suma rowna jest zero, jesli tak mozemy ;dalej mierzyc, jesli nie pojawi
;sie sygnal alarmowy
jmp start
;/////////////////////////////////////////////////////////////////////////// /
reset: ;reset-zgodnie ze specyfikacja jest to sytuacja w ktorej uklad ;nadrzedny(master) ustawia
mov r7,#250 ;-zeruje magistrale na conajmniej 480 micro sekund. ;Zaden inny sygnal nie trwa tak dlugo
clr port ;zerujemy port, po czym wprowadzamy opoznienie ;rzedu~500 microsekund.
djnz r7,$
ret
;////////////////////////
obecnosc: ;w komendzie nastepujacej zawsze po resecie-obecnosc-; ;uwalniamy magistrale, uklad czeka od 15
setb port ;;do 60 mikros, po czym nadaje sygnal obecnosci, niski ;stan magistrali przez okres 60-240 microsekund. ;sprawdzamy po conajmniej 60 micro czy uklad nadaje ;sygnal potwierdzenia . nawet
mov r7, #32 ;jesli uklad czekal 15 micro a sam sygnal trwa 60 ;micro(razem 75) to po sprawdzeniu stanu
djnz r7,$ ;magistrali powinienen na niej byc sygnal niski. jesli go ;nie ma, jeszcze raz resetujemy uklad. jesli sygnal jest ;spokojnie czekamy az sie skonczy-z pewnym zapasem
jb port, reset
mov r7, #120
djnz r7,$
jnb port, $
ret
;////////////////////////
sent:
mov r1, #9 ;kazdorazowo wysylamy po
8 bitow(bajt), dlatego ;wystarczy sekwencje zapisu jednego bitu
kolo: ;powtorzyc 8 krotnie. Magistrala 1-wire umozliwia nam ;odczyt i zapis tylko po jednym bicie
djnz r1, wyslij ;sprawdzamy czy zapisalismy juz 8 bitow, jesli tak ;powracamy ;do programu, jesli nie zapisujemy dalej.
ret
wyslij: ;wyslanie pojedynczego bitu. kazde slowo do wyslania przed ;wywolaniem komendy wyslij jest
rrc a ;kopiowane do akumulatora. teraz do wyslania i sprawdzania ;bedzie uzywac przeniesienia
clr port ;akumulatora. dlatego tez obracamy akumulator w prawo z ;uzyciem przeniesienia, co przy 8 krotnym wejsciu do petli ;zapewnia nam wyslanie calego bajtu
jnc zero ;zerujemy port by zainicjowac wysylanie ramki. teraz w ;zaleznosci od tego czy wyslamy zero
mov r7, #30 ;czy jeden tak dlugo bedziemy utrzymywac odpowiedni stan ;magistrali. jesli jeden to szybko
setb port ;zwalniamy magistrale i przez okres probkowania trzymamy ja ;wysoka(uklad probkuje od 15 do 60
djnz r7,$ ;mikrosekundy po wykryciu opadajacego zbocza. jesli podczas ;probkowania wykryje wysoki stan
jmp kolo ;magistrali traktuje to jako jeden, etc. jesli bylo zero, to po ;conajmniej 60 mikro s uwalniamy magistrale. miedzy ;wyslaniem kolejnych bitow musi byc conajmniej 1 mikro s ;przerwy
zero:
mov r7,#30
djnz r7, $
setb port
jmp kolo
;///////////////////////
read:
mov a, #00h ;program odpowiedzialny za odczyt z ukladu. odczytujemy ;podobnie jak zapisujemy bit po bicie
mov r1, #9 ;w naszym przypadku czytamy tylko pierwsze 16 bitow, a wiec ;jedynie temperature, bardziej
petla1: ;znaczacy bajt to znak liczby, zas mniej to 7 bitowa liczba ;calkowita plus ulamek(0,5).
djnz r1, odbierz1 ;skok do funkcji odpowiedzialnej za odebranie pojedycznego ;bitu, wchodzimy do tej petli 8 razy, po odczytaniu bajtu ;kopiujemy zawartosc z akumulatora do rejestru r0. akumulator ;dalej
mov r0, a ;bedziemy uzywac
mov r1, #9
mov a, #00h
petla2:
djnz r1, odbierz2 ;tutaj na podobnej zasadzie co powyzej odczytujemy drugi bajt-;bardziej znaczacy.
mov r2, a
mov a, #00h
ret ;wracamy z podprogramu
odbierz1: ;po wydaniu polecenia odczytu master wydaje sygnal gotowosci ;do odczytu-opadajace zbocze.
clr port ;nastepnie w ciagu 15 mikro s musi uwolnic magistrale by uklad ;mogl ustawic ja zgodnie z
mov r7,#5 ;przesylanym sygnalem. zaleca sie jednak by czas w ktorym ;master zeruje sygnal byl jaknajmniejszy, tak by pozostawic ;margines czasu na ewentualne ustabilozwanie sie magistrali
setb port
djnz r7,$ ;ustawiamy magistrale, po uplywie okolo 10 mikrosekund od ;opadajacego zbocza odczytujemy
mov c, port ;stan magistrali.
rrc a ;przesuwamy akumulator w prawo z przeniesieniem(odczyt od ;lsb) tak by po 8 krotnym
jmp petla1 ;przesunieciu miec dobrze(zgodnie z wagami) odczytany bajt
odbierz2: ;funkcja analogiczna do powyzszej , z tym, ze odczytuje drugi ;bajt danych
clr port
mov r7,#5
setb port
djnz r7,$
mov c, port
rrc a
jmp petla2
;/////////////////////////
read_alarm: ;zasada dzialania identyczna jak ta w przypadku odczytu bajtow, ;z tym, ze tutaj wystarczy
mov r1, #3 ;nam odczyt tylko dwoch bitow.
kolo_alarmu:
djnz r1, odbierz_alarm
ret
odbierz_alarm:
clr port
mov r7,#4
setb port
djnz r7,$
mov c, port
rrc a
jmp kolo_alarmu
alarm:
lcall wyswietl_alarm ;jesli uklad wykryl przekroczenie zakresu wywolamy ;'alarm'-jakas sygnalizacje.
jmp start
;/////////////////////////////////////////////////////////////////////////// ////
wyswietl:
mov p5,r0
lcall delay
lcall delay
lcall delay
lcall delay
lcall delay
lcall delay
mov p5, r2
lcall delay
lcall delay
lcall delay
lcall delay
lcall delay
lcall delay
ret
delay:
djnz r7, delay
djnz r6, delay
ret
wyswietl_alarm:
;mov p5, #11001100b
lcall delay
lcall delay
lcall delay
ret
;/////////////////////////////////////////////////////////////////////////// /////
end