Senin, 27 Juni 2011

MEMBUAT SINYAL PWM MENGGUNAKAN TIMER AVR

Mungkin teman-teman semua sudah tau pengertian dari PWM (Pulse Width Modulation), jadi saya tidak akan membahasnya lagi. Disini saya akan menjelaskan beberapa istilah yang berhubungan dengan PWM sehingga nantinya akan mempermudah teman-teman dalam pembuatan sinyal PWM menggunakan Timer pada AVR.


Gambar diatas merupakan sinyal PWM dengan amplitudo 5 volt. Dari gambar diatas dapat diketahui pengertian dari 1 periode gelombang, yaitu lamanya interval waktu dalam 1 panjang gelombang, gambar diatas mempunyai periode 10 ms. sedangkan duty cycle, yaitu lamanya pulsa high (on) selama 1 periode, terlihat bahwa lamanya duty cycle 7 ms. Biasanya duty cycle ditulis dalam satuan persentase (%). Jika dari gambar diatas ingin mengubah duty cycle kedalam persen yaitu:

Duty cycle = (interval pulsa high dalam 1 periode/periode gelombang)*100%
Sehingga gambar diatas mempunyai duty cycle sebesar 70%.

Jika periode suatu gelombang diketahui, maka dapat dihitung berapa frekuensinya, menggunakan:
F=1/T

F = Frekuensi (Hz)
T = Periode (detik)

Maka frekuensi dari gambar diatasa adalah F = 1/10 ms= 100 Hz.

Untuk menghasilkan sinyal PWM pada AVR digunakan fitur timer. AVR Atmega 8535 mempunyai 3 buah timer, tetapi disini saya akan membahas Timer0 dan Timer1 saja yang digunakan untuk membangkitkan sinyal PWM. Pada dasarnya Timer0 dan Timer1 mempunyai 4 buah mode untuk membangkitkan sinyal PWM. Untuk lebih jelasnya teman-teman baca datasheet saja.

Disini saya akan membangkitkan sinyal PWM menggunakan Timer0 dan timer1 dengan menggunakan 2 buah mode saja, yaitu Phase Correct PWM dan Fast PWM. Untuk pengertian dan penjelasan masing-masing mode dapat dilihat didatasheet ATmega8535, silakan download datasheet ATmega8535 disini..

Output pin PWM pada Atmega8535 terdapat pada 2 buah pin yaitu PD4 (OC1B) dan PD5 (OC1A).

>>>Timer0<<<
Mode Phase Correct PWM
Foc0 = Fosc/(N*512)
D = (OCR0/255)*100%

Mode Fast PWM
Foc0 = Fosc/(N*256)
D = (OCR0/255)*100%

Dimana:
Foc0 = Frekuensi output OC0
N = Skala clock (mempunyai nilai 1, 8, 64, 256 dan 1024)
D = Duty cycle
Fosc = Frekuensi clock kristal yang digunakan

>>>Timer1<<<
Mode Phase Correct PWM
Foc1a = Fosc/(2*N*TOP)
Foc1b = Fosc/(2*N*TOP)
D = (OCR1X/TOP)*100%

Mode Fast PWM
Foc1a = Fosc/(N*(1+TOP))
Foc1b = Fosc/(N*(1+TOP))
D = (OCR1X/TOP)*100%

Dimana:
Foc1a = Frekuensi output OC1A
Foc1b = Frekuensi output OC1B
N = Skala clock (mempunyai nilai 1, 8, 64, 256 dan 1024)
D = Duty cycle
Fosc = Frekuensi clock kristal yang digunakan
TOP = nilai maksimum counter (TCNT1), TOP mempunyai 3 buah nilai untuk kedua mode tersebut yaitu 8 bit (FF), 9 bit (1FF) dan 10 bit (3FF)

Sekarang saya akan membuat aplikasi membangkitkan sinyal PWM dengan periode 20 ms dengan duty cycle 75%, menggunakan Timer1 10 Bit Mode Fast PWM.

Dengan menggunakan kristal 12 Mhz, N = 256 dan TOP = 10 bit = 3FF = 1023

Maka akan didapat frekuensi output (Foc1x) sebesar 45,77 Hz atau jika diubah kedalam peroide 21,8 ms ≈ 20 ms

Untuk Duty cycle:
D = (OCR1X/TOP)*100%
75% = (OCR1X/1023)*100%
OCR1X = 767 = 2FF (dalam hexa)

Untuk membangkitkan periode yang benar-benar presisi pada sinyal PWM sangat sulit sekali karena kita hanya mampu memanipulasinya lewat 3 parameter saja yaitu, frekuensi kristal yang kita gunakan (tidak semua nilai frekuensi kristal ada dipasaran), skala clock atau N (hanya mempunyai nilai 1, 8, 64, 256, 1024) dan TOP (untuk kedua mode diatas mempunyai 3 buah nilai 8, 9 dan 10 bit). Dengan kombinasi ketiga variabel diatas kita harus benar-benar dapat menentukan periode output yang kita inginkan, menurut saya itu sangat sulit sekali.

Untuk aplikasi diatas berikut adalah setting untuk CodeVision CodeWizard AVR. Clock Value bernilai 46.875 berasal dari Fosc/N atau 12 MHz/256. 


