Translate

Peraga Jadual Sholat 3



Bagian Ketiga

Sebagai lanjutan dari serial tulisanku tentang peraga jadual Sholat, tapi jangan dianggap seperti sinetron ya, he...he. Sebelumnya sudah dipaparkan mengenai data informasi jadual sholat pada bagian pertama dan rangkaiannya dengan teknik peragaan LED 7 segmen secara scanning, maka kali ini dibagian ketiga akan dilanjutkan mengenai fasilitas KONTROL yang akan dikembangkan untuk pengaturan waktu.

Tapi sebelumnya aku akan menampilkan contoh tata letak LED 7 segmen dari tampilan peraga, sekedar ide saja karena mungkin Sobat memiliki ide lainnya yang lebih disukai.



Gambar di atas hanya contoh tampilan yang terjadi pada tanggal 14 Agustus 2012, pukul 03:54:27 dini hari. Ada 2 digit permanen yaitu untuk menampilkan bilangan tahun yaitu 20 yang tidak dihasilkan dari keluaran program atau mikrokontroler.

Kita lanjutkan pembahasan tentang penggunaan CN104 yang berfungsi sebagai kendali masukan. Konektor ini dapat dihubungkan dengan rangkaian seperti ditunjukkan di bawah ini:



Gerbang P30 dan P31 dari mikrokontroler dapat dimanfaatkan sebagai sarana komunikasi dengan PC yang dihubungkan pada port serial RS232. Agar fasilitas tersebut berfungsi, nanti akan kita rancang bersama program aplikasinya.

Sementara itu gerbang P32 dan P33 dihubungkan dengan sakelar tekan S101 untuk PRG dan S102 untuk SET yang nanti akan difungsikan sebagai fasilitas pengaturan waktu dari RTC. Karena kita pasti sama-sama memahami bahwa informasi waktu dari RTC sangat perlu diatur jika tidak sesuai dengan waktu sebenarnya.

Kita mulai dari penggunaan sakelar PRG dan SET sebagai fasilitas pengaturan waktu. Sebelum membuat atau merancang aplikasinya, terlebih dahulu kita harus menetapkan apa dan bagaimana fungsi dari kedua sakelar tersebut. Sakelar PRG akan ditetapkan untuk memilih informasi data waktu yang akan diatur yaitu jam, menit, tanggal, bulan atau tahun. Sementara sakelar SET untuk mengubah nilai dari informasi data tersebut.

Cara kerjanya adalah sebagai berikut:

Pada keadaan normal, seluruh digit penunjuk waktu baik jam, menit, detik, tanggal, bulan dan tahun akan ditampilkan seperti gambar di atas. Menekan sakelar PRG akan diproses oleh mikrokontroler dengan hanya menampilkan menit saja untuk memasuki mode pengaturan menit. Penekanan sakelar PRG pada kali kedua akan menampilkan hanya jam saja, penekanan ketiga untuk tanggal, keempat untuk bulan, kelima untuk tahun dan penekanan keenam akan mengembalikan peraga pada kondisi semula atau normal.

Pada keadaan normal, menekan sakelar SET tidak akan diproses dan tidak berpengaruh. Namun pada mode pengaturan jam, menit, tanggal, bulan atau tahun maka menekan sakelar SET akan mengusah nilai informasi sesuai posisi mode. Jika pada mode pengaturan jam maka nilai jam akan dinaikkan. Contoh ketika posisi menit menunjuk 03 seperti di atas, maka menekan SET akan mengubah nilai jam menjadi 04, penekanan berikutnya menjadi 05 dan seterusnya sampai ditemui waktu jam yang sesuai.

Jika sakelar SET ditekan dan ditahan maka data akan berotasi ke arah naik dengan kecepatan kurang lebih setengah detik.

Pengaturan akan mengubah nilai waktu dengan rentang berdasarkan dengan format yang sesuai, yaitu:

§  Jam berisi nilai antara 00 sampai 23.
§  Menit berisi nilai antara 00 sampai 59.
§  Pengaturan Tanggal agak kompleks di mana bisa berisi nilai antara 01 sampai 31 (Januari, Maret, Mei, Juli, Agustus, Oktober dan Desember), berisi nilai 01 sampai 30 (April, Juni, September dan November). Sementara untuk Februari maka tanggal bisa berisi 01 sampai 29 untuk tahun kabisat dan 01 sampai 28 untuk selain tahun kabisat.
§  Bulan berisi nilai antara 01 sampai 12.
§  Tahun berisi nilai antara 00 sampai 99, namun aku batasi antara 12 sampai 25 saja.

