Pada ATmega khususnya ATmega 328p, ada 3 buah timer yang bisa digunakan untuk membangkitkan PWM, sehingga ada 6 channel. Masing - masing yaitu Timer0, Timer1 dan Timer2 ada 2 channel.
Timer0 dan Timer2 maksimal nilainya yaitu 255 (8 bit) jika Timer1 maksimal 1023 (10 bit).
PWM ada dua jenis yaitu Fast PWM dan Phase PWM. Perbedaan paling mencolok yaitu jumlah lerengnya. Jika Fast PWM hanya ada satu, Phase PWM ada 2 lereng. Untuk lebih jelasnya bisa dilihat gambar berikut:
- Fast PWM
1. Non-Inverted PWM
Semakin besar nilai maka semakin besar dampak. Misal dalam mengatur kecepatan motor DC, semakin besar PWM semakin cepat jalannya.
2. Inverted PWM
Kebalikan dari Mode Non-Inverted PWM. Semakin besar nilai maka semakin kecil dampak. Misal dalam mengatur kecepatan motor DC, semakin besar PWM semakin lambat jalannya.
- Phase PWM
1. Non-Inverted PWM
Semakin besar nilai maka semakin besar dampak. Misal dalam mengatur kecepatan motor DC, semakin besar PWM semakin cepat jalannya.
2. Inverted PWM
Kebalikan dari Mode Non-Inverted PWM. Semakin besar nilai maka semakin kecil dampak. Misal dalam mengatur kecepatan motor DC, semakin besar PWM semakin lambat jalannya.
Cara mengaturnya di CVAVR jika menggunakan Timer0 dan Timer1 yaitu sebagai berikut:
1. Bikin Project baru
2. Pilih yang avr8 (8 bit)
3. Pada tab chip sesuaikan chip nya, pilih ATmega328p dan clocknya memakai 16 MHz.
4. Pada tab Timers/Counters
> Timer0
- Atur Clock Value menjadi 2 MHz (Atau Terserah berapa)
- Atur Mode Fast PWM
- Atur Output A Non-Inverted PWM
- Atur Output B Inverted PWM
- Hasil Akhir
> Timer1
- Atur Clock Value menjadi 2 MHz (Atau Terserah berapa)
- Atur Mode Phase PWM
- Atur Output A Non-Inverted PWM
- Atur Output B Inverted PWM
- Hasil Akhir
5. Generate, save and exit. Jika ada peringatan klik OK saja
6. Diharuskan menyimpan 3 kali, beri nama sama semua.
7. Source code hasil setting
8. Cara Memberi Nilai PWM
Cara memberi nilainya yaitu dengan meletakkannya di register OCR. Pada Timer0 hanya ada OCR0A dan OCR0B yang nilai maksimalnya 255 (8 bit), namun pada Timer1 OCRA dan OCRB dibagi lagi menjadi OCR1AH, OCR1AL, OCR1BH dan OCR1BL. OCR1xL untuk menyimpan nilai dari bit 0 - 7 atau data LOW dan OCR1xH untuk menyimpan nilai dari bit 8 - 15 atau data HIGH.
9. Source Code Lengkap
Terima kasih, jika masih ada pertanyaan bisa tulis dikolom komentar.
Youtube : https://www.youtube.com/robotikid
IG : https://www.instagram.com/robotikid/
FB : https://www.facebook.com/RobotikID/
Twitter : https://www.twitter.com/robotik_id
Web : https://www.robotikindonesia.com
Line : http://line.me/ti/p/~@464phkow
Tokopedia : http://tokopedia.com/instrumentrobot
4 Comments
gan bagian ini untuk geser bit
ReplyDeleteOCR1AH = (nilai_PWM <<8);
OCR1AL = (nilai_PWM &0xFF);
kebalik tanda, menurut saya seharusnya
OCR1AH = (nilai_PWM >>8);
OCR1AL = (nilai_PWM &0xFF);
oh iya, terima kasih koreksinya
Deletetolong bantu saya gan, jdi saya lgi buat cara mengatur kecepatan dan arah motor dc memakai 3 switch button dan ic atmega 16 juga ic l293d. tolong bantu saya membenarkannya, sebenernya jika di cek dengan multi meter ada outputnya bahkan ke ic l293d juga ada output nya tetapi saat di pasang motor dc dia tiidak berputar, kadang berputar tetapi macet macet dan harus slalu ditekan switch button nya keinginan saya cmn 1x tekan motor berputar terus, kira kira apa yang salah ya? dinamo yg sy pke dinamo dc 130 (3v - 6v)
ReplyDeletecode saya :
while (1)
{
if(PINA.0==0)
{
PORTD.0=0;
PORTD.1=1;
OCR1B=255;
}
if(PINA.1==0)
{
PORTD.0=1;
PORTD.1=0;
OCR1B=255;
}
if(PINA.2==0)
{
PORTD.0=0;
PORTD.1=1;
OCR1B=255;
delay_ms(500);
PORTD.0=1;
PORTD.1=0;
OCR1B=255;
delay_ms(500);
}else{
PORTD.0=0;
PORTD.1=0;
}
}
}
sebelumnya terima kasih dan blog nya bagus btw tidak terlalu banyak iklan seperti yg lain :)
dari programnya emang jika ditekan aja bang, baru jalan.
Deletemisal pengen cuma sekali aja, bisa pakai variabel.
int status=0;
while (1)
{
if(PINA.0==0)
{
status=1;
}
if(PINA.1==0)
{
status=2;
}
if(PINA.2==0)
{
status=3;
}
if(status==1){
PORTD.0=0;
PORTD.1=1;
OCR1B=255;
}
else if(status ==2){
PORTD.0=1;
PORTD.1=0;
OCR1B=255;
}
else if(status == 3){
PORTD.0=0;
PORTD.1=1;
OCR1B=255;
delay_ms(500);
PORTD.0=1;
PORTD.1=0;
OCR1B=255;
delay_ms(500);
}else{
PORTD.0=0;
PORTD.1=0;
}
// stop
else {
PORTD.0=0;
PORTD.1=1;
OCR1B=255;
}
}