Subscribe via email

Enter your email address:

Delivered by FeedBurner

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:
image
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:
image 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
******************

jika ada yg kurang dari artikel di atas mohon kritik dan sarannya

any questions?? post comment on this blog: http://avrku.blogspot.com
or send email to: [email protected]

CodeVisionAVR C Compiler is copyright by Pavel Haiduc, HP InfoTech s.r.l.
AVR is a registered trademark of Atmel Corporation.

Comments :

7 comments to “PWM menggunakan TIMER 0”

koyok'e tau kethok...........
hahahahaaaaaaaa

maziidul mengatakan...
on 

wakakkakakkaaa.... lha iki wong e sing duwe gawe muncul ^_^ V

zigan mengatakan...
on 

klu pwm pake asm gmna mas?

Anonim mengatakan...
on 

mas, bedanya pengendalian PWM dengan TCNT0 ama OCR0 apa mas?saya baca dari referensi lain, pengendalian PWMnya ada yang menggunakan perubahan nilai OCR,makasih mas...

prezst mengatakan...
on 

apiiikkkk.....

Mas... share tutorial membangkitkan pulsa SPWM dengan metode timer duoonkk......

katanya lebih presisi dng timer drpd lookup table yah...?

Nt_delove mengatakan...
on 

kalau untuk yang lookup table ak belum pernah nyoba.. kalau ada monggo di share disni.. nanti kita praktekin bareng2... ^_^

zigan mengatakan...
on 

tolong kalau cara membaca sinyal interrrupt yang dimasukan pada pin INT0 kemudian sinyal nya di keluarkan pada pin OCR1A tetapi disa di atur lebar waktu On dan Off nya..
soal nya saya ingin membuat pengatur tegangan AC yang menggunakan ZCD sebagai Interrupt nya...
masih bingung hehe.. tolong d bantu ya... terimakasih..
[email protected]

Pebriyadi mengatakan...
on