Mode pengaturan juga akan kita otomatisasi dengan timer di mana jika pada mode tertentu yang terpilih dan kita tidak melanjutkan penekanan salah satu sakelar baik PRG maupun SET maka dalam 10 detik mikrokontroler akan mengembalikan posisi program pada keadaan normal.

Nah, berikut akan kita buat aplikasinya sebagai tambahan dari aplikasi program yang sudah dibuat sebelumnya. Pada area konfigurasi kita perlu menambahkan parameter berikut ini:

PB_PRG      bit   p3.2
PB_SET      bit   p3.3

BitMenu     bit   RegBit.3

Kemudian pada rutin Periksa_Waktu baris perintah “JNB PB_PRG, Menu_PRG” akan disisipkan seperti diperlihatkan berikut ini:

Periksa_Waktu:
      jnb   PB_PRG, Menu_Waktu
      djnz  r5, Periksa_Detik
      mov   r5, #255   
      --- dst ---

Baris perintah pertama di atas untuk memeriksa status masukan dari sakelar S101 PRG. Jika ditekan maka logika masukan gerbang akan menjadi rendah dan program akan menjalankan rutin berikut:

Menu_Waktu:
      mov   r2, #0

Untuk program pengaturan, kita akan menggunakan register R2 untuk status menu yang dipilih. Register lainnya yang digunakan adalah Register B, R0 dan R1. Setiap kali rutin Menu_Jam dijalankan maka nilai register R2 akan bertambah untuk menentukan menu yang akan dikerjakan. Isi register R0, R1 dan register B akan digunakan pada program menu.

      Menu_Jam:
            inc   r2
            cjne  r2, #1, Menu_Menit
            mov   r1, #BufDisplay
            mov   r0, #BufWaktu+2
            mov   b, #23h
            ajmp  Prog_Menu

      Menu_Menit:
            cjne  r2, #2, Menu_Tanggal
            mov   r1, #BufDisplay+2
            mov   r0, #BufWaktu+1
            mov   b, #59h
            ajmp  Prog_Menu

Khusus untuk Menu_Tanggal, maka nilai register B perlu dilakukan verifikasi karena perbedaan jumlah hari dalam setiap bulan termasuk adanya tahun kabisat. BitMenu juga akan diset menjadi tinggi untuk keperluan penetapan nilai tersendah saat rotasi data.

      Menu_Tanggal:
            cjne  r2, #3, Menu_Bulan
            setb  BitMenu
            mov   r1, #BufDisplay+6
            mov   r0, #BufWaktu+4
            acall Bulan_01
            ajmp  Prog_Menu

      Menu_Bulan:
            cjne  r2, #4, Menu_Tahun
            mov   r1, #BufDisplay+8
            mov   r0, #BufWaktu+5
            mov   b, #12h
            ajmp  Prog_Menu

      Menu_Tahun:
            cjne  r2, #5, Menu_Selesai
            mov   r1, #BufDisplay+10
            mov   r0, #BufWaktu+6
            mov   b, #25h

Setelah penetapan salah satu dari 5 mode pengaturan di atas, selanjutnya aplikasi menu akan diproses. Hal pertama yang akan diproses adalah memanggil subrutin Display_Menu. Kemudian menyiapkan register R3, R6 dan R7 untuk penundaan kira-kira selama 10 detik melalui rutin Reset_Mnu2. Status PB_PRG dan PB_SET diperiksa pada rutin Prog_Mnu1, jika keduanya bernilai tinggi yang berarti baik sakelar PRG maupun SET tidak ditekan maka delay akan berjalan.

            Prog_Menu:
                  acall Display_Menu
                  jnb   PB_PRG, $

            Reset_Mnu1:
                  mov   r3, #36
                  mov   r6, #255
                  mov   r7, #255

            Reset_Mnu2:
                  djnz  r7, Prog_Mnu1
                  mov   r7, #255
                  djnz  r6, Prog_Mnu1
                  mov   r6, #255
                  djnz  r3, Prog_Mnu1
                  ajmp  Periksa_Waktu

            Prog_Mnu1:
                  jnb   PB_PRG, Menu_Jam
                  jb    PB_SET, Reset_Mnu2
                  mov   r3, #14
                  mov   r6, #255
                  mov   r7, #255

