Categories
Mikrokontroler

Tutorial AT89: RTC DS1307 (64 x 8 Serial Real-Time Clock)

RTC yang kita bahas kali ini adalah RTC dengan antarmuka I2C, yaitu DS1307. Artikel yang membahas RTC lain secara lengkap, DS12C887, yang menggunakan antarmuka paralel dan penggunaan bahasa assembly, bisa Anda baca mulai dari Pendahuluan, Register Data/Kontrol, dan Contoh Aplikasi.

Okey… sekarang kita lihat dulu fitur dari DS1307:

  • Real-time clock (RTC) meyimpan data-data detik, menit, jam, tanggal, bulan, hari dalam seminggu, dan tahun valid hingga 2100;
  • 56-byte, battery-backed, RAM nonvolatile (NV) RAM untuk penyimpanan;
  • Antarmuka serial Two-wire (I2C)
  • Sinyal luaran gelombang-kotak terprogram (Programmable squarewave);
  • Deteksi otomatis kegagalan-daya (power-fail) dan rangkaian switch;
  • Konsumsi daya kurang dari 500nA menggunakn mode baterei cadangan dengan operasional osilator;
  • Tersedia fitur industri dengan ketahana suhu: -40°C hingga +85°C
  • Tersedia dalam kemasa 8-pin DIP atau SOIC

Sedangkan daftar pin DS1307:

  • VCC – Primary Power Supply
  • X1, X2 – 32.768kHz Crystal Connection
  • VBAT – +3V Battery Input
  • GND – Ground
  • SDA – Serial Data
  • SCL – Serial Clock
  • SQW/OUT – Square Wave/Output Driver

Gambar diagram PIN:

Contoh Rangkaian ke mikrokontroler AT89 (plus rangkaian komunikasi serial):

Dan sekarang ke contoh program, sengaja saya gunakan bahasa tingkat tinggi – BASIC, karena rumitnya protokol komunikasi I2C jika diimplementasikan menggunakan bahasa Assembly. Baik…. Tujuannya adalah sistem menanggapi perintah “t” untuk menampilkan informasi jam, dan “d” untuk menampilkan informasi tanggal melalui terminal serial komputer (bisa menggunakan HyperTerminal atau lain yang sejenisnya).

Okey, let’s get started…

KIta awali dengan beberapa definisi atau inisialisasi program…

$regfile = "89s8252.dat"
$crystal = 11059200
$baud = 9600

Keterangan:

  1. $regfile digunakan untuk mendefinisikan mikrokontroler yang digunakan, yaitu 89s8252;
  2. $crystal kita gunakan untuk mendefinisikan frekuensi kristal yang terpasang pada rangkaian kita, dan ini penting banget soalnya akan menentukan proses kompilasi perintah-perintah I2C yang terkait. Jika Anda salah menuliskan angkanya atau angka yang ditulis tidak sama dengan kristal yang terpasang di rangkaian;
  3. $baud digunakan untuk menentukan kecepatan komunikasi serial, yaitu 9600 bps, Anda bisa mengubah untuk kecepatan yang lain.

Selanjutnya, kita definisikan beberapa variabel untuk kebutuhan pemrograman:

Dim Reg_sec As Byte , Reg_min As Byte , Reg_hour As Byte
Dim Num_hour As Byte , Num_min As Byte , Num_sec As Byte
Dim Reg_date As Byte , Reg_month As Byte , Reg_year As Byte
Dim Num_date As Byte , Num_month As Byte , Num_year As Byte
Dim Masuk As String * 1

