P. 1
Pengenalan PWM

Pengenalan PWM

|Views: 630|Likes:
Published by apyf

More info:

Published by: apyf on Jun 25, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOCX, PDF, TXT or read online from Scribd
See more
See less

06/21/2013

pdf

text

original

Pengenalan

Pengaturan lebar pulsa modulasi atau PWM merupakan salah satu teknik yang ³ampuh´ yang digunakan dalam sistem kendali (control system) saat ini. Pengaturan lebar modulasi dipergunakan di berbagai bidang yang sangat luas, salah satu diantaranya adalah: speed control (kendali kecepatan), power control (kendali sistem tenaga), measurement and communication (pengukuran atau instrumentasi dan telekomunikasi). Di dalam tutorial yang akan saya bahas kali ini akan mengajak anda mengenal dasar-dasar PWM dan implementasi PWM dengan menggunakan microcontroller.

Prinsip Dasar PWM
Modulasi lebar pulas (PWM) dicapai/diperoleh dengan bantuan sebuah gelombang kotak yang mana siklus kerja (duty cycle) gelombang dapat diubah-ubah untuk mendapatkan sebuah tegangan keluaran yang bervariasi yang merupakan nilai rata-rata dari gelombang tersebut. Lebih jelasnya mari kita simak gambar dibawah ini,

Ton adalah waktu dimana tegangan keluaran berada pada posisi tinggi (baca: high atau 1) dan, Toff adalah waktu dimana tegangan keluaran berada pada posisi rendah (baca: low atau 0). Anggap Ttotal adalah waktu satu siklus atau penjumlahan antara Ton dengan Toff , biasa dikenal dengan istilah ³periode satu gelombang´.

0592MHz. Dia menggunakan ATmega 16 dengan crystal 11. 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.Siklus kerja atau duty cycle sebuah gelombang di definisikan sebagai. sehingga: Dari rumus diatas dapat ditarik kesimpulan bahwa tegangan keluaran dapat diubah-ubah secara langsung dengan mengubah nilai Ton. Tegangan keluaran dapat bervariasi dengan duty-cycle dan dapat dirumusan sebagai berikut. Dia pengen 2 signal PWM. PWM menggunakan TIMER 0 Seorang temen meminta saran tentang bagaimana menghasilkan signal PWM menggunakan microcontroller AVR. mari kita kita lihat pada implementasi praktek dari teori PWM tersebut diatas pada sebuah microcontroller. Vout juga akan 0. Apabila Ton adalah 0. Jadi untuk mengatur lebar . Tapi masalahnya ada delay antara 2 signal tersebut. Apabila Ton adalah Ttotal maka Vout adalah Vin atau katakanlah nilai maksimumnya. Sekarang. Penjelasan tersebut diatas merupakan keseluruhan dari teori dasar dibalik sistem PWM. inverting dan non inverting.

time_value++. signal PWM yang dihasilkan nampak seperti berikut: Code program yang digunakan: #include <mega16. // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0xd4. Rumus yg digunakan untuk mengatur waktu interrupt Timer 0 adalah: TCNT0=(1+0xFF) ± (waktu * (XTAL/PRESCALER)) nilai ³waktu´ adalah waktu interrupt yang kita inginkan.7 unsigned int time_value. Akhirnya kita coba pake interrupt Timer 0. Namun kita kesulitan dalam setting delay antara 2 signal. Dalam kasus ini kita menggunakan XTAL (crystal) 11. Sesuai dengan karakter sistem diatas maka nilai yang diisikan ke TCNT0 adalah: TCNT0=256-(0.3 #define Ch2 PORTD.PWM tinggal mengubah nilai OCR. } if(time_value<=1) { . if(time_value>=20) { time_value=0.001*43200) =212.0592 MHz dengan waktu interrupt 1 millisecond dan prescaler 256(bingung nilai prescaler itu apa??? klik disini). Disini interrupt diatur tiap 1 millisecond.8 TCNT0=0xD4 (format heksadesimal) Dengan menggunakan interrupt timer 0 .h> #define Ch1 PORTB.

} // Declare your global variables here void main(void) { PORTA=0x00. } else { Ch1=0. // Analog Comparator initialization . DDRC=0x00. PORTC=0x00. PORTD=0x00. DDRD=0xff. // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01. } if((time_value>=1)&(time_value<=9)) { Ch1=1.//--------->nilai ini utk menset nilai prescaler 256 TCNT0=0xd4.(waktu *( XTAL / prescaler) ) //waktu yg diinginkan 1 ms OCR0=0x00.//-------> nilai dari rumus TCNT = (1+0xFF) . PORTB=0x00. } if(time_value<=10) { Ch2=0. } else { Ch2=1. // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 43. DDRA=0x00.200 kHz ---> XTAL/prescaler // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x04.Ch1=0. DDRB=0xff.

