Pulse Width Modulation (PWM) atau modulasi lebar pulsa sangat bermanfaat pada sistem mikrokontroler, salah satunya adalah untuk mengendalikan motor DC. Pada chip ATmega328, sinyal PWM ini dapat dibangkitkan dengan perangkat lunak, ataupun dapat dibangkitkan dari perangkat keras dengan menggunakan periferal Timer internal. PWM dari perangkat keras cukup praktis karena tidak membebani perangkat lunak, namun ada keterbatasan karena pada ATmega328 hanya terdapat 3 buah timer internal, sehingga tidak bisa memiliki banyak output PWM dari perangkat keras.
Berikut ini ujicoba output PWM (Pulse Width Modulation) dari Timer 0 pada ATmega328. Modul yang digunakan adalah Arduino Nano clone.
Konfigurasi pengujian PWM ini adalah sebagai berikut:
- Perangkat keras menggunakan Timer 0 (8 bit)
- Clock Source: System Clock
- Clock Value 2000.000 kHz
- Mode: Fast PWM top=0xFF
- Out A: Non-Inverted PWM
- Out B: Disconnected
- tidak ada interupsi dari Timer0
- output pada pin OC0A (pin PD6 pada ATmega328, D6 pada Arduino Nano)
Pengaturan register menggunakan Code Wizard dari CodeVision AVR Evaluation dengan detail sebagai berikut ini:
Source code terkait dengan Timer 0 adalah sebagai berikut:
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 2000.000 kHz
// Mode: Fast PWM top=0xFF
// OC0A output: Non-Inverted PWM
// OC0B output: Disconnected
// Timer Period: 0.128 ms
// Output Pulse(s):
// OC0A Period: 0.128 ms Width: 0.016063 ms
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x20;
OCR0B=0x00;
Source code lengkap dapat dilihat di https://github.com/waskita/embedded/blob/master/cv-kendali/cv-kendali-usart.c
Variable yang dapat diubah-ubah adalah OCR0A untuk mengatur duty-cycle dari PWM. Nilai register ini dapat diisi dari 0x00 sampai dengan 0xff (255)
Tahap selanjutnya adalah pengujian output PWM dengan cara melihat sinyal yang dihasilkan dengan osiloskop GW INSTEK GDS-1042
Berikut ini adalah output dengan nilai register OCR0A=0x00. Perioda PWM adalah 2000/256 = 0.128 ms
Nampak bahwa nilai register 0 akan memberikan sinyal yang paling pendek, yaitu dengan panjang pulsa 500 ns. Berikut ini adalah sinyal yang sama dilihat dengan time base 100 ns per div
Berikut ini adalah sinyal dengan OCR0A=0x80 atau duty cycle=50%
Berikut ini adalah sinyal dengan OCR0A=0xfe (254)
Terakhir adalah sinyal dengan duty cycle = 100% , dengan OCR0A=0xff (255)
Hal penting yang perlu diperhatikan: nilai duty cycle tidak pernah 0%, minimum adalah 1/256. Nilai maksimum duty cycle adalah 100%. Untuk membuat sinyal PWM duty cycle =0 dapat dilakukan dengan mematikan output PWM.