JAM DIGITAL
Oleh:
Dian Neipa P.
1110155002
Dosen Pengampu:
Akhmad Hendriawan, S.T., M.T.
Pendahuluan
Waktu sangat penting bagi kehidupan sehari-hari. Untuk dapat mengetahui waktu,
kita dapat menggunakan alam sekitar, dengan cara melihat arah dan posisi matahari. Namun
pada zaman yang modern ini, sudah ditemukan jam untuk mengetahui kapan waktu bekerja,
waktu pulang, waktu beribadah dan juga waktu untuk istirahat. Model jam ada dua yaitu,
jam analog dan jam digital. Jenisnya pun ada dua yaitu jam tangan dan jam dinding.
Jam adalah alat elektronika yang tidak asing untuk, karena sebagai alat penghitung
waktu yang telah di gunakan pada abad ke 14 atau sekitar 700 tahun yang lalu. Nama
tersebut berasal dari bahasa latin yang namanyaclocca. Cara orang dulu untuk
mengetahui waktu dengan menggunakan matahari dan mambagi dalam dua waktu, yang
pertama jika matahari tepat diatas kepala berarti tengah hari atau, dan ketika matahari
dekat dengan kaki langit berarti sudah waktunya dekat pagi atau malam. Jam tertua
bernama jam sundial atau biasanya disebut dengan jam matahari, pertama kali digunakan
sekitar 3.500 sebelum masehi, Ibnu Al-Shatir, Ahli Astronomi (777H atau 1375M)
menciptakan sebuah jam matahari untuk Masjid Jamik Umayyah di Damsyik. Ia dianggap
sebagai pencapaian tertinggi bagi penciptaan jam matahari.
Dengan begitu pentingnya waktu, maka dibutuhkan sebuah pengingat yang dapat
berfungsi secara otomatis dan terkontrol untuk mendukung aktivitas sehari-hari. Oleh sebab
itu dengan adanya jam digital mikrokontroler ini, diharapkan mampu mendukung aktivitas
sehari-hari, karena jam digital ini prinsip kerjanya otomatis, terkontrol dan terprogram
untuk berfungsi sebagai pengingat. Jam digital ini diatur oleh sebuah mikrokontroler yang
di dalamnya sudah terprogram menggunakan bahasa C++ dan hasilnya ditampilkan dalam
LCD.
Dasar Teori
1. ATmega 16
ATmega 16 merupakan seri mikrokontroler CMOS 8-bit buatan Atmel, berbasis
arsitektur RISC (Reduced Instruction Set Computer). Hampir semua instruksi dieksekusi
dalam satu siklus clock. ATMega16 mempunyai 32 register general-purpose,
timer/counter fleksibel dengan mode compare, interrupt internal dan eksternal, serial
UART, programmable Watchdog Timer, dan mode power saving, ADC dan PWM
512Bytes EEPROM
Programming of Flash, EEPROM, Fuses, and Lock Bits through the JTAG Interface
5. Peripheral Features
-
One 16-bit Timer/Counter with Separate Prescaler, Compare Mode, and Capture
Mode
8 Single-ended Channels
Six Sleep Modes: Idle, ADC Noise Reduction, Power-save, Power-down, Standby
and Extended Standby
8. Operating Voltages
-
2.7 - 5.5V
9. Speed Grades
-
0 - 16MHz
Active: 0.6mA
model TQFP. ATmega 16A-AU ini memiliki kaki sebanyak 44. Konfigurasi pin pada
ATmega16A-AU dapat dilihat pada gambar berikut.
kombinasi dua buah push button. Digunakan dua buah pushbutton sebagai tombol mode
dan tombol advance. Fitur yang disediakan pada jam digital yang akan dibuat adalah ubah
jam, ubah menit, ubah detik, dan alarm. Untuk membangkitkan jam digital berupa jam,
menit dan detik digunakan sebuah timer dengan konfigurasi seperti berikut:
void SCH_init(unsigned int periode)
{
TCNT1=0;
// reset counter
OCR1A=(unsigned long) periode*1000/64; // delayms
TCCR1B |=(1<<WGM12); //mode ctc
TCCR1B |=(1<<CS12)|(1<<CS10); //prescaller 1024
TIMSK |= (1<<OCIE1A);
//enable interupt timer
Task_Init();
}
Konfigurasi timer menggunakan mode CTC dengan clock select pada prescaller
1024. Parameter TCNT disetting 0 sebagai reset counter. Agar user dapat sewaktu-waktu
mengganti tampilan jam menit maupun detik maka pada parameter OC1E1A diberi logika 1
untuk mengaktifkan interrupt timer.
case tampil:
{
_jam();
lcd_gotoxy(1,0); lcd_putstr(" ");
//button Mode ditekan
if (!isCheckPIN(btnMode))
debounceMode=(debounceMode<<1);
else debounceMode= (debounceMode<<1)|1;
if (debounceMode==0b11111100)
state=ubah_jam;
break;
}
case ubah_jam:
{
unsigned int da=0;
display_jam();
lcd_gotoxy(1,0); lcd_putstr("Ubah Jam");
//button Mode ditekan
if (!isCheckPIN(btnMode))
debounceMode=(debounceMode<<1);
else debounceMode= (debounceMode<<1)|1;
if (debounceMode==0b11111100)
state=ubah_menit;
//button Advance ditekan
if (!isCheckPIN(btnAdvance))
{debounceAdvance=(debounceAdvance<<1);}
else debounceAdvance= (debounceAdvance<<1)|1;
if (debounceAdvance==0b11111100) update_jam1();
if (debounceAdvance==0b00000011) update_jam10();
break;
}
Secara keseluruhan cara kerja program jam digital dapat dilihat dalam listing
program diatas, ketika pertama kali dinyalakan program akan menuju state tampil dan akan
menampilkan jam dengan tampilan 0:0:0. Selanjutnya user dapat mengatur jam menit
maupun detik dengan menekan tombol mode. Ketika tombol mode ditekan, program akan
menuju state ubah jam dan pada LCD akan muncul tampilan Ubah Jam. Untuk mengubah
pengaturan jam digunakan tombol advance untuk menambahkan jam sesuai keinginan. Jika
tombol advance ditekan satu kali maka menambahkan jam sebanyak 1 jam, sedangkan jika
tombol advance ditekan lebih lama maka program akan menambahkan jam dengan
kelipatan 10 untuk mempermudah user melakukan pengaturan jam. Untuk mengganti
pengaturan pada state ubah menit maka user hanya perlu menekan tombol mode sekali,
begitupun dengan ubah menit.
Daftar Pustaka
https://mnurudin47.wordpress.com/2014/12/16/jam-digital/ (diakses 12 Juni 2016)
Lampiran
sEOS.h
#ifndef _SEOS_H
#define _SEOS_H
void
void
void
void
void
void
void
void
void
#endif
sEOS.c
#include "sEOS.h"
#include "task.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include "device.h"
#include "utility.h"
#include "lcd.h"
#include "stdio.h"
//#include "button.h"
// global variable
volatile uint8_t jam = 0;
volatile uint8_t menit = 0;
volatile uint8_t detik = 0;
volatile uint8_t count = 0;
unsigned char buff[50];
ISR (TIMER1_COMPA_vect)
{
Task_Run();
system_update();
}
void SCH_init(unsigned int periode)
{
TCNT1=0;
// reset counter
OCR1A=(unsigned long) periode*1000/64; // delayms
TCCR1B |=(1<<WGM12); //mode ctc
TCCR1B |=(1<<CS12)|(1<<CS10); //prescaller 1024
TIMSK |= (1<<OCIE1A);
//enable interupt timer
Task_Init();
}
void system_update (void)
{
if (++count>6)
{
count =0;
if (++detik>=60)
{detik=0; ++menit;lcd_clear();}
if (menit>=60)
{menit=0; ++jam;lcd_clear();}
if (jam>=24)
{jam=0;lcd_clear();}
}
void update_jam1 (void)
{jam++; if (jam>=24){jam=0;lcd_clear();} }
void update_jam10 (void)
{jam+=10; if (jam>=24){jam=0;lcd_clear();}}
void update_menit1 (void)
{menit++; if (menit>=60) {menit=0; ++jam;lcd_clear();}}
void update_menit10 (void)
{menit += 10; if (menit>=60) {menit=0;++jam;lcd_clear();}}
void update_detik1 (void)
{detik++; if (++detik>=60) {detik=0;++menit;lcd_clear();}}
void update_detik10 (void)
{detik +=10; if (++detik>=60) {detik=0;++menit;lcd_clear();}}
void display_jam (void)
{
lcd_gotoxy(0,0);
sprintf (buff,"%d:%d:%d",jam,menit,detik);
lcd_putstr(buff);
// lcd_putstr("HELLO");
}
LCD.h
#ifndef _LCD_H
#define _LCD_H
#include <avr/io.h>
#include <util/delay.h>
//LCD interface
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
PORT_LCD
PORTB
DDR_LCD
DDRB
RS
PB0
RW
PB1
EN
PB2
DB4
PB4
DB5
PB5
DB6
PB6
DB7
PB7
SETBIT(address,bit) (address |= (1<<bit))
CLRBIT(address,bit) (address &= ~(1<<bit))
SET_EN SETBIT(PORT_LCD,EN)
CLR_EN CLRBIT(PORT_LCD,EN)
SET_RS SETBIT(PORT_LCD,RS)
CLR_RS CLRBIT(PORT_LCD,RS)
SET_RW SETBIT(PORT_LCD,RW)
CLR_RW CLRBIT(PORT_LCD,RW)
// prototipe fungsi
void enable(void);
// enable fulse for LCD
void lcd_init(void);
// intialization LCD
void lcd_putchar(unsigned char c); // send character to LCD
void lcd_putstr(char *s);
// send string to LCD
void lcd_clear(void);
// clear display
void lcd_gotoxy(unsigned char i,unsigned char j); //move LCD cursor
position
#endif
LCD.c
#include "lcd.h"
/********************************************************************/
/* Function
: void enable(void)
*/
/*------------------------------------------------------------------*/
/* Description : This subroutine send Pulse to activate LCD
*/
/*------------------------------------------------------------------*/
/* Author
: Akhmad Hendriawan
*/
/*------------------------------------------------------------------*/
/* Input
:
*/
/*------------------------------------------------------------------*/
/* Returnvalue :
*/
/*------------------------------------------------------------------*/
/* History
: 2 December 2008
*/
/*
*/
/********************************************************************/
void enable(void) {
SET_EN;
_delay_ms(3);
CLR_EN;
}
/********************************************************************/
/* Function
: void lcd_init(void)
*/
/*------------------------------------------------------------------*/
/* Description : This subroutine initialization LCD
*/
/*------------------------------------------------------------------*/
/* Author
: Akhmad Hendriawan
*/
/*------------------------------------------------------------------*/
/* Input
:
*/
/*------------------------------------------------------------------*/
/* Returnvalue :
*/
/*------------------------------------------------------------------*/
/* History
: 2 December 2008
*/
/*
*/
/********************************************************************/
void lcd_init(void)
{
DDR_LCD=0xFF;
// enable output for LCD
CLR_EN;
_delay_ms(15);
//step1
PORT_LCD=0x30;CLR_RS;CLR_RW;enable();
_delay_ms(5);
// step2
PORT_LCD=0x30;CLR_RS;CLR_RW;enable();
_delay_ms(1);
// step3
PORT_LCD=0x30;CLR_RS;CLR_RW;enable();
//next init
PORT_LCD=0x20;CLR_RS;CLR_RW;enable();
PORT_LCD=0x20;CLR_RS;CLR_RW;enable();
PORT_LCD=0x80;CLR_RS;CLR_RW;enable();
PORT_LCD=0x00;CLR_RS;CLR_RW;enable();
PORT_LCD=0xE0;CLR_RS;CLR_RW;enable();
PORT_LCD=0x00;CLR_RS;CLR_RW;enable();
cursor shift right
PORT_LCD=0x60;CLR_RS;CLR_RW;enable();
PORT_LCD=0x00;CLR_RS;CLR_RW;enable();
PORT_LCD=0x10;CLR_RS;CLR_RW;enable();
}
// display on
// entry mode address inc and
// display clear
// display clear
/********************************************************************/
/* Function
: void lcd_putchar(unsigned char kar)
*/
/*------------------------------------------------------------------*/
/* Description : This subroutine send character to LCD
*/
/*------------------------------------------------------------------*/
/* Author
: Akhmad Hendriawan
*/
/*------------------------------------------------------------------*/
/* Input
: character
*/
/*------------------------------------------------------------------*/
/* Returnvalue :
*/
/*------------------------------------------------------------------*/
/* History
: 3 December 2008
*/
/*
*/
/********************************************************************/
void lcd_putchar(unsigned char kar)
{
unsigned char kar2;
//kar2=(kar|(PORT_LCD&0x0F))& (PORT_LCD|0xF0); //save control in bit
0-3
//kar2= (kar & 0xF0) + (PORT_LCD &0x0F);
//CLRBIT(kar2,EN);
kar2=kar & 0xF0;
PORT_LCD=kar2;SET_RS;CLR_RW;enable(); //
kar=(kar<<4|kar>>4);
kar2 = kar & 0xF0;
PORT_LCD=kar2;SET_RS;CLR_RW;enable(); // display clear
}
/********************************************************************/
/* Function
: void lcd_putstr(char *s)
*/
/*------------------------------------------------------------------*/
/* Description : This subroutine send string to LCD
*/
/*------------------------------------------------------------------*/
/* Author
: Akhmad Hendriawan
*/
/*------------------------------------------------------------------*/
/* Input
: String
*/
/*------------------------------------------------------------------*/
/* Returnvalue :
*/
/*------------------------------------------------------------------*/
/* History
: 2 December 2008
*/
/*
*/
/********************************************************************/
Task.h
#ifndef _TASK_H
#define _TASK_H
#include "device.h"
#include <avr/io.h>
#define YES
#define NO
0
void Task_Init(void);
void Task_Run(void);
#endif
Task.c
#include <util/delay.h>
#include <avr/io.h>
#include "task.h"
#include "device.h"
#include "utility.h"
#include "lcd.h"
#include "sEOS.h"
//#include "button.h"
//Private variable----------------------enum state {tampil, ubah_jam, ubah_menit, ubah_detik} state;
unsigned char debounceMode=0xFF;
unsigned char debounceAdvance=0xFF;
unsigned char buff[50];
//Private task ----------------------void Task_Init(void)
{
SETInputPullup(btnMode);
SETInputPullup(btnAdvance);
state=tampil;
}
void Task_Run(void)
{
switch(state)
{
case tampil:
{
display_jam();
lcd_gotoxy(1,0); lcd_putstr("
//button Mode ditekan
if (!isCheckPIN(btnMode))
debounceMode=(debounceMode<<1);
else debounceMode= (debounceMode<<1)|1;
if (debounceMode==0b11111100) state=ubah_jam;
");
break;
}
case ubah_jam:
{
unsigned int da=0;
display_jam();
lcd_gotoxy(1,0); lcd_putstr("Ubah Jam");
//button Mode ditekan
if (!isCheckPIN(btnMode))
debounceMode=(debounceMode<<1);
else debounceMode= (debounceMode<<1)|1;
if (debounceMode==0b11111100) state=ubah_menit;
//button Advance ditekan
if
(!isCheckPIN(btnAdvance))
{debounceAdvance=(debounceAdvance<<1);}
else
debounceAdvance= (debounceAdvance<<1)|1;
if
(debounceAdvance==0b11111100)
update_jam1();
if
(debounceAdvance==0b00000011)
update_jam10();
}
break;
case ubah_menit:
{
display_jam();
lcd_gotoxy(1,0); lcd_putstr("Ubah Menit");
//button Mode ditekan
if (!isCheckPIN(btnMode))
debounceMode=(debounceMode<<1);
else debounceMode= (debounceMode<<1)|1;
if (debounceMode==0b11111100) state=ubah_detik;
//button Advance ditekan
if
(!isCheckPIN(btnAdvance))
{debounceAdvance=(debounceAdvance<<1);}
else
debounceAdvance= (debounceAdvance<<1)|1;
if
(debounceAdvance==0b11111100)
update_menit1();
if
(debounceAdvance==0b00000011)
update_menit10();
break;
}
case ubah_detik:
{
display_jam();
lcd_gotoxy(1,0); lcd_putstr("Ubah Detik");
//button Mode ditekan
if (!isCheckPIN(btnMode))
debounceMode=(debounceMode<<1);
else debounceMode= (debounceMode<<1)|1;
if (debounceMode==0b11111100) state=tampil;
//button Advance ditekan
if
(!isCheckPIN(btnAdvance))
{debounceAdvance=(debounceAdvance<<1);}
else
debounceAdvance= (debounceAdvance<<1)|1;
if
(debounceAdvance==0b11111100)
update_detik1();
if
(debounceAdvance==0b00000011)
update_detik10();
}
}
break;
Device.h
#ifndef DEVICE_H_
#define DEVICE_H_
//DeviceIO
#define ledBar PORTA
#define pushButton1 C,0
#define pushButton2 C,1
#define pushButton3 C,2
#define pushButton4 C,3
#define ledDebug
C,4
#define ledHijau
C,5
#define buzzer
C,6
//custom
#define
#define
#define
#define
#define
btnMode
pushButton1
btnAdvance pushButton2
ledRED
A,0
ledYellow
A,2
ledGreen
A,4
#endif /* DEVICE_H_ */
Utility.h
#ifndef UTILITY_H_
#define UTILITY_H_
//utility
#define checkbit(address,bit) (address & (1<<bit))
#define setbit(address,bit) (address |=(1<<bit))
#define clrbit(address,bit) (address &=~(1<<bit))
#define flipbit(address,bit) (address ^=(1<<bit))
//temporary
#define _set(address,bit) (PORT##address |=(1<<bit))
#define _clr(address,bit) (PORT##address &=~(1<<bit))
#define _flip(address,bit) (PORT##address ^=(1<<bit))
#define _setInputPullup(address,bit) (DDR##address &=~(1<<bit));
(PORT##address |=(1<<bit))
#define _setOutput(address,bit) (DDR##address |=(1<<bit))
#define _Checkbit2(address,bit) (PIN##address &(1<<bit))
//final
#define SET(address) _set(address)
#define CLR(address) _clr(address)
#define FLIP(address) _flip(address)
#define SETInputPullup(address) _setInputPullup(address)
#define SETOutput(address)_setOutput(address)
#define isCheckPIN(x) _Checkbit2(x)
//end utility
#endif /* UTILITY_H_ */
Main.c
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "task.h"
#include "sEOS.h"
#include "lcd.h"
#include "device.h"
#include "utility.h"
//#include "button.h"
int main(void)
{
Task_Init();
// button_init();
SCH_init(10);
lcd_init();
sei();
while(1)
{sleep_mode();}
return 0;
}