Interrupt Timer1 di AVR ATmega16 (PWM 16bit 2 Kanal)

Dah lama rasanya tidak posting yang berhubungan dengan Robotik. Maklum sibuk aktifitas *Sombong beud ya*ūüėÄ. Pi, sekarang kita bahas cara konfigurasi pwm pada ATmega16. Coz, masih banyak yang menanyakan di laboratorium robotika atau bengkel. Seperti postingan sebelum2ny software yang digunakan yaitu CodeVisionAVR. Biar cepet codingnya, kita gunakan CodeWizardAVR. Untuk lebih jelasnya tentang PWM bisa di klik di sini. He…he… Pake bahasa inggris yach. di translate aja pake google translate. Perlu diperhatikan, untuk dapat memutar motorDC memerlukan 2 kanal. Dua kanal tersebut berada di portD 4 dan portD 5. Bila di asumsikan, menggunakan driver motor l298. hubungkan 2 kaki Enable pada L298 ke portD4 dan portD5 AVR16. jangan lupa hubungkan input direction L298 pada portD yang jaraknya dekat dengan portD4 dan portD5.

 

ATmega16
ATmega16

okeh…. kita masuk ke tahap konfigurasi pada CodeWizardAVR. Penulis pake AVR ATmega16 dengan Xtal/Kristal 4Mhz.

Atur CodeWizardAVR seperti gambar di bawah ini

Tambahkan definisikan setiap port directionnya. seperti dibawah ini.
#define dir4                PORTD.0
#define dir3                PORTD.1
#define dir2                PORTD.2
#define dir1                PORTD.3
Selanjutnya buat void untuk menggerakkan motorDC tersebut maju. Seperti dibawah ini.
void maju()
{
 dir1=0;dir2=1;
 dir3=1;dir4=0;
 // en1=1;en2=1;
}
Setelah void terbuat. Maka untuk nilai pwm, kita harus memberikan nilai ke dalam OCR1A dan OCR1B. Jangan lupa memberikan tipe data unsigned int pada lpwm dan rpwm. perlu diingat lebar data untuk tipe data tersebut antara 0-65000, he…he… mudah2an bener. Seperti dibawah ini.
unsigned int rpwm,lpwm;
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
 OCR1A=rpwm;
 OCR1B=lpwm;
}
kita ubah nilai ICR1H dan ICR1L
karena kita menggunakan clock valuenya sebesar 4000.000 KHz maka jika dijadikan Mhz didapat 4000 Mhz. kemudian rubah menjadi hexa pada kalkulator.
nilainya FA0. nilai A0 untuk ICR1L dan tambahkan (0) “nol” dibelakang F. maka menjadi 0F untuk ICR1H. Seperti dibawah ini.
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 4000.000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA2;
TCCR1B=0x19;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x0F;
ICR1L=0xA0;
langkah terakhir yaitu kita panggil void maju beserta nilai rpwm dan lpwm. seperti dibawah ini.
while (1)
 {
 // Place your code here
 maju();
 lpwm=10000;
 rpwm=5000;
 };
Flash program ke AVR16 .
berikut program keseluruhannya.
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.3 Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 12/15/2010
Author  : l4g14s1k
Company : l4g14s1k
Comments:

Chip type           : ATmega16
Program type        : Application
Clock frequency     : 4.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include <mega16.h>
#define dir4                PORTD.0
#define dir3                PORTD.1
#define dir2                PORTD.2
#define dir1                PORTD.3

#define sensor              PINA

// Declare your global variables here
void maju()
{
 dir1=0;dir2=1;
 dir3=1;dir4=0;
 // en1=1;en2=1;
}

void kanan()
{
 dir1=0;dir2=1;//motor kiri
 dir3=0;dir4=0;//motor kanan

}

void kiri()
{
 dir1=0;dir2=0;//motor kiri
 dir3=1;dir4=0;//motor kanan

}

// Timer 1 overflow interrupt service routine
unsigned int rpwm,lpwm;
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
 OCR1A=rpwm;
 OCR1B=lpwm;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 4000.000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA2;
TCCR1B=0x19;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x0F;
ICR1L=0xA0;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")

while (1)
 {
 // Place your code here
 maju();
 lpwm=10000;
 rpwm=5000;
 };
}
Selamat Mencoba !!!!

8 thoughts on “Interrupt Timer1 di AVR ATmega16 (PWM 16bit 2 Kanal)”

  1. program di atas gak jalan..
    menurut saya maksudnya pwm 16 bit itu pwm 8 bit untuk OCR1A ditambah pwm 8 bit untuk OCR1B, bukan setiap OCR1A nya 16 bit..
    program di atas sudah saya coba simulasikan dan ternyata tidak berhasil..

    tapi gak tahu kalo punya mas nya berhasil.. monggo dijelaskan di sini.. trims..

    1. Programnya sudah saya terapkan di robot saya. hasilnya range nilai pwm lebar. coba cek datasheet ATmeganya. disitu tertera 16 bit bukan 8 bit perkanal. semoga membantu….

  2. nilai ICR1H (0x0F) dan ICR1L (0xA0) di atas memberikan nilai maksimal (pwm 100%) sebesar 4000 saja pada OCR1A dan OCR1B nya, Di atas 4000 itu pwm bernilai maksimal atau100%.

    setelah saya ganti , ICR1H = 0xFF dan ICR1L = 0xFF, hasilnya OCR1A maupun 0CR1B bisa memiliki range 16 bit (maksimal 65535 desimal).
    PROGRAM BERHASIL

  3. maaf mas kalau saya pake h-bridge mosfet yang inputnya ada dua input 1 dan input 2 dimasukkan ke port yang mana soalnya saya dah coba dimasukkan ke portD 4,5 tapi motornya gak jalan trs tak pindah 2,3 tetep aja gak jalan
    mohon pencerahannya

  4. gan itu kalo mau belok kanan terus maju dan kemudian mundur gimana saya kasih delay di while ga mau mohon bantuannya masih newbie saya

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s