Register R3, R6 dan R7 juga digunakan untuk pengaturan secara otomatis nilai informasi waktu jika PB_SET rendah secara terus menerus atau ditahan. Kecepatan rotas kurang lebih per-setengah detik. Contoh untuk menu Jam maka nilai akan berubah dari 0 sampai 23 kemudian kembali lagi ke 0 dan seterusnya. Proses rotasi data dilakukan pada subrutin Ubah_Waktu.

            Prog_Mnu2:
                  acall Ubah_Waktu

            Prog_Mnu3:
                  jb    PB_SET, Reset_Mnu1
                  djnz  r7, Prog_Mnu3
                  mov   r7, #255
                  djnz  r6, Prog_Mnu3
                  mov   r6, #255
                  djnz  r3, Prog_Mnu3
                  mov   r3, #3
                  ajmp  Prog_Mnu2

      Menu_Selesai:
            cjne  r2, #6, Menu_Kembali
            clr   BitMenu
            ajmp  Periksa_Waktu

      Menu_Kembali:
            ajmp  Menu_Jam

Seperti kita ketahui bahwa jumlah hari dalam 1 bulan tidak sama ada yang berjumlah 31 dan 30, sementara bulan februari bahkan 28 hari dan pada tahun kabisat menjadi 29. Subrutin berikut menetapkan nilai tanggal sesuai dengan bulan dan tahun yang bersesuaian.

Mula-mula nilai akumulator digunakan untuk menyimpan informasi bulan. Kecuali bulan Februari maka setiap bulan akan dibandingkan untuk menentukan jumlah hari 30 dan 31.

Bulan_01:
      mov   a, BufWaktu+5
      cjne  a, #1, Bln03
      ajmp  Hari31

      Bln03:
            cjne  a, #3, Bln04
            ajmp  Hari31

      Bln04:
            cjne  a, #4, Bln05
            ajmp  Hari30

      Bln05:
            cjne  a, #5, Bln06
            ajmp  Hari31

      Bln06:
            cjne  a, #6, Bln07
            ajmp  Hari30

      Bln07:
            cjne  a, #7, Bln08
            ajmp  Hari31

      Bln08:
            cjne  a, #8, Bln09
            ajmp  Hari31

      Bln09:
            cjne  a, #9, Bln10
            ajmp  Hari30

      Bln10:
            cjne  a, #10h, Bln11
            ajmp  Hari31

      Bln11:
            cjne  a, #11h, Bln12

      Hari30:
            mov   b, #30h
            ret

      Bln11:
            cjne  a, #12h, Bln02

      Hari31:
            mov   b, #31h
            ret

Untuk bulan Februari, giliran register B yang digunakan untuk menyimpan informasi tahun. Register R3 dan akumulator digunakan untuk melacak tahun. Sepintas register R3 dan akumulator sepertinya mirip namun informasi yang disimpan sesungguhnya berbeda dimana register R3 untuk nilai dalam bilangan biner sementara akumulator dalam format BCD sesuai dengan format yang disimpan pada register B.

      Bln02:
            mov   b, BufWaktu+6
            clr   a
            mov   r3, #0

Tahun kabisat adalah jumlah tahun yang habis jika dibagi dengan 4. Untuk menghindari pembagian bilangan 0 maka jumlah tahun dalam biner yang disimpan oleh register R3 akan ditambahkan dengan 4. Setelah nilai minimal dari akumulator adalah 4 kemudian dilakukan pembagian dengan 4. Jika sisa pembagian pada register B bernilai 0 berarti merupakan tahun kabisat.

            Thn1: cjne  a, b, Thn2
                  mov   a, r3
                  mov   b, #4
                  add   a, b
                  div   ab
                  xch   a, b
                  jz    Kabisat
                  mov   b, #28h
                  ret

            Kabisat:
                  mov   b, #29h
                  ret

            Thn2: inc   r3
                  mov   a, r3
                  clr   ac
                  clr   c
                  da    a
                  ajmp  Thn1

