Anda di halaman 1dari 6

PWM menggunakan TIMER 0

Seorang temen meminta saran tentang bagaimana menghasilkan signal PWM menggunakan microcontroller AVR. Dia menggunakan ATmega 16 dengan crystal 11.0592MHz. Dia pengen 2 signal PWM, inverting dan non inverting. Tapi masalahnya ada delay antara 2 signal tersebut. berikut ilustrasi signal PWM yang diinginkan:

t0 : time delay antara 2 signal (1 millisecond) tH : time signal HIGH (9 millisecond) tL: time signal LOW (11 millisecond) Pertama kali ide buat alur programmnya menggunakan Fast PWM. Jadi untuk mengatur lebar PWM tinggal mengubah nilai OCR. Namun kita kesulitan dalam setting delay antara 2 signal. Akhirnya kita coba pake interrupt Timer 0. Disini interrupt diatur tiap 1 millisecond. Rumus yg digunakan untuk mengatur waktu interrupt Timer 0 adalah: TCNT0=(1+0xFF) (waktu * (XTAL/PRESCALER)) nilai waktu adalah waktu interrupt yang kita inginkan. Dalam kasus ini kita menggunakan XTAL (crystal) 11,0592 MHz dengan waktu interrupt 1 millisecond dan prescaler 256(bingung nilai prescaler itu apa??? klik disini). Sesuai dengan karakter sistem diatas maka nilai yang diisikan ke TCNT0 adalah: TCNT0=256-(0.001*43200) =212,8 TCNT0=0xD4 (format heksadesimal) Dengan menggunakan interrupt timer 0 , signal PWM yang dihasilkan nampak seperti

berikut:

Code program yang digunakan:

#include <mega16.h> #define Ch1 PORTB.3 #define Ch2 PORTD.7 unsigned int time_value; // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0xd4; time_value++; if(time_value>=20) { time_value=0; } if(time_value<=1) { Ch1=0; } if((time_value>=1)&(time_value<=9)) { Ch1=1; } else { Ch1=0; } if(time_value<=10) { Ch2=0; } else { Ch2=1; } // Declare your global variables here

void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0xff; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0xff; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 43.200 kHz ---> XTAL/prescaler // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x04;//--------->nilai ini utk menset nilai prescaler 256 TCNT0=0xd4;//-------> nilai dari rumus TCNT = (1+0xFF) - (waktu *( XTAL / prescaler) ) //waktu yg diinginkan 1 ms OCR0=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01; // 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 }; } YOOO.. sekarang saatnya memenggal code-code program diatas: #include <mega16.h> menyertakan file library mega16.h karena kita menggunakan ATmega16 klo menggunakan ATmega 8535 ya tinggal diganti #include<mega8535.h>

#define Ch1 PORTB.3 #define Ch2 PORTD.7 PORTB.3 diganti namanya menjadi Ch1 PORTD.7 diganti namanya menjadi Ch2 Ini untuk memudahkan penulisan program aja, biar lebih gampang diinget. Ch1 ato Ch2 bisa diubah sesuka hati misal: ChannelA, ChannelB dan seterusnya. PORT yang digunakan pun terserah anda. Tinggal diganti aja. Disini enaknya menghasilkan

PWM pake interrupt timer, port yg di pakai tidak harus menggunakan port PWM microcontroller (port PWM micrcontroller atmega 16 adalah: PORTB.3(OC0), PORTD.4(OC1B), PORTD.5(OC1A), PORTD.7(OC2),)>_<.

unsigned int time_value; mendefinisikan variabel bertipe unsigned integer dengan nama time_value. varibel time_value ini yang nantinya dijadikan acuan dalam menghasilkan sinyal PWM.

// Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { .. . } code-code program yg ada di antara 2 kurung kurawal itu yang dijalankan jika terjadi interrupt Timer 0

TCNT0=0xd4; nilai TCNT diisi nilai yg dihasilkan dari rumus (rumus diawal artikel). nilai ini yg menentukan interval waktu terjadinya interrupt

time_value++; setiap terjadi interrupt nilai time_value ditambah 1.

if(time_value>=20) { time_value=0; } jika nilai time_value lebih atau sama dengan 20 maka nilai time_value di nol kan

if(time_value<=1) { Ch1=0; } if((time_value>=1)&(time_value<=9)) {

Ch1=1; } else { Ch1=0; } code di atas untuk menghasilkan PWM di Ch1 (PORTB.3) sesuai dengan nilai variabel time_value.

if(time_value<=10) { Ch2=0; } else { Ch2=1; } code di atas untuk menghasilkan PWM di Ch2 (PORTD.7) sesuai dengan nilai variabel time_value.

void main(void) { .. . } main program, program utama yang selalu dijalankan microcontroller.

PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0xff; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0xff; setting port microntroller mau dijadikan input atau output.

// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 43.200 kHz ---> XTAL/prescaler // Mode: Normal top=FFh

// OC0 output: Disconnected TCCR0=0x04;//--------->nilai ini utk menset nilai prescaler 256 TCNT0=0xd4;//-------> nilai dari rumus TCNT = (1+0xFF) - (waktu *( XTAL / prescaler) ) //waktu yg diinginkan 1 ms OCR0=0x00; inisialisasi timer 0 sesuai rumus.

TIMSK=0x01; inisialisasi interrupt Timer 0.

ACSR=0x80; SFIOR=0x00; me non-aktifkan analog comparator

#asm("sei") mengaktifkan interrupt

while (1) { // Place your code here }; infinite looping. mikro hanya muter disini di dalam while(1){...}; (inget !!! infinite looping di artikel BASIC I/O ).. Jadi mikro sama sekali tidak mengeksekusi perintah. lha kok bisa????? bingungg.... ~_~ ! Disinilah bedanya pake Interrupt!!. saat terjadi Interrupt Timer0, alur program mikro akan meloncat ke:

interrupt [TIM0_OVF] void timer0_ovf_isr(void) { ...................................... ......yoww..... program yg ada disini yg dijalanin... ...................................... } setelah program yg ada di sub rutin INTERRUPT dijalankan, maka alur program mikro akan muter2 lagi di infinite looping ******************

Anda mungkin juga menyukai