12F675-LM35 Termometre v3

Başlatan ByTEK, 23 Haziran 2018, 02:09:40

ByTEK

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












Ç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.

yılmaz_34

ben bu devreyi zamanında yapmıştım gayet kararlı ve düzgün çalışıyor taviye ederim yapmayı düşünenlere...
İnsan yazdığını silerde ,yaşadığını silemez içinden.....

ByTEK

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.

yılmaz_34

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...
İnsan yazdığını silerde ,yaşadığını silemez içinden.....