3 #define Ch2 PORTD. mendefinisikan variabel bertipe unsigned integer dengan nama ³time_value´.h> #define Ch1 PORTB. unsigned int time_value.// Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80.5(OC1A).3(OC0). PORTD. biar lebih gampang diinget. Ch1 ato Ch2 bisa diubah sesuka hati misal: ChannelA. PORT yang digunakan pun terserah anda. // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { ««««. . varibel time_value ini yang nantinya dijadikan acuan dalam menghasilkan sinyal PWM. ChannelB dan seterusnya«. PORTD. sekarang saatnya memenggal code-code program diatas: #include <mega16. Tinggal diganti aja. SFIOR=0x00.4(OC1B).3 diganti namanya menjadi Ch1 PORTD.7(OC2). Disini enaknya menghasilkan PWM pake interrupt timer.. } YOOO..h> menyertakan file library mega16. PORTD.)>_<.7 diganti namanya menjadi Ch2 Ini untuk memudahkan penulisan program aja.h karena kita menggunakan ATmega16 klo menggunakan ATmega 8535 ya tinggal diganti #include<mega8535.7 PORTB. // Global enable interrupts #asm("sei") while (1) { // Place your code here }. port yg di pakai tidak harus menggunakan port PWM microcontroller (port PWM micrcontroller atmega 16 adalah: PORTB.

. nilai ini yg menentukan interval waktu terjadinya interrupt time_value++. } else { Ch1=0. if(time_value>=20) { time_value=0. } if((time_value>=1)&(time_value<=9)) { Ch1=1. } code di atas untuk menghasilkan PWM di Ch1 (PORTB. setiap terjadi interrupt nilai time_value ditambah 1. } code-code program yg ada di antara 2 kurung kurawal itu yang dijalankan jika terjadi interrupt Timer 0 TCNT0=0xd4. } jika nilai time_value lebih atau sama dengan 20 maka nilai time_value di ³nol´ kan if(time_value<=1) { Ch1=0. nilai TCNT diisi nilai yg dihasilkan dari ³rumus´ (rumus diawal artikel).«««««.3) sesuai dengan nilai variabel time_value.

setting port microntroller mau dijadikan input atau output.//-------> nilai dari rumus TCNT = (1+0xFF) .//--------->nilai ini utk menset nilai prescaler 256 TCNT0=0xd4. ««««. DDRD=0xff. PORTC=0x00. PORTA=0x00. } else { Ch2=1. . DDRB=0xff.7) sesuai dengan nilai variabel time_value. DDRA=0x00.(waktu *( XTAL / prescaler) ) //waktu yg diinginkan 1 ms OCR0=0x00. PORTD=0x00. PORTB=0x00. // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 43. program utama yang selalu dijalankan microcontroller.200 kHz ---> XTAL/prescaler // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x04. ««««« } main program. } code di atas untuk menghasilkan PWM di Ch2 (PORTD.if(time_value<=10) { Ch2=0. void main(void) { «««. DDRC=0x00..

.... maka alur program mikro akan muter2 lagi di infinite looping ****************** .......inisialisasi timer 0 sesuai rumus........ lha kok bisa????? bingungg...... mikro hanya muter disini di dalam while(1){.......... (inget !!! infinite looping di artikel BASIC I/O ).}...................... .... SFIOR=0x00...... ACSR=0x80.. saat terjadi Interrupt Timer0. inisialisasi interrupt Timer 0.............yoww. ~_~ ! Disinilah bedanya pake Interrupt!!... alur program mikro akan meloncat ke: interrupt [TIM0_OVF] void timer0_ovf_isr(void) { . Jadi mikro sama sekali tidak mengeksekusi perintah... program yg ada disini yg dijalanin.... TIMSK=0x01..... infinite looping... ...... } setelah program yg ada di sub rutin INTERRUPT dijalankan. me ³non-aktifkan´ analog comparator #asm("sei") mengaktifkan interrupt while (1) { // Place your code here }.