Penjelasan diatas adalah untuk membangkitkan sinyal PWM sesuai dengan output yang kita inginkan, sedikit sulit memang. Tetapi pada dasarnya banyak sekali aplikasi yang menggunakan PWM tanpa harus memperdulikan kepresisian periode output, contohnya pengaturan motor DC. Untuk aplikasi pengaturan motor DC sangat simple sekali programnya.

Baiklah sekarang saya akan mengimplementasikan aplikasi pengaturan kecepatan motor DC menggunakan input yang berasal dari potensiometer. Cara kerjanya kecepatan motor DC diatur oleh potensio yang nilainya didapat dari pembacaan ADC. Untuk PWM nya saya gunakan hasil dari yang diatas (Timer1 10 bit mode Fast PWM). Berikut adalah setting untuk CodeWizard AVR dan schematicnya:



Berikut adalah listing program lengkapnya (sangat simple):

#include <mega16.h>
#include <delay.h>
int potensio;

#define ADC_VREF_TYPE 0×00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0×40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0×10)==0);
ADCSRA|=0×10;
return ADCW;
}

void main(void)
{
// Port D initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T
PORTD=0×00;
DDRD=0×30;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 46.875 kHz
// Mode: Ph. correct PWM top=03FFh
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA3;
TCCR1B=0×04;
TCNT1H=0×00;
TCNT1L=0×00;
ICR1H=0×00;
ICR1L=0×00;
OCR1AH=0×02;
OCR1AL=0xFF;
OCR1BH=0×00;
OCR1BL=0×00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0×80;
SFIOR=0×00;

// ADC initialization
// ADC Clock frequency: 750.000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0×84;

while (1)
      {
      potensio=read_adc(0);//membaca nilai ADC potensio
      OCR1A=potensio;//nilai potensio diumpan ke register PWM untuk ngatur kecepatan motor
      };
}

15 komentar:

  1. mas, mau nanya..kalo cristal diatas diganti dengan yang 4Mhz, apakah frekuensinya bisa diakali biar mendekati 50 Hz?
    kalo bisa minta rumusnya mas..buat TA..terima kasih...

    BalasHapus
  2. lho.. seharusnya anda sudah bisa menentukan frekuensi yg akan anda hasilkan jika anda memahami postingan saya diatas...
    anda bisa membuat suatu frekuensi (mendekati) dengan mengubah nilai kristal, skala clock (N) dan TOP...

    jika anda menggunakan kristal 4mhz, maka anda tingal memanipulasi nilai skala clock dan TOP

    BalasHapus
  3. Euu... bermanffat buat pribadi saya mas..
    Mo tanya dong,,
    kalo untuk mengatur besar kecilnya intensitas lampu bohlam lebih baik pake pwm ato cukup pake timer ya??
    Maksudnya pake 2 buah push button gitu...
    (menambah intensitas dan mengurangi intensitas)
    makasi mas__

    BalasHapus
  4. bohlamnya AC apa DC? klo AC tidak bisa langsung dihubungkan dengan PWM, membutuhkan rangkaian khusus untuk mengontrolnya...

    BalasHapus
  5. mas saya mau tanya,,
    begini kasusnya
    " sy ingin buat 1 motor DC yang dikontrol oleh mikro, dan mikro tersebut juga mencatat data putaran (RPM) dari putaran motor DC tersebut. kemudian kita bisa menginput berapa RPM putaran motor DC yang kita mau"
    apakah hal ini bisa dilakukan dengan 1 ic mikrokontroller saja??
    sy melihat sepertinya untuk membaca RPM dari motor perlu aktifkan Timer1 dengan mode yang berbeda, dengan timer1 untuk pWm motor.
    apa itu bisa dilakukan?
    tolong pencerahannya mas,,saya masih banyak belajar.
    terima kasih

    BalasHapus
  6. bisa menggunakan 1 buah mikro... tetapi untuk mengontrol kecepatan motor DC bisa menggunakan metode kontrol seperti PID atau fuzzy

    BalasHapus
  7. mas saya mau tanya...
    apakah sama mengaktifkan timer0, timer1, dan timer2...
    karena saya binggung bagaimana cara untuk mengaktifkan itu...
    dan tolong kasih saran tentang jedanya karena sama mau buat kendali 3 fasa...

    BalasHapus
    Balasan
    1. wah sama ni mas saya juga mau buat kendali 3 fasa. kita tunggu jawabannya dari yang punya blog. bingung disitu juga saya.

      Hapus
  8. mas mau nanya ?
    kal itu program nya pake soft apa ya ?

    BalasHapus
    Balasan
    1. Pake Code Vision AVR gan

      Hapus
    2. setahu saya ini programnya pake CodeVision AVR..

      Hapus
    3. setahu saya ini menggunakan software CodeVision AVR..

      Hapus
  9. Mohon bantuannya mas, saya buat program pwm untuk trigger switching penaik tegangan dc..
    saya menggunakan bascom avr, pwmnya sdh keluar tp frekuensinya hanya 30 hz pdhal sy btuh 20 khz

    BalasHapus
  10. Paling suka gw baca blog elctro-control, jelas. Sekali baca langsung bisa., trmksih bnyk

    BalasHapus
    Balasan
    1. ya betul.saya juga suka download2,filenya bentuk rar juga makasih elektro contol

      Hapus