"wahhh..kalo banyak 7 segmentnya, ngabisin banyak port dong ?"
Jangan khawatir, kita pake teknik " SCANNING", artinya kita hidupin segment satu persatu, tiap segment diparalel saja...tp kita hidupin dengan memberikan switch/saklar ke common port 7segment yg dikontrol oleh port micro ..dan scanningnya cepetttt...sehingga mata kita melihatnya seperti nyala biasa aja.
jadi untuk bikin 7-segment 4 buah, diperlukan 7 port display(diparalel) + 4 port control
rangkaiannya seperti berikut :
klik untuk memperbesar gambar
Biasanya untuk display yg agak besar, kita perlu transistor untuk mengatur scanning, tp karena contoh kali ini memakai segment yg kecil maka tidak memerlukan kontrol memakai transistor ( coba pake transistor dijamin nyalanya redup !!)
Prinsip jam kali ini menggunakan prinsip DELAY, jadi tidak terlalu akurat.
Sebenernya mau seh membagi ilmu untuk jam yg super akurat, tapi ntar aja yahh..soalnya memerlukan pengetahuan mengenai "Timer/Counter" dari microcontroller
source code nya sebagai berikut :
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int jam=0, min=0, detik=0; //variable global untuk menyimpan data2 waktu
void segmen (int angka)
{
switch (angka)
{
case 0 : { PORTB =0b1000000; break ; }
case 1 : { PORTB =0b1111001; break ; }
case 2 : { PORTB =0b0100100; break ; }
case 3 : { PORTB =0b0110000; break ; }
case 4 : { PORTB =0b0011001; break ; }
case 5 : { PORTB =0b0010010; break ; }
case 6 : { PORTB =0b0000010; break ; }
case 7 : { PORTB =0b1111000; break ; }
case 8 : { PORTB =0b0000000; break ; }
case 9 : { PORTB =0b0010000; break ; }
case 10 : { PORTB =0b1111111; break ; } //blank biar ga berbayang
}
}
void clock (void) //fungsi penambah waktu
{
detik ++; //jika fungsi dipanggil maka var detik ditambah
if ( detik == 60) // tambahkan menit jika 60 detik
{ detik=0; //untuk kembali ke 0
min++;
}
if ( min == 60) // tambahkan jam jika 60 menit
{ min = 0; //untuk kembali ke 0
jam++ ;
}
if (jam == 24) jam=0; //untuk kembali ke 0
}
int main(void)
{
int counter=0; //variabel delay
int digit; //variabel digit yang ditampilkan
// Port untuk display 7 segment
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6);
//port untuk scanning ( PD0-4) dan dot ":" (PD6)
DDRD |= (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3) |(1<<PD6);
//tombol untuk nambah jam/menit
DDRD &= ~(1<<PD4) & ~(1<<PD5) ;
PORTD = (1<<PD6) ; // blink untuk ":"
while(1)
{
counter++ ; //bikin delay nambah terusss
// sesuaikan nilai max counter dengan detik yg pas, tentunya tidak akurat
if(counter == 30) { counter =0 ; clock(); }
// nilai 1/2 dari counter untuk blink ":"
if(counter == 15) PORTD ^=(1<<PD6) ;
else{
segmen(10); // kasi display "mati' agar tidak berbayang
//digit pertama
digit = jam/10;
PORTD |= (1<<PD0); // 7 segment no1 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 2
segmen(10);
digit = jam%10;
PORTD |= (1<<PD1); // 7 segment no2 hidup..yg laen mati
PORTD &= ~(1<<PD0) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 3
segmen(10);
digit = min/10;
PORTD |= (1<<PD2); // 7 segment no3 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD0) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 4
segmen(10);
digit = min%10;
PORTD |= (1<<PD3); // 7 segment no4 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD0) ;
segmen(digit);
_delay_ms(5);
}
if (bit_is_set(PIND, PIND4)) //tombol nambah jam
{
jam++;
if(jam==24) jam =0;
_delay_ms(100);
}
if (bit_is_set(PIND, PIND5)) //tombol nambah menit
{
min++;
if(min==60) min=0;
_delay_ms(100);
}
}
return 0;
}
jika ingin mengetest/kalibrasi delay detik, ganti salah satu digit untuk menampilkan detik
//digit pertama
digit = detik/10;
PORTD |= (1<<PD0); // 7 segment no1 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 2
segmen(10);
digit = detik%10;
PORTD |= (1<<PD1); // 7 segment no2 hidup..yg laen mati
PORTD &= ~(1<<PD0) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
Bagaimana dengan jam akurat ? disini nih kuncinya ...menggunakan xtal 4Mhz
/* ===================
GUNAKAN XTAL 4MHZ dan 2 buah capacitor 22pf
dan sambungkan seperti gambar di petunjuk awal
di bagian menggunakan xtal dan ubah dusebit
rangkaian tetap sama seperti jam_sederhana
hanya tambahan xtal pada kaki 4 dan 5 serta
masing kaki xtal dihubungkan ke GND oleh
capacitor 22pf
*/
#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int jam=0, min=0, detik=0;
void segmen (int angka)
{
switch (angka)
{
case 0 : { PORTB =0b1000000; break ; }
case 1 : { PORTB =0b1111001; break ; }
case 2 : { PORTB =0b0100100; break ; }
case 3 : { PORTB =0b0110000; break ; }
case 4 : { PORTB =0b0011001; break ; }
case 5 : { PORTB =0b0010010; break ; }
case 6 : { PORTB =0b0000010; break ; }
case 7 : { PORTB =0b1111000; break ; }
case 8 : { PORTB =0b0000000; break ; }
case 9 : { PORTB =0b0010000; break ; }
case 10 : { PORTB =0b1111111; break ; } //blank biar ga berbayang
}
}
ISR(TIMER1_COMPA_vect)
{
detik ++;
if ( detik == 60)
{ detik=0;
min++;
}
if ( min == 60)
{ min = 0;
jam++ ;
}
if (jam == 24) jam=0;
}
int main(void)
{
int digit;
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 62499; //compare the CTC A
TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer at Fcpu/64
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6);
DDRD |= (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3) |(1<<PD6);
DDRD &= ~(1<<PD4) & ~(1<<PD5) ;
sei();
while(1)
{
if(TCNT1 < 31250) PORTD |=(1<<PD6) ;
else PORTD &=~(1<<PD6) ;
segmen(10);
digit = jam/10;
PORTD |= (1<<PD0);
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
segmen(10);
digit = jam%10;
PORTD |= (1<<PD1);
PORTD &= ~(1<<PD0) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
segmen(10);
digit = min/10;
PORTD |= (1<<PD2);
PORTD &= ~(1<<PD1) & ~(1<<PD0) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
segmen(10);
digit = min%10;
PORTD |= (1<<PD3);
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD0) ;
segmen(digit);
_delay_ms(5);
if (bit_is_set(PIND, PIND4))
{
jam++;
if(jam==24) jam =0;
_delay_ms(100);
}
if (bit_is_set(PIND, PIND5))
{
min++;
if(min==60) min=0;
_delay_ms(100);
}
}
return 0;
}
hasilnya dapat dilihat seperti berikut :
Prinsip jam kali ini menggunakan prinsip DELAY, jadi tidak terlalu akurat.
Sebenernya mau seh membagi ilmu untuk jam yg super akurat, tapi ntar aja yahh..soalnya memerlukan pengetahuan mengenai "Timer/Counter" dari microcontroller
source code nya sebagai berikut :
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int jam=0, min=0, detik=0; //variable global untuk menyimpan data2 waktu
void segmen (int angka)
{
switch (angka)
{
case 0 : { PORTB =0b1000000; break ; }
case 1 : { PORTB =0b1111001; break ; }
case 2 : { PORTB =0b0100100; break ; }
case 3 : { PORTB =0b0110000; break ; }
case 4 : { PORTB =0b0011001; break ; }
case 5 : { PORTB =0b0010010; break ; }
case 6 : { PORTB =0b0000010; break ; }
case 7 : { PORTB =0b1111000; break ; }
case 8 : { PORTB =0b0000000; break ; }
case 9 : { PORTB =0b0010000; break ; }
case 10 : { PORTB =0b1111111; break ; } //blank biar ga berbayang
}
}
void clock (void) //fungsi penambah waktu
{
detik ++; //jika fungsi dipanggil maka var detik ditambah
if ( detik == 60) // tambahkan menit jika 60 detik
{ detik=0; //untuk kembali ke 0
min++;
}
if ( min == 60) // tambahkan jam jika 60 menit
{ min = 0; //untuk kembali ke 0
jam++ ;
}
if (jam == 24) jam=0; //untuk kembali ke 0
}
int main(void)
{
int counter=0; //variabel delay
int digit; //variabel digit yang ditampilkan
// Port untuk display 7 segment
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6);
//port untuk scanning ( PD0-4) dan dot ":" (PD6)
DDRD |= (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3) |(1<<PD6);
//tombol untuk nambah jam/menit
DDRD &= ~(1<<PD4) & ~(1<<PD5) ;
PORTD = (1<<PD6) ; // blink untuk ":"
while(1)
{
counter++ ; //bikin delay nambah terusss
// sesuaikan nilai max counter dengan detik yg pas, tentunya tidak akurat
if(counter == 30) { counter =0 ; clock(); }
// nilai 1/2 dari counter untuk blink ":"
if(counter == 15) PORTD ^=(1<<PD6) ;
else{
segmen(10); // kasi display "mati' agar tidak berbayang
//digit pertama
digit = jam/10;
PORTD |= (1<<PD0); // 7 segment no1 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 2
segmen(10);
digit = jam%10;
PORTD |= (1<<PD1); // 7 segment no2 hidup..yg laen mati
PORTD &= ~(1<<PD0) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 3
segmen(10);
digit = min/10;
PORTD |= (1<<PD2); // 7 segment no3 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD0) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 4
segmen(10);
digit = min%10;
PORTD |= (1<<PD3); // 7 segment no4 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD0) ;
segmen(digit);
_delay_ms(5);
}
if (bit_is_set(PIND, PIND4)) //tombol nambah jam
{
jam++;
if(jam==24) jam =0;
_delay_ms(100);
}
if (bit_is_set(PIND, PIND5)) //tombol nambah menit
{
min++;
if(min==60) min=0;
_delay_ms(100);
}
}
return 0;
}
jika ingin mengetest/kalibrasi delay detik, ganti salah satu digit untuk menampilkan detik
//digit pertama
digit = detik/10;
PORTD |= (1<<PD0); // 7 segment no1 hidup..yg laen mati
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
//digit ke 2
segmen(10);
digit = detik%10;
PORTD |= (1<<PD1); // 7 segment no2 hidup..yg laen mati
PORTD &= ~(1<<PD0) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
Bagaimana dengan jam akurat ? disini nih kuncinya ...menggunakan xtal 4Mhz
/* ===================
GUNAKAN XTAL 4MHZ dan 2 buah capacitor 22pf
dan sambungkan seperti gambar di petunjuk awal
di bagian menggunakan xtal dan ubah dusebit
rangkaian tetap sama seperti jam_sederhana
hanya tambahan xtal pada kaki 4 dan 5 serta
masing kaki xtal dihubungkan ke GND oleh
capacitor 22pf
*/
#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int jam=0, min=0, detik=0;
void segmen (int angka)
{
switch (angka)
{
case 0 : { PORTB =0b1000000; break ; }
case 1 : { PORTB =0b1111001; break ; }
case 2 : { PORTB =0b0100100; break ; }
case 3 : { PORTB =0b0110000; break ; }
case 4 : { PORTB =0b0011001; break ; }
case 5 : { PORTB =0b0010010; break ; }
case 6 : { PORTB =0b0000010; break ; }
case 7 : { PORTB =0b1111000; break ; }
case 8 : { PORTB =0b0000000; break ; }
case 9 : { PORTB =0b0010000; break ; }
case 10 : { PORTB =0b1111111; break ; } //blank biar ga berbayang
}
}
ISR(TIMER1_COMPA_vect)
{
detik ++;
if ( detik == 60)
{ detik=0;
min++;
}
if ( min == 60)
{ min = 0;
jam++ ;
}
if (jam == 24) jam=0;
}
int main(void)
{
int digit;
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 62499; //compare the CTC A
TCCR1B |= (1 << CS11)|(1 << CS10); // Start timer at Fcpu/64
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6);
DDRD |= (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3) |(1<<PD6);
DDRD &= ~(1<<PD4) & ~(1<<PD5) ;
sei();
while(1)
{
if(TCNT1 < 31250) PORTD |=(1<<PD6) ;
else PORTD &=~(1<<PD6) ;
segmen(10);
digit = jam/10;
PORTD |= (1<<PD0);
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
segmen(10);
digit = jam%10;
PORTD |= (1<<PD1);
PORTD &= ~(1<<PD0) & ~(1<<PD2) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
segmen(10);
digit = min/10;
PORTD |= (1<<PD2);
PORTD &= ~(1<<PD1) & ~(1<<PD0) & ~(1<<PD3) ;
segmen(digit);
_delay_ms(5);
segmen(10);
digit = min%10;
PORTD |= (1<<PD3);
PORTD &= ~(1<<PD1) & ~(1<<PD2) & ~(1<<PD0) ;
segmen(digit);
_delay_ms(5);
if (bit_is_set(PIND, PIND4))
{
jam++;
if(jam==24) jam =0;
_delay_ms(100);
}
if (bit_is_set(PIND, PIND5))
{
min++;
if(min==60) min=0;
_delay_ms(100);
}
}
return 0;
}
hasilnya dapat dilihat seperti berikut :
bisa gak pake 4 ic 4026 truss 4 ne 555 (4x dadu digital) nanti kecepatannya kita atur pake potensiometer
BalasHapusjadi gak usah pakai program
BalasHapusbuat shinjiru ...bisa aja ..4026 nya di cascade (googling aja) , tapi digitnya sampe 99 ( kalo pake 2biji 4026) ntar...susahnya harus bikin pendeteksi digit "60" ato "24" trus biar di reset ...ini yang agak ribet ..
BalasHapusthank's
BalasHapustutorialnya
bikin kaya gini abis berapa mas ?
BalasHapusya tergantung belanja komponennya dimana, kalo diaku dijamin murah...praktek ini sudah ada di paket belajar yang bisa dibeli di link kanan atas broo...
BalasHapusKomentar ini telah dihapus oleh pengarang.
BalasHapusmas itu yg "TCCR1B |= (1<<CS10) | (1<<CS11) ;"
BalasHapusbukannya prescaler 64 cma pake CS11 ya ??...
coba cek dulu datasheet attiny2313 ...kayaknya saya bener dehh
BalasHapusmaaf mas.. sya lihatnya di post timer dan counter... prescaler di post itu memang dibuat salah ya ??
BalasHapusKomentar ini telah dihapus oleh pengarang.
BalasHapusAtur fusebitNya jdi sprti ap .mas Nyoman yudi
BalasHapus