. Artikel kali ini akan membahas TIMER 1. 256 . AVR yang saya pakai sebagai contoh adalah ATmega 8535. timer juga jalan sendiri (digerakkan XTAL). Hitung jumlah instruksi yg kita tulis. 64 . Misal saat mau nampilin rpm. Atau untuk menghidupkan device dengan interval tertentu.(waktu *( XTAL / prescaler) ) waktu --> waktu yg kita inginkan XTAL --> frekuensi xtal yg dipakai prescaler --> nilai prescaler Apa nilai prescaler itu? Timer membutuhkan clock source. Macam2 nilai prescaler yg diijinkan: 1.Bermain dengan Timer 1 AVR Yang namanya timer sering kali kita gunakan. Nah nilai pembagi (1024) ini yg disebur nilai prescaler.. kita butuh timer sebagai acuan. Karena saat program dijalanin. Hmmmm. Dengan Interrupt kita gak perlu susah2 menghitung berapa waktu yang di perlukan untuk meng eksekusi seluruh program kita. TIMER 0 (8 bit) 2. Dulu ak disaranin klo timer mau presisi harus memakai bahasa assembly. register TCNT sendiri dibagi dua: TCNT 1 H dan TCNT 1 L. Pada ATmega8535 timer jenis 16 bit adalah TIMER 1. 8 . Register yg biasa saya gunakan untuk menset nilai Timer1 adalah register TCNT. 1024 . lalu hitung lama waktunya. minimum XTAL/1024. Maximum sama dengan XTAL. AVR ini memilki 3 timer. Yaitu: 1. rumus yang digunakan adalah : TCNT = (1+0xFFFF) . Trus saat nilai tercapai terjadilah interrupt timer. TIMER 1 (16 bit) 3.. Biasanya clock source yg saya pakai adalah clock sistem (XTAL). TIMER 2 (8 bit) Apa yang dimaksud timer 8 bit dan 16 bit? timer 8 bit adalah timer yg bisa mencacah/menghitung sampai maksimal nilai 0xFF heksa (dalam biner = 1111 1111). ribet bener. Dan kita bisa menset besarnya nilai ini. Untung aja nemu artikel tentang interrupt timer. Pada ATmega 8535 ada 2 timer jenis ini yaitu TIMER 0 dan 2 Klo yg 16 bit nilai maksimalnya 0xFFFF.

unsigned long detik.113 Contoh Program: Mengakses Timer 1 dengan interval waktu 1 detik. kita harus merubah nilai register TCCR1B bit 0. #include <mega8535."detik %d".h> #include <stdio. TCNT1L=0xF7.equ __lcd_port=0x18 #endasm #include <lcd.2 gambar diatas di ambil dari data sheet ATmega 8535 hal. detik++.h> unsigned char buff[30]. lcd_puts(buff)..detik).. sprintf(buff.Untuk mengubah nilai prescaler timer 1. lcd_clear().h> // LCD di PORT B #asm . } . // sub rutin saat terjadi interrupt Timer 1 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { TCNT1H=0xC2.

. // Noise Canceler: Off // Input Capture on Falling Edge TCCR1A=0x00. // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off // Analog Comparator Output: Off ACSR=0x80. OCR1AH=0x00. // Global enable interrupts #asm("sei") lcd_putsf("wait. OCR1BL=0x00. // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x04. TCNT1H=0xC2. OCR1BH=0x00. // OC1B output: Discon. while (1) { }. SFIOR=0x00.. } Program di atas menggunakan timer 1 untuk menambah nilai variabel "detik" setiap 1 detik sekali. // LCD module initialization lcd_init(16). ayo kita mutilasi code program di atas: yang akan kita bahas dari program diatas adalah code yang kliatan ruwet aja. TCCR1B=0x04. TCNT1L=0xF7. OCR1AL=0x00."). Klo yg biasa silahkan lihat .void main(void) { // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: kHz // Mode: Normal top=FFFFh // OC1A output: Discon. Kemudian menampilkan hasilnya ke LCD.