Keterangan:

  • Reg_sec, Reg_min, dan Reg_hour merupakan variabel-variabel 8-bit atau 1 byte yang digunakan untuk menyimpan hasil pembacaan RTC DS1307 yang masing-masing untuk data detik, menit dan jam;
  • Reg_date, Reg_month, dan Reg_year merupakan variabel-variabel 8-bit atau 1 byte yang digunakan untuk menyimpan hasil pembacaan RTC DS1307 yang masing-masing untuk data tanggal, bulan dan tahun;
  • Num_sec, Num_min, dan Num_hour merupakan variabel-variabel 8-bit atau 1 byte yang digunakan untuk menyimpan hasil konversi BCD (pembacaan RTC) ke desimal, yang akan dikirim melalui komunikasi serial, masing-masing untuk detik, menit, dan jam;
  • Num_date, Num_month, dan Num_year merupakan variabel-variabel 8-bit atau 1 byte yang digunakan untuk menyimpan hasil konversi BCD (pembacaan RTC) ke desimal, yang akan dikirim melalui komunikasi serial, masing-masing untuk tanggal, bulan, dan tahun;
  • Masuk sebagai variabel untuk menyimpan sebuah karakter (string * 1) kiriman dari port serial, yang diterjemahkan hanya “t” dan “d”, masing-masing untuk perintah baca jam dan baca tanggal.

Langkah berikutnya adalah mendefinisikan jalur atau pin dari mikrokontroler ke RTC-nya (DS1307):

'------------------------------------------
' konfigurasi bus I2C
Config Scl = P2.0
' jalur untuk clock I2C
Config Sda = P2.1
' jalur untuk data I2C
'-------------------------------------------

Keterangan:

  • Hanya 2 kabel utama (selain menyamakan GND – ground) yang digunakan untuk komunikasi dengan mikrokontroler, yaitu SCL dan SDA (perhatikan diagram pin-nya);
  • SCL (serial clock) dihubungkan dengan P2.0, sedangkan SDA (serial data) dihubungkan dengan P2.1.

