Vakti zamanında fantezi ürünü olan 12F675 ve LM35 termometre devresinin 3. versiyonunu yaptım. Sanırım bundan sonra geliştirmeye devam etmem. zaten yapacak birşeyde kalmadı.
Bayağı yenilikler yaptım diyebilirim.
Kaynak : http://www.sercanca.com/jalv2-12f675-lm35-termometre-v3/
Bu uygulama eğitim amaçlı olduğu için aşağıdaki konuların öğrenilmesinde yardımcı olacaktır. Özellikle tek pin ile shift register kullanımına real bir örnektir.
- Jalv2 dilinin temel kullanımı
- Jalv2 dilinde 12F675 kullanımı ve sigorta ayarları
- Jalv2 dilinde LM35 kullanımı ve sıcaklığın hesaplanması
- Jalv2 dilinde tek pin ile 74LS164 shift register kullanımı
- Shift register kullanarak port çoklama
- Shift register kullanarak 4 digit 7 segment display kullanımı
- Jalv2 dilinde 12F675 için ADC kullanımı
- Jalv2 dilinde 12F675 pinin giriş olarak kullanımı
- Jalv2 dilinde TMR0 kesmesinin kullanımı
- TMR0 kesmesi ile 7 segment sürülmesi
- 7 segment display yazı yazma ve kaydırma
(http://www.sercanca.com/wp-content/uploads/2018/06/Devre-semasi-1.png)
(http://www.sercanca.com/wp-content/uploads/2018/06/devre-test.png)
(http://www.sercanca.com/wp-content/uploads/2018/06/devre.png)
(http://www.sercanca.com/wp-content/uploads/2018/06/1-one-wire-shift.png)
(http://www.sercanca.com/wp-content/uploads/2018/06/2-74LS164-One-wire.png)
Çalışma Videosu
--------------------------------------------------------------------------------
-- Program : 12F675-LM35 4x7 segmentli Termometre
-- Author : Sercan TEK - Turkey/Tekirdağ
-- www.sercanca.com
-- Version : v3
-- Date : 2018 Haziran
-- chip : 12F675 ve 74hc164
-- compiler : jal jalv24q6 (compiled Oct 25 2016)
-- derleme : 23.06.2018
--
-- Güncelemeler :
-- 1) - 4lü 7 segment kullanıldı.
-- 2) - Tarama işlemi TMR0 Kesmesi ile yapıldı.
-- 3) - Shift Register entegresi Tek pin ile kullanıldı.
-- 4) - Celsius to Fahrenheit seçimi eklendi.
-- 5) - Yeni animasyonlar eklendi.
-- 6) - Başlangıca Kayan Yazı Eklendi.
-- 7) - Algoritmasal İyileştirme Yapıldı.
--
--------------------------------------------------------------------------------
include 12f675
pragma target clock 4_000_000 -- kristal 4 Mhz
pragma target OSC INTOSC_NOCLKOUT -- dahili OSC
pragma target WDT disabled -- watchdog Kapalı
pragma target MCLR INTERNAL -- mclr kullanılmıyor
pragma target CP ENABLED -- Kod Koruma açık
enable_digital_io()
pin_A0_direction = input -- LM35
pin_A1_direction = output -- Display Data
pin_A2_direction = output -- Display 3
pin_A3_direction = input -- animasyon seçeği
pin_A4_direction = output -- Display 1
pin_A5_direction = output -- Display 2
alias display_data is pin_a1
alias Birim_sec is pin_a3
alias D1_Etkin is pin_a4
alias D2_Etkin is pin_a5
alias D3_Etkin is pin_a2
const byte digit[]={0b11111100, -- 0
0b01100000, -- 1
0b11011010, -- 2
0b11110010, -- 3
0b01100110, -- 4
0b10110110, -- 5
0b10111110, -- 6
0b11100000, -- 7
0b11111110, -- 8
0b11110110} -- 9
const byte yazi[] ={0 ,
0 ,
0 ,
0b11001110, -- P
0b01100000, -- 1
0b10011100, -- C
0b01100000, -- 1
0b11011010, -- 2
0b10001110, -- F
0b10111110, -- 6
0b11100000, -- 7
0b10110110, -- 5
0,
0b00011100, -- L
0b10101000, -- M
0b11110010, -- 3
0b10110110, -- 5
0,
0b01111000, -- J
0b11101110, -- A
0b00011100, -- L
0b11011010, -- 2
0,
0b10110110, -- S
0b01100000, -- I
0b10011100, -- C
0b11101110, -- A
0b10101110, -- K
0b00011100, -- L
0b01100000, -- I
0b10101110, -- K
0,
0b10111010, -- ö
0b00011100, -- L
0b10011100, -- C
0b10011110, -- E
0b11001100, -- R
0 ,
0b10110110, -- S
0b10011110, -- E
0b11001100, -- R
0b10011100, -- C
0b11101110, -- A
0b11101100, -- N
0b10011100, -- C
0b11101110, -- A
0b00010000, -- -
0b10011100, -- C
0b11111100, -- O
0b10101000, -- M
0 ,
0 ,
0 }
var byte Data[] = {0,0,0,0} -- Display Dataları burada tutulur
var byte Display = 0
var byte anime = 0
var byte Birimi = 0
var bit oku = false
--------------------------------------------------------------------------------
-- 12F675 için AN0 pinindeki Analog değeri okuma fonksiyonu
-- Geri dönüş değeri word tipindedir.
--------------------------------------------------------------------------------
ADCON0_CHS0 = false -- Kanal AN0 Seçildi
ADCON0_CHS1 = false
ADCON0_VCFG = false -- Harici Vref yok
ADCON0_ADFM = true -- Sonuc Sağa yaslansın
ANSEL_ADCS = 0b_001 -- ADC Çevrim Clock Seçeneği = OSC/8
function adc_oku return word is
pragma inline
ADCON0_ADON = True
_usec_Delay(2000)
ADCON0_GO = true
while ADCON0_GO loop end loop
return ((ADRESH<<8)+ADRESL)
end function
--------------------------------------------------------------------------------
-- Verilen parametreye göre ms gecikmesi yapar
--------------------------------------------------------------------------------
procedure gecikme(byte in ms) is
for ms loop
_usec_delay(986)
end loop
end procedure
--------------------------------------------------------------------------------
-- 74LS164 için Tek Hattan veri gönderimini sağlar.
--------------------------------------------------------------------------------
procedure bekle20us is -- 20 mikrosaniye gecikme sağlar
_usec_delay(18)
end procedure
procedure Data_Bas(byte in _Data) is
pragma inline
var bit v_bit at _Data : 0 -- 0. biti ata
for 8 loop -- 8 bit olduğu için 8 kez dön
if v_bit == high then -- Bit : 1 ise
display_data = low asm nop -- 0 gönder, 1us Bekle
display_data = high bekle20us -- 1 gönder, 20us Bekle
else -- Bit : 0 ise
display_data = low bekle20us -- 0 gönder, 20us bekle
display_data = high bekle20us -- 1 gödner, 20us bekle
end if
_Data = _Data >> 1 -- Datayı 1 bit sağ kaydır
end loop
end procedure
--------------------------------------------------------------------------------
-- Dataları Displaylere yollar
--------------------------------------------------------------------------------
procedure display_yolla(byte in seg7) is
pragma inline
var byte v_Data = Data[seg7]
var bit D4_Etkin at v_Data : 0
D1_Etkin = false D2_Etkin = false
D3_Etkin = false D4_Etkin = false
Data_Bas(0)
if (seg7 == 3) then
Data_Bas(0)
D4_Etkin = true
end if
Data_Bas(v_data)
case seg7 of
0 : D1_Etkin = true
1 : D2_Etkin = true
2 : D3_Etkin = true
end case
end procedure
--------------------------------------------------------------------------------
-- Her 20 okumadan sonra oynayan animasyon
--------------------------------------------------------------------------------
procedure anime_kapanip_acil is
const byte a[] = {0b00001110,0b00000010,0b00000010,0b01100010,
0b01100000,0b00000010,0b00000010,0b00001100,
0b00000000,0b00001110,0b01100010,0b00000000,
0b00000000,0b01100000,0b00001100,0b00000000}
var byte dongu,sira
-- içe kapanma efekti
for 4 using dongu loop
sira = dongu * 4
Data[0] = a[sira]
Data[1] = a[sira+1]
Data[2] = a[sira+2]
Data[3] = a[sira+3]
Gecikme(150)
end loop
-- dışa açılma efekti
for 4 using dongu loop
sira = dongu * 4
Data[0] = a[15-sira-3]
Data[1] = a[15-sira-2]
Data[2] = a[15-sira-1]
Data[3] = a[15-sira]
Gecikme(150)
end loop
end procedure
--------------------------------------------------------------------------------
--Analog girişten okunan değeri sıcaklık bilgisine çeviren alt program
--------------------------------------------------------------------------------
procedure LM35_oku is
var word sicaklik = 0
var bit birim_durumu = false
var byte isaret,sonuc[] = {0,0,0}
-- verilen değer kadar sıcaklığı okur ve ortalamasını alır.
const ortalama = 50
for ortalama loop
if oku then sicaklik = sicaklik + (((adc_oku)*60)/124) end if
end loop
-- celsius sinsinde sıcaklık
sicaklik = sicaklik / ortalama
-- fahrenheit cinsine dönüşüm.
if Birim_sec == false then
-- celsius(0,100) = fahrenheit(32,212) göre orantı kuruldu.
sicaklik = (sicaklik - 0) * (212 - 32) / (100 - 0) + 32
isaret = yazi[8] -- F
else
isaret = yazi[5] -- C
end if
birim_durumu = false
anime = anime + 1
Birimi = Birimi + 1
if anime == 50 then
anime_kapanip_acil
anime = 0
Birimi = 0
end if
sonuc[0] = digit[byte((sicaklik / 100))] -- yüzler
sonuc[1] = digit[byte((sicaklik % 100)/10)] -- onlar
sonuc[2] = digit[byte((sicaklik % 100)% 10) ] -- birler
Data[2] = 198 -- *
Data[3] = isaret -- F - C
-- 0 ve altı olan derecelerde -0*C göstersin
if (sicaklik <= 0) then
Data[0] = 2 -- -
Data[1] = digit[0] -- 0
-- 0..9 arası ise "*C" sembolünü kullan
elsif (sicaklik < 10) then
Data[0] = 0
Data[1] = sonuc[2]
-- 10 ile 99 arasında ise "*" sembolünü kullan
elsif (sicaklik <= 99) then
Data[0] = sonuc[1]
Data[1] = sonuc[2]
-- 99 dan büyük ise tüm segmentleri kullan
elsif (sicaklik > 99) then
Data[0] = sonuc[0]
Data[1] = sonuc[1]
Data[2] = sonuc[2]
Data[3] = 198 -- *
birim_durumu = true
end if
if birim_durumu then
if Birimi == 20 then
for 3 loop
for 2 loop
Data[3] = 198 -- *
gecikme(200)
gecikme(200)
Data[3] = 0
gecikme(200)
end loop
Data[3] = isaret
for 4 loop
gecikme(250)
end loop
end loop
Data[3] = 198 -- *
Birimi = 0
end if
end if
end procedure
--------------------------------------------------------------------------------
-- ilk açılış yazısını yazan alt program
--------------------------------------------------------------------------------
procedure yazi_yaz is
var byte adet,sira
for count(yazi)-3 using adet loop
Data[0] = yazi[adet]
Data[1] = yazi[adet+1]
Data[2] = yazi[adet+2]
Data[3] = yazi[adet+3]
Gecikme(160)
Gecikme(160)
end loop
end procedure
--------------------------------------------------------------------------------
-- Anime için görselleri Data Dizisine Aktarır
--------------------------------------------------------------------------------
procedure Aktar(byte in veri,Byte in Ekran) is
Data[0] = 0 Data[1] = 0
Data[2] = 0 Data[3] = 0
Data[Ekran] = veri
Gecikme(65)
end procedure
--------------------------------------------------------------------------------
-- ilk açılış animasyon alt programı 2
--------------------------------------------------------------------------------
procedure Boot is
pragma inline
var byte d
oku = true
LM35_oku
for 2 loop
for 4 using d loop
Aktar(0b10000000,d) -- üst sıra gez
end loop
Aktar(0b01000000,3) -- ortaya geç
for 4 using d loop
Aktar(0b00000010,3-d) -- orta sıra gez
end loop
Aktar(0b00001000,0) -- en alta geç
for 4 using d loop
Aktar(0b00010000,d) -- en alt gez
end loop
Aktar(0b00100000,3) -- ortaya geç
for 4 using d loop
Aktar(0b00000010,3-d) -- orta sıra gez
end loop
Aktar(0b00000100,0) -- üste geç
end loop
yazi_yaz
anime_kapanip_acil
end procedure
--------------------------------------------------------------------------------
-- Kesme Alt Programı
--------------------------------------------------------------------------------
-- Prescaler=32 - TMR0Preset=130 - Freq=248.02 Hz - Period=0.004032 seconds
const _TMR0 = 130
OPTION_REG_T0CS = false -- Clock palsi kaynağı olarak dahili osilatör seçildi.
OPTION_REG_T0SE = false
OPTION_REG_PSA = false -- Prescaler değeri Timer0 için kullanılacak.
OPTION_REG_PS2 = true -- Prescaler değeri 1:32 olarak seçildi.
OPTION_REG_PS1 = false
OPTION_REG_PS0 = false
INTCON_GIE = true -- tüm kesmelere izin verdik.
INTCON_TMR0IF = false -- Kesme bayrağını sıfırladık
TMR0 = _TMR0 -- 4 ms de bir kesme oluşturacak değer yükleniyor.
INTCON_TMR0IE = true -- Timer0 kesmesini aktif edildi
Boot
--------------------------------------------------------------------------------
-- Ekranı Tarama Alt Programı
--------------------------------------------------------------------------------
procedure Ekran_Tarama is
pragma interrupt -- Kesme Alt Programları
if (INTCON_TMR0IF) then -- TMR0 Kesmesi İse
Display_yolla(Display)
Display = (Display - 1) % 4
TMR0 = _TMR0
INTCON_TMR0IF = false -- TMR0 Kesmesinin Bayrağını
end if -- sıfırla
end procedure
forever loop
LM35_oku -- LM35 Oku
_usec_delay(2_000_000) -- 2sn Bekle
end loop
Not: eleştiriye ve fikir alışverişine açıktır.
ben bu devreyi zamanında yapmıştım gayet kararlı ve düzgün çalışıyor taviye ederim yapmayı düşünenlere...
Alıntı yapılan: yılmaz_34 - 23 Haziran 2018, 11:27:02ben bu devreyi zamanında yapmıştım gayet kararlı ve düzgün çalışıyor taviye ederim yapmayı düşünenlere...
Sizinki v1 yada v2 olan modeliydi. Bunu yeni geliştirdim ve 4digitli yaptım.
Kullanılan sensör ne kadar iyi ise Sonuç o kadar iyi oluyor. Piyasadan aldığım ucuz lm35 var elimde çıkışlari çok dengesiz. Ucuz etin yahnisi misali.
Alıntı yapılan: SercanTEK - 23 Haziran 2018, 12:30:09Sizinki v1 yada v2 olan modeliydi. Bunu yeni geliştirdim ve 4digitli yaptım.
Kullanılan sensör ne kadar iyi ise Sonuç o kadar iyi oluyor. Piyasadan aldığım ucuz lm35 var elimde çıkışlari çok dengesiz. Ucuz etin yahnisi misali.
doğrudur eski sürümdü ama ona rağmen güzel ve hoş bir devre olmuştu...