TCNT1L=0xF7.. TCNT1L=0xF7. --------------------------->menampilkan karakter-karakter variabel buff ke LCD } Saat kita ingin menampilkan sederet tulisan ke LCD maka kita harus memasukkan karakter-karakter tulisan itu ke suatu variabel array (dalam program di atas adalah variabel "buff").agar Timer 1 bernilai 1 detik . ------------------> nilai didapat dari rumus .. Baru kemudian data yg ada di variabel array kita tampilkan ke LCD *************** void main(void) { // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: kHz // Mode: Normal top=FFFFh // OC1A output: Discon. ----------------------> nilai didapat dari rumus ... lcd_clear()."detik %d".detik).agar Timer 1 bernilai 1 detik detik++.h> --------------->> library untuk fungsi2 akses LCD ************** // sub rutin saat terjadi interrupt Timer 1 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { TCNT1H=0xC2. // OC1B output: Discon.. // Noise Canceler: Off // Input Capture on Falling Edge TCCR1A=0x00.. sprintf(buff.. --------------> memasukkan karakter-karakter ke variabel buff lcd_puts(buff). ^_^ ************** // LCD di PORT B #asm ..... ------------------> .... TCCR1B=0x04.di artikel2 sebelumnya .... ----------------------> .equ __lcd_port=0x18 -------------->> mendefinisakan bahwa LCD di hubungkan ke PORT B #endasm #include <lcd. ------------------> prescaler 256 TCNT1H=0xC2.

Overflow Interrupt Enable code di atas hanya men set "Overflow Interrupt Timer 1". ----------------------> inisialisasi LCD 16*2 ******************* // Global enable interrupts #asm("sei") ----------------------> meng aktifkan Interrupt-interrupt yg sudah di set sebelumnya Nah.... 2 angka yg di depan kita masukkan ke TCNT1H dan 2 angka yg dibelakang kita masukkan ke TCNT1L **************** // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x04. ----------------->Timer/Counter1. sebaiknya analog comparator di OFF..inget rumus: TCNT = (1+0xFFFF) . Untuk menghemat pemakaian daya.(waktu *( XTAL / prescaler) ) waktu yg dinginkan adalah 1 detik ... ketika saya coba untuk ATmega 162 nilai TIMSK diubah menjadi TIMSK=0x80..(1detik*15625) =65536-15625 = 49911 (desimal) = C2F7 (heksadesimal) Nilai untuk TCNT yang di dapat dari rumus bernilai 16bit (4 angka Heksadesimal).. ******************* // LCD module initialization lcd_init(16). Interrupt baru aktif saat ada perintah: #asm("sei") pada contoh ini saya pake ATmega 8535. pada saat ini interrupt Timer 1 aktif ******************* . Hal ini sangat penting jika sumber daya yg digunakan memakai baterai.. **************** // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off // Analog Comparator Output: Off ACSR=0x80. jika tidak dipakai. TCNT= (1+65535)-(1detik * (4. XTAL yg saya pakai adl 4 Mhz dan nilai prescaler=256 Jadi.... ------------> me OFF kan analog comparator SFIOR=0x00..000.....000/256)) =65536 .

... --------------> menampilkan tulisan wait..........")............... Program ini yg dijalankan oleh microcontroller... program yg ada disini yg dijalanin..lcd_putsf("wait..... maka alur program mikro akan muter2 lagi di infinite looping ****************** ... alur program mikro akan meloncat ke: // sub rutin saat terjadi interrupt Timer 1 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { .........}...... lha kok bisa????? bingungg.............. ~_~ ! Disinilah bedanya pake Interrupt!!......... ke LCD ********************* while (1) { }..... (inget !!! infinite looping di artikel BASIC I/O ). saat terjadi Interrupt Timer1... ... } setelah program yg ada di sub rutin INTERRUPT dijalankan.........yoww...... Jadi mikro sama sekali tidak mengeksekusi perintah..... mikro hanya muter disini di dalam while(1){....

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->