Kemudian kita definisikan beberapa konstanta yang berkaitan dengan alamat-alamat register di dalam DS1307 (silahkan merujuk datasheet DS1307 (PDF):

' perintah penulisan
Const Ds1307w = &HD0
' perintah pembacaan
Const Ds1307r = &HD1
' alamat register DS1307 yg berhubungan dengan jam
Const Sec_addmap = &H00
Const Min_addmap = &H01
Const Hour_addmap = &H02
' alamat register DS1307 yg berhubungan dengan tanggal
Const Date_addmap = &H04
Const Month_addmap = &H05
Const Year_addmap = &H06

Keterangan:

  • Instruksi atau perintah yang digunakan untuk penulisan data ke RTC DS1307 adalah D0h, sedangkan untuk pembacaan D1h, masing-masing disimpan ke dalam variabel DS1307w dan DS1307r;
  • Alamat-alamat yang berhubungan dengan jam untuk detik, menit dan jam, masing-masing di 00h, 01h dan 02h;
  • Alamat-alamat yang berhubungan dengan jam untuk tanggal, bulan dan tahun, masing-masing di 04h, 05h dan 06h.

Program utamanya melakukan menunggu masukan port serial, semua karakter diterima, tetapi hanya huruf “t” (huruf kecil), dan “d” diterjemahkan masing-masing untuk “baca jam”, dan “baca tanggal”. Selain kedua perintah tersebut, mikrokontroler akan mengirimkan “er” sebagai tanda salah kirim perintah. Selain itu akan dikirim data jam atau tanggal, perhatikan potongan program utamanya berikut ini (pengulangan menggunakan DO LOOP, penerjemahan menggunakan SELECT CASE):

Do
  Input Masuk
  Select Case Masuk
  Case "t" : Call Read_time
             Print Num_hour ; ":" ; Num_min ; ":" ; Num_sec
  Case "d" : Call Read_date
             Print Num_date ; "/" ; Num_month ; "/" ; Num_year
  Case Else
             Print "er"
  End Select
Loop
End

Perhatikan pada program utama. Terdapat dua subrutin: (1) Read_time digunakan untuk membaca data dan (2) Read_date untuk membaca tanggal…

'-=-=-=-=-=-=-=-=-=-=-=-=-=
Sub Read_time
'-=-=-=-=-=-=-=-=-=-=-=-=-=
' Read Clock Data
  I2CStart
' Generate start
  I2CWbyte Ds1307w
' Slave address
  I2CWbyte Sec_addmap
' Address of SECONDS REG
  I2Cstop
' Generate Stop
  I2Cstart
' Repeated start
  I2CWbyte Ds1307r
' Slave address (read)
  I2CRbyte Reg_sec , Ack
  I2CRbyte Reg_min , Ack
  I2CRbyte Reg_hour , Nack
  I2CStop
' Generate Stop
' reg_hour.6 =1(12 hrmode), if =0 (24 hourmode)
  If Reg_hour.6 = 1 Then
    Reg_hour = Reg_hour And &B00011111
  Else
    Reg_hour = Reg_hour And &B00111111
  End If
'=-=-=-=-=-=-=-=-=-=-=-
'  Reg_hour = Reg_hour And &B00111111
'  remove 12/24 and am/pm bits
'  set numeric variables
  Num_hour = Makedec(reg_hour)
  Num_min = Makedec(reg_min)
  Num_sec = Makedec(reg_sec)
End Sub

Keterangan:

  • Ini merupakan subrutin Read_time yang digunakan untuk membaca jam;
  • Proses pembacaan jam dan tanggal pada dasarnya sama saja, diawali dengan (lihat listing programnya) inisialisasi I2Start, kemudian dilanjutkan dengan I2CWByte DS1307w (menuliskan perintah atau instruksi);
  • Kemudian diikuti dengan menuliskan alamat register detiknya: I2CWByte Sec_addmap dan dihentikan dengan I2CStop;
  • Langkah selanjutnya adalah mulai membaca dari data detik, diawali dengan I2Cstart (lagi, awal pembacaan data) kemudan perintah membaca dikirimkan ke RTC menggunakan instruksi I2CWbyte DS1307r;
  • Kemudian baru data detik, menit dan jam-nya dibaca berturut-turut menggunakan perintah I2CRbyte Reg_sec, Ack untukmembaca data detik, Ack digunakan untuk indikator masih ada data yang lain perlu dibaca (kebalikannya adalah NAck). Dan berturut-turut membaca data menit (I2CRbyte Reg_min, Ack), dan detik (I2CRbyte Reg_hour, NAck), NAck artinya tidak ada lagi data yang perlu dibaca, jangan lupa di-stop;
  • Untuk proses normalisasi terhadap mode jam, apakah mode 12 jam atau 24 jam, digunakan pengecekan pada bit-6 di Reg_hour;
  • Langkah terakhir adalah merubah hasil pembacaan yang masih dalam format BCD ke decimal melalui instruksi Makedec();

Untuk subrutin baca data tanggal sebagai berikut:

'-=-=-=-=-=-=-=-=-=-=-=-=-=
Sub Read_date
'-=-=-=-=-=-=-=-=-=-=-=-=-=
' Read Clock Data
   I2cstart
' Generate start
   I2cwbyte Ds1307w
' Slave address
   I2cwbyte Date_addmap
' Address of SECONDS REG
   I2cstop
' Generate Stop
   I2cstart
' Repeated start
   I2cwbyte Ds1307r
' Slave address (read)
   I2crbyte Reg_date , Ack
   I2crbyte Reg_month , Ack
   I2crbyte Reg_year , Nack
   I2cstop
' Generate Stop
' set numeric variables
   Num_date = Makedec(reg_date)
   Num_month = Makedec(reg_month)
   Num_year = Makedec(reg_year)
End Sub

Contoh tampilan running program di mikrokontroler, perhatikan hanya “t” dan “d” saja yang diterjemahkan, perintah atau huruf lain ditanggapi dengan “er”:

Semoga bermanfaat, ada pertanyaan dan komentar dipersilahkan…