Dalam proyek ini kita akan merancang jam Alarm sederhana menggunakan timer ATMEGA 32 . Mikrokontroler ATmega32A memiliki timer 16 bit, dan kita akan menggunakan timer tersebut untuk menghitung detik dan mengembangkan jam digital.
Semua jam digital memiliki kristal di dalamnya yang merupakan jantung dari jam. Kristal ini tidak hanya hadir di jam tetapi hadir di semua sistem komputasi Real time. Kristal ini menghasilkan pulsa clock, yang diperlukan untuk perhitungan waktu. Meskipun ada beberapa cara lain untuk mendapatkan pulsa jam tetapi untuk akurasi dan frekuensi yang lebih tinggi kebanyakan lebih memilih jam berbasis kristal. Saya akan menghubungkan kristal ke ATMEGA32 untuk mendapatkan jam yang akurat.
Komponen yang Diperlukan
Perangkat keras: Mikrokontroler ATmega32, kristal 11,0592MHz, Kapasitor 22pF (2 buah), Catu daya (5v), PROGRAMMER AVR-ISP, JHD_162ALCD(LCD 16x2), kapasitor 100uF (terhubung melintasi catu daya), tombol (empat buah), resistor 10KΩ (enam buah), 100nF capacito r(empat buah), Tiga pin switch (2 buah), transistor 2N2222, Buzzer, resistor 200Ω.
Perangkat lunak: Atmel studio 6.1, progisp atau flash magic.
Diagram Sirkuit dan Penjelasan Kerja
Untuk pengaturan waktu yang akurat, saya telah menghubungkan kristal 11,0592MHz untuk jam. Sekarang untuk menonaktifkan clock internal ATMEGA kita harus mengubah LOW FUSE BITS-nya. Ingat kita tidak menyentuh bit sekering tinggi sehingga komunikasi JTAG akan tetap diaktifkan.
Untuk memberi tahu ATMEGA untuk menonaktifkan jam internal dan untuk bekerja pada eksternal, kita perlu mengatur:
PENGGUNAAN BYTE RENDAH = 0xFF atau 0b111111111.
Pada rangkaian PORTB ATMEGA32 terhubung ke LCD port data. Di sini kita harus ingat untuk menonaktifkan komunikasi JTAG di PORTC ATMEGA dengan mengubah byte sekering tinggi, jika seseorang ingin menggunakan PORTC sebagai port komunikasi normal. Pada LCD 16x2 ada 16 pin di atas semua jika ada lampu hitam, jika tidak ada lampu belakang akan ada 14 pin. Seseorang dapat memberi daya atau meninggalkan pin lampu belakang. Sekarang di 14 pin ada 8 data pin (7-14 atau D0-D7), 2 pin power supply (1 & 2 atau VSS & Vdd atau gnd & + 5V), 3 rd pin untuk kontrol kontras (VEE-kontrol seberapa tebal karakter harus ditunjukkan), dan 3 pin kontrol (RS&RW&E)
Di sirkuit, Anda dapat mengamati bahwa saya hanya mengambil dua pin kontrol. Hal ini memberikan fleksibilitas pemahaman yang lebih baik, bit kontras dan READ/WRITE tidak sering digunakan sehingga dapat dikorsletingkan ke ground. Ini menempatkan LCD dalam mode kontras dan baca tertinggi. Kita hanya perlu mengontrol pin ENABLE dan RS untuk mengirim karakter dan data yang sesuai.
Koneksi yang dilakukan untuk LCD diberikan di bawah ini:
PIN1 atau VSS ke ground
PIN2 atau VDD atau VCC ke daya +5v
PIN3 atau VEE ke ground (memberikan kontras maksimum terbaik untuk pemula)
PIN4 atau RS (Register Selection) ke PD6 dari uC
PIN5 atau RW (Baca/Tulis) ke ground (menempatkan LCD dalam mode baca memudahkan komunikasi bagi pengguna)
PIN6 atau E (Aktifkan) ke PD5 dari uC
PIN7 atau D0 ke PB0 dari uC
PIN8 atau D1 ke PB1 dari uC
PIN9 atau D2 ke PB2 dari uC
PIN10 atau D3 ke PB3 dari uC
PIN11 atau D4 ke PB4 dari uC
PIN12 atau D5 ke PB5 dari uC
PIN13 atau D6 ke PB6 dari uC
PIN14 atau D7 ke PB7 dari uC
Di sirkuit ini terlihat, saya telah menggunakan komunikasi 8 bit (D0-D7) namun ini tidak wajib, saya dapat menggunakan komunikasi 4bit (D4-D7) tetapi dengan program komunikasi 4 bit menjadi sedikit rumit. Jadi seperti yang ditunjukkan pada tabel di atas saya menghubungkan 10 pin LCD ke pengontrol di mana 8 pin adalah pin data dan 2 pin untuk kontrol.
Sakelar satu adalah untuk mengaktifkan fitur penyesuaian antara alarm dan waktu. Jika pin rendah, kita dapat mengatur waktu alarm dengan menekan tombol. Jika tombol tingginya hanya untuk menyesuaikan WAKTU. Ada EMPAT tombol yang ada di sini, yang pertama adalah untuk menambah MENIT dalam alarm atau waktu. Kedua adalah untuk mengurangi MENIT dalam alarm atau waktu. Ketiga adalah untuk kenaikan JAM dalam alarm atau waktu. KEEMPAT adalah untuk pengurangan JAM dalam alarm atau waktu.
Kapasitor yang ada di sini adalah untuk meniadakan efek pantulan tombol. Jika dilepas, pengontrol mungkin menghitung lebih dari satu setiap kali tombol ditekan. Resistor yang terhubung untuk pin adalah untuk membatasi arus, ketika tombol ditekan untuk menarik pin ke tanah.
Setiap kali sebuah tombol ditekan, Pin pengontrol yang sesuai ditarik ke bawah ke ground dan dengan demikian pengontrol mengenali bahwa tombol tertentu ditekan dan tindakan yang sesuai diambil.
Pertama-tama, jam yang kita pilih di sini adalah 11059200 Hz, membaginya dengan 1024 menghasilkan 10800. Jadi untuk setiap detik kita mendapatkan 10800 pulsa. Jadi kita akan memulai pencacah dengan 1024 prescaler untuk mendapatkan jam pencacah sebagai 10800 Hz. Kedua kita akan menggunakan mode CTC (Clear Timer Counter) dari ATMEGA. Akan ada register 16 bit di mana kita dapat menyimpan nilai (nilai bandingkan), ketika penghitung menghitung hingga nilai perbandingan, interupsi diatur untuk dihasilkan.
Kami akan menetapkan nilai perbandingan ke 10800, jadi pada dasarnya kami akan memiliki ISR (Interrupt Service Routine pada setiap perbandingan) untuk setiap detik. Jadi kita akan menggunakan rutinitas tepat waktu ini untuk mendapatkan jam yang kita butuhkan.
BROWN(WGM10-WGM13): Bit ini untuk memilih mode operasi untuk timer.
Sekarang karena kita menginginkan mode CTC dengan nilai perbandingan dalam byte OCR1A, kita hanya perlu mengatur WGM12 menjadi satu, sisanya dibiarkan karena nilainya nol secara default.
RED (CS10,CS11,CS12): Ketiga bit ini untuk memilih prescalar dan mendapatkan counter clock yang sesuai.
Karena kita menginginkan 1024 sebagai prescaling, kita harus mengatur CS12 dan CS10.
Sekarang ada register lain yang harus kita pertimbangkan:
GREEN (OCIE1A): Bit ini harus diset untuk mendapatkan interupsi pada kecocokan perbandingan antara nilai counter dan nilai OCR1A(10800) yang kita set.
Nilai OCR1A (nilai pembanding counter), ditulis pada register di atas.
Penjelasan Pemrograman
Cara kerja jam Alarm dijelaskan langkah demi langkah dalam kode di bawah ini:
#include <avr/io.h> //header to enable data flow control over pins #define F_CPU 1000000 //telling controller crystal frequency attached #include <util/delay.h> //header to enable delay function in program #define E 5 //giving name “enable” to 5th pin of PORTD, since it Is connected to LCD enable pin #define RS 6 //giving name “registerselection” to 6th pin of PORTD, since is connected to LCD RS pin void send_a_command(unsigned char command); void send_a_character(unsigned char character); void send_a_string(char *string_of_characters); ISR(TIMER1_COMPA_vect); static volatile int SEC =0;//allocating integer memory for storing seconds static volatile int MIN =0;// allocating integer memory for storing minutes static volatile int HOU =0;// allocating integer memory for storing hours int main(void) { DDRA = 0b11000000;//only pin7 and pin8 of port a as output DDRD = 0xFF; _delay_ms(50);//giving delay of 50ms DDRB = 00FF;//Taking portB as output. TCCR1B |=(1<<CS12)|(1<<CS10)|(1<<WGM12);// setting prescale and CTC mode OCR1A=10800;//setting compare value equal to counter clock frequency to get an interrupt every second sei();// enabling global interrupts TIMSK |=(1<<OCIE1A);//compare match interrupt enable char SHOWSEC [2];//seconds displaying character on LCD char SHOWMIN [2];//minutes displaying character on LCD char SHOWHOU [2];// hours displaying character on LCD int ALSEC = 0;//alarm seconds storing memory int ALMIN = 0;//alarm minutes storing memory int ALHOU = 0;//alarm hours storing memory char SHOWALSEC [2];//alarm seconds displaying character on LCD char SHOWALMIN [2];// alarm minutes displaying character on LCD char SHOWALHOU [2];//alarm hours displaying character on LCD send_a_command(0x01); //Clear Screen 0x01 = 00000001 _delay_ms(50); send_a_command(0x38);//telling lcd we are using 8bit command /data mode _delay_ms(50); send_a_command(0b00001111);//LCD SCREEN ON and courser blinking while(1) { itoa(HOU/10,SHOWHOU,10); //command for putting variable number in LCD(variable number, in which character to replace, which base is variable(ten here as we are counting number in base10)) send_a_string(SHOWHOU);// telling the display to show character(replaced by variable number) of first person after positioning the courser on LCD // displaying tens place of hours above itoa(HOU%10,SHOWHOU,10); send_a_string(SHOWHOU); // displaying ones place of hours above send_a_string (":");//displaying character send_a_command(0x80 + 3);// shifting cursor to 4th shell itoa(MIN/10,SHOWMIN,10);///as integer cannot store decimal values, when MIN=9, we have MIN/10 = 0.9(actual), = 0 for CPU(as integer cannot store decimal values) send_a_string(SHOWMIN); // displaying tens place of minutes above itoa(MIN%10,SHOWMIN,10); send_a_string(SHOWMIN); // displaying ones place of minutes above send_a_command(0x80 + 5);// shifting cursor to 6th shell send_a_string (":"); send_a_command(0x80 + 6);// shifting cursor to 7th shell if (bit_is_set(PINA,5))//if alarm pin is high { send_a_string(" ALM:ON ");//show alarm is on if ((ALHOU==HOU)&(ALMIN==MIN)&(ALSEC==SEC))//alarm minute=min //and alarm hours= time hours and alarm seconds= time seconds { PORTA|=(1<<PINB7);//buzzer on } } if (bit_is_clear(PINA,5))//if alarm pin is low { send_a_string(" ALM:OFF");//show alarm is off PORTA&=~(1<<PINB7);//buzzer off } send_a_command(0x80 + 0x40 + 0);// move courser to second line zero position send_a_string ("ALARM:");//show string of characters send_a_command(0x80 + 0x40 + 7);//move to eight position on second line itoa(ALHOU/10,SHOWALHOU,10); send_a_string(SHOWALHOU); itoa(ALHOU%10,SHOWALHOU,10); send_a_string(SHOWALHOU); send_a_command(0x80 + 0x40 +9); send_a_string (":"); send_a_command(0x80 + 0x40 +10); // Showing alarm hours above itoa(ALMIN/10,SHOWALMIN,10); send_a_string(SHOWALMIN); itoa(ALMIN%10,SHOWALMIN,10); send_a_string(SHOWALMIN); send_a_command(0x80 + 0x40+ 12); send_a_string (":"); send_a_command(0x80 + 0x40+ 13); // Showing alarm minutes above itoa(ALSEC/10,SHOWALSEC,10); send_a_string(SHOWALSEC); itoa(ALSEC%10,SHOWALSEC,10); send_a_string(SHOWALSEC); send_a_command(0x80 + 0); // Showing alarm seconds above send_a_command(0x80 + 0);// shifting cursor to 0th position if (bit_is_set(PINA,4)) // if switch is set to adjust TIME { if (bit_is_clear(PINA,0)) //button 1 is pressed { if (MIN<60) { MIN++;//if minutes of TIME are less than 60 increment it by one _delay_ms(220); } if (MIN==60) { if (HOU<24) { HOU++;//if minutes of TIME =60 when button is pressed //and hours of TIME are less than 24, increment hour by one. } MIN=0;//if minute of TIME=60,reset it to zero _delay_ms(220); } } if (bit_is_clear(PINA,1)) { if (MIN>0) { MIN--; //if second button is pressed and minute of TIME are //greater than zero, decrease minutes by one _delay_ms(220); } } if (bit_is_clear(PINA,2)) { if (HOU<24) { HOU++; //if third button is pressed and hours of TIME are less //than 24, increment the hour by one } _delay_ms(220); if (HOU==24) { HOU=0;//if hour of TIME equal to 24, reset hour of TIME } } if (bit_is_clear(PINA,3)) { if (HOU>0) { HOU--;//if fourth button is pressed and hours of TIME are //greater than ZERO, decrement the hour by one _delay_ms(220); } } } if (bit_is_clear(PINA,4))//if alarm adjust is set { if (bit_is_clear(PINA,0)) { if (ALMIN<60) { ALMIN++; _delay_ms(220); } if (ALMIN==60) { if (ALHOU<24) { ALHOU++; } ALMIN=0; _delay_ms(220); } } if (bit_is_clear(PINA,1)) { if (ALMIN>0) { ALMIN--; _delay_ms(220); } } if (bit_is_clear(PINA,2)) { if (ALHOU<24) { ALHOU++; } _delay_ms(220); if (ALHOU==24) { ALHOU=0; } } if (bit_is_clear(PINA,3)) { if (ALHOU>0) { ALHOU--; _delay_ms(220); } } } } } // Everything follows the same as described above for TIME ISR(TIMER1_COMPA_vect) //loop to be executed on counter compare match { if (SEC<60) { SEC++; } if (SEC==60) { if (MIN<60) { MIN++; } SEC=0; } if (MIN==60) { if (HOU<24) { HOU++; } MIN=0; } if (HOU==24) { HOU=0; } } void send_a_command(unsigned char command) { PORTA = command; PORTD &= ~ (1<<RS); //putting 0 in RS to tell lcd we are sending command PORTD |= 1<<E; //telling lcd to receive command /data at the port _delay_ms(50); PORTD &= ~1<<E;//telling lcd we completed sending data PORTA= 0; } void send_a_character(unsigned char character) { PORTA= character; PORTD |= 1<<RS;//telling LCD we are sending data not commands PORTD |= 1<<E;//telling LCD to start receiving command/data _delay_ms(50); PORTD &= ~1<<E;//telling lcd we completed sending data/command PORTA = 0; } } void send_a_string(char *string_of_characters) { while(*string_of_characters > 0) { send_a_character(*string_of_characters++); } }
/* ---- Code for Digital Clock with Alarm using AVR Microcontroller ------ */
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define enable 5
#define registerselection 6
void send_a_command(unsigned char command);
void send_a_character(unsigned char character);
void send_a_string(char *string_of_characters);
ISR(TIMER1_COMPA_vect);
static volatile int SEC =0;
static volatile int MIN =0;
static volatile int HOU =0;
int main(void)
{
DDRA = 0b11000000;
DDRB = 0xFF;
DDRD = 0xFF;
TCCR1B |=(1<<CS12)|(1<<CS10)|(1<<WGM12);
OCR1A=10800;
sei();
TIMSK |=(1<<OCIE1A);
char SHOWSEC [2];
char SHOWMIN [2];
char SHOWHOU [2];
int ALSEC = 0;
int ALMIN = 0;
int ALHOU = 0;
char SHOWALSEC [2];
char SHOWALMIN [2];
char SHOWALHOU [2];
send_a_command(0x01); //Clear Screen 0x01 = 00000001
_delay_ms(50);
send_a_command(0x38);
_delay_ms(50);
send_a_command(0b00001111);
_delay_ms(50);
while(1)
{
itoa(HOU/10,SHOWHOU,10);
send_a_string(SHOWHOU);
itoa(HOU%10,SHOWHOU,10);
send_a_string(SHOWHOU);
send_a_string (":");
send_a_command(0x80 + 3);
itoa(MIN/10,SHOWMIN,10);
send_a_string(SHOWMIN);
itoa(MIN%10,SHOWMIN,10);
send_a_string(SHOWMIN);
send_a_command(0x80 + 5);
send_a_string (":");
send_a_command(0x80 + 6);
itoa(SEC/10,SHOWSEC,10);
send_a_string(SHOWSEC);
itoa(SEC%10,SHOWSEC,10);
send_a_string(SHOWSEC);
if (bit_is_set(PINA,5))
{
send_a_string(" ALM:ON ");
if ((ALHOU==HOU)&(ALMIN==MIN)&(ALSEC==SEC))
{
PORTA|=(1<<PINB7);
}
}
if (bit_is_clear(PINA,5))
{
send_a_string(" ALM:OFF");
PORTA&=~(1<<PINB7);
}
send_a_command(0x80 + 0x40 + 0);
send_a_string ("ALARM:");
send_a_command(0x80 + 0x40 + 7);
itoa(ALHOU/10,SHOWALHOU,10);
send_a_string(SHOWALHOU);
itoa(ALHOU%10,SHOWALHOU,10);
send_a_string(SHOWALHOU);
send_a_command(0x80 + 0x40 +9);
send_a_string (":");
send_a_command(0x80 + 0x40 +10);
itoa(ALMIN/10,SHOWALMIN,10);
send_a_string(SHOWALMIN);
itoa(ALMIN%10,SHOWALMIN,10);
send_a_string(SHOWALMIN);
send_a_command(0x80 + 0x40+ 12);
send_a_string (":");
send_a_command(0x80 + 0x40+ 13);
itoa(ALSEC/10,SHOWALSEC,10);
send_a_string(SHOWALSEC);
itoa(ALSEC%10,SHOWALSEC,10);
send_a_string(SHOWALSEC);
send_a_command(0x80 + 0);
if (bit_is_set(PINA,4))
{
if (bit_is_clear(PINA,0))
{
if (MIN<60)
{
MIN++;
_delay_ms(220);
}
if (MIN==60)
{
if (HOU<24)
{
HOU++;
}
MIN=0;
_delay_ms(220);
}
}
if (bit_is_clear(PINA,1))
{
if (MIN>0)
{
MIN--;
_delay_ms(220);
}
if (bit_is_clear(PINA,2))
{
if (HOU<24)
{
HOU++;
}
_delay_ms(220);
if (HOU==24)
{
HOU=0;
}
}
if (bit_is_clear(PINA,3))
{
if (HOU>0)
{
HOU--;
_delay_ms(220);
}
}
}
if (bit_is_clear(PINA,4))
{
if (bit_is_clear(PINA,0))
{
if (ALMIN<60)
{
ALMIN++;
_delay_ms(220);
}
if (ALMIN==60)
{
if (ALHOU<24)
{
ALHOU++;
}
ALMIN=0;
_delay_ms(220);
}
}
if (bit_is_clear(PINA,1))
{
if (ALMIN>0)
{
ALMIN--;
_delay_ms(220);
}
}
if (bit_is_clear(PINA,2))
{
if (ALHOU<24)
{
ALHOU++;
}
_delay_ms(220);
if (ALHOU==24)
{
ALHOU=0;
}
}
if (bit_is_clear(PINA,3))
{
if (ALHOU>0)
{
ALHOU--;
_delay_ms(220);
}
}
}
}
}
ISR(TIMER1_COMPA_vect)
{
if (SEC<60)
{
SEC++;
}
if (SEC==60)
{
if (MIN<60)
{
MIN++;
}
SEC=0;
}
if (MIN==60)
{
if (HOU<24)
{
HOU++;
}
MIN=0;
}
if (HOU==24)
{
HOU=0;
}
}
void send_a_command(unsigned char command)
{
PORTB = command;
PORTD &= ~ (1<<registerselection);
PORTD |= 1<<enable;
_delay_ms(3);
PORTD &= ~1<<enable;
PORTB = 0xFF;
}
void send_a_character(unsigned char character)
{
PORTB = character;
PORTD |= 1<<registerselection;
PORTD |= 1<<enable;
_delay_ms(3);
PORTD &= ~1<<enable;
PORTB = 0xFF;
}
void send_a_string(char *string_of_characters)
{
while(*string_of_characters > 0)
{
send_a_character(*string_of_characters++);
}
}
Posting Komentar
Posting Komentar