Pengaturan data waktu terbagi menjadi 2 bagian dalam penentuan nilai terendah saat reset di mana untuk jam dan menit adalah 0. Sementara untuk tanggal dan bulan adalah 1. Pemilihan tersebut ditentukan oleh nilai dari BitMenu. Khusus untuk tahun maka aku sengaja sisipkan pembatasan minimal saat rotasi adalah 12.

Ubah_Waktu:
      jb    BitMenu, Ubah_Wkt1
      mov   a, @r0
      cjne  a, b, Ubah_Wkt2
      mov   a, #0
      ajmp  Ubah_Wkt2

      Ubah_Wkt1:
            mov   a, @r0
            cjne  a, b, Ubah_Wkt2
            mov   a, #1
            cjne  r2, #6, Ubah_Wkt2
            mov   a, #12h

            Ubah_Wkt2:
                  inc   a
                  clr   ac
                  clr   c
                  da    a
                  mov   @r0, a
                  push  b
                  mov   a, r0
                  clr   c
                  subb  a, #BufWaktu
                  xch   a, b
                  mov   a, #1
                  acall DS1307_Write
                  pop   b
                  acall Display_Menu
                  ret

Tampilan menu berbeda dengan saat normal di mana hanya informasi waktu yang akan diatur saja yang akan ditampilkan pada LED 7 segmen. Untuk itu seluruh data digit akan dibersihkan dengan mengisi masing-masing dengan data 255 atau FFH sehingga akan menyebabkan seluruh LED 7 segmen padam. Setelah seluruh LED padam maka hanya informasi waktu yang akan diatur saja yang akan ditampilkan pada subrutin Display_Prog.

Display_Menu:
      push  b
      push  01h
      push  0h
      mov   r7, #18
      mov   r0, #BufDisplay

      Bersihkan_Digit:
            mov   @r0, #255
            inc   r0
            djnz  r7, Bersihkan_Digit
            pop   0h

      Display_Prog:
            mov   a, @r0
            acall Display_BCD
            pop   01h
            pop   b
            ret

Sampai di sini aplikasi program menu pengaturan untuk perangkat Peraga Jadual Sholat sudah selesai. Perangkat sudah dilengkapi dengan mode pengaturan untuk mengubah informasi agar sesuai.



Sudah ya, terima kasih sudah membaca artikel aku. Semoga bermanfaat dan bisa diterapkan oleh sobat semua.

Salam....

Peraga Jadual Sholat 2



Bagian Kedua

Pada bagian pertama kita sudah melihat jadual waktu Sholat yang merupakan data referensi bagi perangkat yang akan dibuat pada bagian ini. Pada bagian kedua, kita akan melihat rangkaian secara lengkap dari penampil jadual Sholat yang akan dibuat.

Hal pertama yang terpikir oleh penulis adalah konsep yang akan digunakan untuk menampilkan digit waktu. Mengapa ini perlu dipertimbangkan pertama kali? Jelas perlu, karena kita harus menetapkan bagian dari waktu dan jadwal yang akan ditampilkan melalui peraga LED 7 segmen.

Yang jelas jadual waktu Sholat dan terbit akan ditampilkan maka dari itu setidaknya kita membutuhkan 24 digit. Sementara untuk penunjuk waktu dengan format HHMMSS serta tanggal DDMMYY maka diperlukan 12 digit lagi. Total LED 7 segmen yang diperlukan adalah 36 digit.

Seperti pernah aku tulis pada artikel sebelumnya mengenai teknik mengoperasikan LED 7 segmen, di mana ada 2 cara yaitu dengan teknik scanning dan buffering. Masing-masing memiliki kelebihan dan kekurangan.

Dari sisi perangkat keras maka teknik scanning jelas lebih sedikit memerlukan komponen dibanding dengan teknik buffering yang membutuhkan sebuah kemudi latch untuk tiap digit LED 7 segmen.

Dari sisi perangkat lunak, jelas teknik buffering sedikit lebih sederhana ketimbang teknik scanning yang memerlukan waktu ekstra bagi mikrokontroler untuk menampilkan data pada LED 7 segmen.

Dari sisi tampilan maka teknik buffering lebih terlihat stabil tanpa ada kedipan, berbeda dengan teknik scanning yang harus menggilir setiap digit untuk ditampilkan. Berdasarkan pengalaman penulis, maka pada teknik scanning setidaknya membutuhkan kecepatan scanning hingga 100Hz atau lebih untuk menjamin tampilan tidak terlalu tampak berkedip.

Pada teknik scanning, siklus LED tidak 100% tetapi bergantung banyaknya digit yang dirotasikan. Untuk 36 digit maka hasilnya adalah daur aktif LED di bawah 2,7% bahkan mungkin hanya 2,5%. Dengan frekuensi 100Hz, total perioda 1 putaran adalah 10 ms sehingga masing-masing digit hanya aktif dalam 250us.

Lalu teknik penampil LED 7 segmen yang manakah yang akan digunakan?

Tidak usah kuatir, penulis akan menyampaikan kedua teknik tersebut. Namun pada bagian ini yang akan disampaikan adalah penampil jadual Sholat dengan teknik scanning terlebih dahulu.

Komponen utama yang digunakan adalah mikrokontroler jenis AT89C51 atau AT89S51 dari keluarga MCS51. Untuk RTC-RAM dapat menggunakan DS1307 dan untuk memori penyimpanan data waktu Sholat menggunakan AT24C512 di mana keduanya sama-sama memiliki antarmuka I2C.

Mikrokontroler AT89C51 memiliki 4 byte gerbang yakni P0, P1, P2 dan P3. Aku akan melakukan proses scanning ganda dari ke 36 digit menggunakan P0 dan P1 yang dihubungkan ke Anoda LED 7 segmen sehingga masing-masing gerbang mengoperasikan 18 digit. Sementara P2 digunakan untuk scanning alamat digit sebanyak 18 bit. Dengan demikian kita bisa menghemat penggunaan komponen 74LS138 menjadi cukup 3 buah saja.

Sekarang kita bisa mendapatkan daur aktif LED mencapai 5,5% dengan perioda ON masing-masing digit kurang lebih 500us.

Biar gampang sebelum dilanjutkan oborolannya, kita lihat rangkaian utamanya aja yuk!


Anoda dari setiap LED 7 segmen dihubungkan langsung pada CN101 dan CN102 yang masing-masing terhubung ke gerbang P0 dan P1 dan setiap kelompok terhubung secara paralel. Karena secara internal setiap keluaran gerbang memiliki pembatas arus sebesar 20mA maka kita tidak memerlukan tambahan resistor yang dihubungkan seri dengan LED.

Pada gambar di atas, untuk keperluan scanning menggunakan 74LS138 sebuah dekoder/demultiplekser 1 ke 8. Pengalamatan yang dibutuhkan adalah 18 bit saja dari 24 bit yang disediakan. Karena kita akan membagi 36 digit yang ditampilkan menjadi 2 bagian dengan masing-masing 18 digit. Alokasi ke 36 digit sesuai pengalamatan dari 74LS138 menjadi seperti berikut ini:

Alokasi Pengalamatan Dari Gerbang P2 Terhadap P0
00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
Detik
Menit
J a m
Tanggal
Bulan
Tahun
J a m
Menit
J a m
Penunjuk Waktu
Penunjuk Penanggalan
S h u b u h
Terbit

Alokasi Pengalamatan Dari Gerbang P2 Terhadap P1
00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
10
11
Menit
J a m
Menit
J a m
Menit
J a m
Menit
J a m
Menit
Terbit
D z u h u r
A s h a r
M a g h r i b
I  s  y  a

Untuk dapat menggerakkan LED maka keluaran dari 74LS138 masih memerlukan tambahan rangkaian berupa penggerak menggunakan transistor. Rangkaian penggerak tersebut dapat dilihat di bawah ini:


Keluaran dari 74LS138 menurut datasheet mampu mendayai hingga 8mA. Setiap transistor pada keadaan maksimal harus mampu memberikan arus sebesar 280mA dengan kondisi di mana setiap LED 7 segmen yang didayainya menunjukkan angka 8 atau seluruh LED menyala. Jika hFE dari transistor adalah 100 maka nilai resistor 1k5 adalah cukup untuk arus kemudi basis sebesar 2mA. Namun nilai tersebut bisa diturunkan sampai dengan 1k.

Berikut adalah aplikasi dasar yang minimal harus diisikan ke mikrokontroler. Aplikasi yang ditulis di bawah belum dilengkapi dengan rutin yang berhubungan dengan CN104 atau KONTROL yaitu fasilitas komunikasi serial dan pengaturan waktu secara manual.

Seperti biasa, penulisan program diawali dengan konfigurasi baik saluran gerbang maupun register atau RAM dari AT89C51 yang digunakan.

$mod51

PortDsp1    data  p0
PortDsp2    data  p1
PortDigit   data  p2

SCL         bit   p3.6
SDA         bit   p3.7

RegDetik    data  08h
RegDigit    data  09h
RegDsp1     data  0ah
RegDsp2     data  0bh
BufWaktu    data  0ch
BufJadwal   data  14h

RegBit      data  20h
      FSRDY       bit   RegBit.0
      FACK        bit   RegBit.1
      FLB         bit   RegBit.2

BufDisplay  data  27h
RegStack    data  50h

org   0h
      mov   sp, #RegStack-1
      mov   r4, #1
      mov   r5, #1
      ajmp  Periksa_Waktu

Setelah menuliskan beberapa perintah persiapan berupa penetapan register yang diperlukan dan melompat ke rutin Periksa_Waktu, maka disisipkan program berikut pada alamat 000BH yang merupakan alamat interupsi timer. Program ini digunakan untuk menampilkan peragaan pada LED 7 segmen secara scanning.

Jika dicermati, program berikut terbagi dalam 2 bagian yang ditentukan oleh nilai register R4. Saat R4 bernilai 1 maka program akan menjalankan perintah menampilkan data pada peraga. Program menjalankan perintah yang berkaitan dengan keluaran pada gerbang-gerbang seperti PortDigit, PortDsp1 dan PortDsp2. Perintah pada bagian ini membutuhkan waktu proses sekitar 25 siklus.

Kenapa aku tuliskan mengenai siklus mesin di atas? Nanti akan dijelaskan setelah beberapa paragraf di bawah ini.

org   0bh
      push  00h
      push  01h
      push  acc
      mov   r5, #5
      djnz  r4, Scan_Display
      mov   r4, #2
      mov   PortDigit, #255
      mov   PortDsp1, RegDsp1
      mov   PortDsp2, RegDsp2
      mov   PortDigit, RegDigit
      pop   acc
      pop   01h
      pop   00h
      reti

Sementara jika register R4 bernilai 2, maka program akan menjalankan perintah yang berhubungan dengan proses scanning pada register-register seperti RegDigit, RegDsp1 dan RegDsp2. Untuk perintah pada bagian ini masing-masing membutuhkan waktu proses sekitar 26 siklus.

      Scan_Display:
            mov   a, #17
            cjne  a, RegDigit, Scan_Berikut
            mov   RegDigit, #0
            mov   RegDsp1, #BufJadwal
            mov   RegDsp2, #BufJadwal+18
            pop   acc
            pop   01h
            pop   00h
            reti

            Scan_Berikut:
                  inc   RegDigit
                  inc   RegDsp1
                  inc   RegDsp2
                  pop   acc
                  pop   01h
                  pop   00h
                  reti

Pada rutin berikut yang merupakan rutin utama, program memeriksa nilai register R5 yang kegunaannya mirip “watchdog” atau berkaitan dengan timer peraga. Nilai register ini tidak boleh habis dicacah turun dan pada keadaan normal selalu diset pada program interupsi timer. Saat boot awal tentu subrutin interupsi belum aktif dan program akan menjalankan perintah inisialisasi timer karena nilai register R5 pastinya akan habis dicacah.

Pada inisialisasi, kita menggunakan timer 0 yang disetel auto-reload dengan nilai TH0 adalah 1 untuk menjalankan interupsi timer setiap 255 siklus termasuk siklus dalam subrutin interupsi itu sendiri. Maka jika subrutin interupsi timer sebelumnya membutuhkan 25 dan 26 siklus maka rutin hanya memiliki sisa sekitar 199 dan 250 siklus dalam menjalankan perintah. Maka sudah dapat dipastikan proses perintah pada rutin dan subrutin berikut akan mengalami interupsi.

Periksa_Waktu:
      djnz  r5, Periksa_Detik
      mov   r5, #5     
      mov   tmod, #02h
      mov   th0, #1
      mov   tl0, #1
      mov   ie, #8ah
      setb  tr0

Rutin berikut adalah untuk mengambil informasi register “detik” yang berasal dari RTS-RAM DS1307. Perintah yang dijalankan juga memeriksa status bit CH (clock halt) untuk memastikan RTC selalu berosilasi.

      Periksa_Detik:
            mov   a, #1
            mov   b, #0
            mov   r0, #BufWaktu
            acall DS1307_Read
            mov   a, BufWaktu
            jnb   acc.7, Ambil_Detik
            acall DS1307_ClockRUN

Data informasi detik dibandingkan dengan nilai register RegDetik pada rutin Ambil_Detik untuk memeriksa adanya peruban waktu dalam detik. Kemudian pada rutin Ambil_Waktu, informasi detik juga diperiksa, jika bernilai 00 yang berarti data menit pastinya juga berubah, maka program membaca waktu secara keseluruhan akan dijalankan untuk mendapatkan informasi menit, jam, tanggal, bulan dan tahun.

Setelah diperoleh informasi terkini dari waktu, maka selanjutnya kita akan menjalankan subrutin yang berkaitan dengan jadual Sholat pada subrutin Periksa_Bulan dan subrutin berkaitan dengan data register untuk peraga LED 7 segmen pada subrutin Set_Display.

            Ambil_Detik:
                  cjne  a, RegDetik, Ambil_Waktu
                  ajmp  Periksa_Waktu
     
                  Ambil_Waktu:
                        mov   RegDetik, a
                        jnz   Periksa_Waktu
                        mov   a, #6
                        mov   b, #1
                        mov   r0, #BufWaktu+1
                        acall DS1307_Read
                        acall Periksa_Bulan
                        acall Set_Display
                        ajmp  Periksa_Waktu

Hal pertama yang dijalankan pada subrutin Periksa_Bulan adalah menentukan lokasi memori dari jadwal yang sesuai dengan informasi waktu yang ada. Awalnya register DPTR berisi alamat awal dari data alamat yang dikurangkan sebanyak 2 byte karena seperti diketahui bahwa bulan dimulai dari nilai 1 bukan 0. Karena alamat memori dari jadwal membutuhkan data sebanyak 2 byte maka nilai bulan dikalikan dengan 2.

;I/P: BufWaktu+4 => data Bulan
;     BufWaktu+3 => data Tanggal
;O/P: Alamat Jadwal => DPTR

Periksa_Bulan:
      mov   dptr, #AlamatBulan-2
      mov   a, BufWaktu+5
      mov   b, #2
      mul   ab
      mov   b, a
      movc  a, @a+dptr
      xch   a, b
      inc   a
      movc  a, @a+dptr
      mov   dph, b
      mov   dpl, a
      mov   r1, BufWaktu+4
      ajmp  Ambil_Jadwal

Setelah program di atas dijalankan, kita akan mendapatkan data alamat yang sesuai dengan informasi bulan. Sebagai contoh, jika data bulan adalah 07H maka nilai DPTR seharusnya 0888H seperti ditunjukkan pada daftar alamat memori dari jadual di bawah ini.

AlamatBulan:
      db 00h, 00h, 01h,  74h, 02h, 0d0h, 04h,  44h, 05h, 0ach, 07h,  20h
      db 08h, 88h, 09h, 0fch, 0bh,  70h, 0ch, 0d8h, 0eh,  4ch, 0fh, 0b4h

Jika alokasi alamat memori untuk jadwal bulan sudah didapat, maka selanjutnya kita akan mencari alokasi yang lebih akurat sesuai dengan tanggal dari bulan tersebut. Setiap tanggal yang dilewati akan membuat nilai register DPTR bertambah 12 sampai tanggal yang sesuai.

Begitu tanggal yang dituju ditemukan maka selanjutnya program akan membaca informasi jadual Sholat yang disimpan pada memori AT24C512 yang kemudian dipindahkan ke BufJadwal.

Periksa_Tanggal:
      mov   r2, #12

      Cari_Tanggal:
            inc   dptr
            djnz  r2, Cari_Tanggal

      Ambil_Jadwal:
            djnz  r1, Periksa_Tanggal
            mov   r7, #12
            mov   r0, #BufJadwal
            acall AT24C512_Read
            ret

Sampai dengan subrutin di atas, kita sudah mendapatkan informasi baik waktu pada BufWaktu dan jadual Sholat pada BufJadwal. Selanjutnya kita akan memproses informasi tersebut untuk kebutuhan tampilan yang menggunakan BufDisplay.

Pertama adalah memproses informasi waktu. Karena ada sedikit perbedaan urutan maka proses dibagi menjadi 2 bagian. Proses dimulai dari urutan informasi jam (BufWaktu+2), menit (BufWaktu+1) kemudian detik (BufWaktu). Proses akan mengubah 3 byte data BCD menjadi 6 digit melalui subrutin Display_BCD.

Set_Display:
      mov   r6, #3
      mov   r0, #BufWaktu+2
      mov   r1, #BufDisplay

      Dsp_Jam:
            mov   a, @r0
            dec   r0
            acall Display_BCD
            djnz  r6, Dsp_Jam
            mov   r6, #3
            mov   r0, #BufWaktu+4

Proses pada bagian kedua untuk informasi tanggal (BufWaktu+4), bulan (BufWaktu+5) dan tahun (BufWaktu+6). Dari informasi waktu yang berjumlah 6 byte akan kita dapati jumlah digit untuk tampilan LED 7 segmen sebanyak 12 byte.

      Dsp_Tanggal:
            mov   a, @r0
            inc   r0
            acall Display_BCD
            djnz  r6, Dsp_Tanggal
            mov   r6, #12
            mov   r0, #BufJadwal

Untuk informasi jadwal yang disimpan pada BufJadwal akan diubah pula dari 12 byte BCD menjadi 24 digit informasi LED 7 segmen yang disimpan pada BufDisplay.

      Dsp_Jadwal:
            mov   a, @r0
            inc   r0
            acall Display_BCD
            djnz  r6, Dsp_Jadwal
            ret

Subrutin di bawah ini dijalankan untuk mengubah byte data ke dalam digit dari nibel yang dimulai dari MSB kemudian LSB.

      Display_BCD:
            mov   b, a
            swap  a
            acall DataLED
            xch   a, b
            acall DataLED
            djnz  r6, Display_BCD        
            ret

Data digit yang berasal dari nibel MSB dan LSB selanjutnya akan dikonversikan menjadi digit LED 7 segmen sesuai dengan data dari tabel alokasi pada Kode7Segmen.

DataLED:
      mov   dptr, #Kode7Segmen
      anl   a, #0fh
      movc  a, @a+dptr
      mov   @r1, a
      inc   r1
      ret

Kode7Segmen:
      db 11000000b, 11111001b, 10100100b, 10110000b, 10011001b
      db 10010010b, 10000010b, 11111000b, 10000000b, 10010000b

Untuk melaksanakan perintah di atas kita membutuhkan 3 modul tambahan yaitu DS1307.TXT, AT24C512.TXT dan I2C.TXT seperti dituliskan pada bagian di bawah ini.

$include (c:\tesasm\ds1307.txt)
$include (c:\tesasm\at24c512.txt)
$include (c:\tesasm\i2c.txt)

end

Sampai di sini aplikasi jadual Sholat sudah bisa berjalan namun belum sempurna. Untuk aplikasi kendali pengaturan manual waktu atau lainnya akan dibahas pada kesempatan berikut dari seri tulisan ini. Termasuk aplikasi komunikasi serial yang bisa diterapkan pada rangkaian di atas sebagai salah satu fasilitas.

Kebutuhan ruang penyimpanan informasi jadwal adalah 4.392 byte sementara kapasitas AT24C512 adalah 65.526 byte. Sobat bisa menggantinya dengan memori berkapasitas lebih kecil seperti AT24C256 yang memiliki kapasitas 32.768 byte, AT24C128 berkapasitas 16.384 byte dan minimal adalah AT24C64 yang berkapasitas 8.192 byte tanpa memerlukan perubahan program.

Jika Sobat tertarik untuk membuatnya, saran penulis sebaiknya menggunakan setidaknya AT24C128 untuk pengembangan program di mana diperlukan penyesuaian waktu menurut lokasi tempat tinggal.



Sudah ya, terima kasih sudah membaca artikel aku. Semoga bermanfaat dan bisa diterapkan oleh sobat semua.

Salam....