Pin Timer /Counter pada AVR
2. Menghitung panjang pulsa (input capture)
3. Menghitung banyaknya event ( sebagai counter).
4. Mengendalikan kecepatan motor DC (pulsa wide modulation /PWM).
5. Membuat penundaan waktu (delay).
Komponen utama Timer/Counter adalah sebuah register yg tugasnya hanya berhitung dari 0 sampai batas maximumnya, register ini pada AVR disebut register TCNT . Misalnya sebuah register TCNT pada AVR adalah 8 bit, maka nilai maksimunya adalah 255.
Register yang digunakan untuk mendukung operasi Timer Counter pada AVR :
- Register TCNT = register pencacah dari 0 sampai nilai maximum yg kita tentukan.
- Register TCCR =Untuk pengaturan mode operasi Timer/Counter
- Register TIMSK =Untuk memilih Timer Counter mana yg aktif.
- Register TIFR = Untuk mengetahui adanya interupsi akibat operasi Counter Timer .
- Register OC (output compare) = untuk menyimpan nilai pembanding dgn nilai pd register TCNT.
Ketika sumber clock dari external / pin T maka ia berlaku sebagai counter.
pemilihan sumber clock ada pada bit CS pada register TCCR.
1. Timer Mode NormalMemilih mode ini dgn cara menset semua bit WGM =0 , pada register TCCR
Untuk mode normal penggunaanya cukup mudah, contohnya anda bisa baca disini.
Contoh code:
*====================================================== Chip type : ATmega8535 Compiler : CodeVision Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 Author : pccontrol.wordpress.com *****************************************************/ #includeketerangan program :#include // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x15 ;PORTC #endasm #include unsigned char bufferperiodeL[15]; unsigned char bufferperiodeH[15]; // Timer 1 input capture interrupt service routine interrupt [TIM1_CAPT] void timer1_capt_isr(void) { sprintf(bufferperiodeL,"%i ",ICR1L); sprintf(bufferperiodeH,"%i ",ICR1H); lcd_gotoxy(0,1); lcd_puts(bufferperiodeH); lcd_gotoxy(4,1); lcd_puts(bufferperiodeL); ICR1H=0; ICR1L=0; TCNT1L =0; TCNT1H =0; } void main(void) { // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 3.906 kHz // Mode: Normal top=FFFFh // Noise Canceler: Off // Input Capture on Rising Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: On TCCR1A=0x00; TCCR1B=0x45; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1 // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x20; // LCD module initialization lcd_init(16); lcd_gotoxy(0,0); lcd_putsf("periode pulsa :"); // Global enable interrupts #asm("sei") while (1) { }; }
setiap ada perubahan tegangan dari o ke 1 di pin ICP /portD.6 maka akan memicu interupt input capture. besaran panjang pulsa antara 2 rising edge ada di register ICR1H dan ICR1L . misal hasil di ICR1 = 1250 maka perioda pulsa = 1/clock timer * 1250 . Clock timer sudah kita pilih 3,906 khz.
(1/3906) * 1250 = 0,32 detik.
/*=================================================== Chip type : ATmega8535 Author : cipto-suparno.blogspot.com Clock frequency : 4.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/ #include#include // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x15 ;PORTC #endasm #include unsigned int hitunganMSB; unsigned int hitunganLSB; unsigned char bufferCounter[15]; unsigned long int hitungan; // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { //hitungan lebih dari 255 hitunganMSB = hitunganMSB + 1; } // Declare your global variables here void main(void) { // Declare your local variables here // Timer/Counter 0 initialization // Clock source: T0 pin Falling Edge // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x06; TCNT0=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01; // LCD module initialization lcd_init(16); lcd_gotoxy(0,0); lcd_putsf("counter :"); // Global enable interrupts #asm("sei") while (1) { // Place your code here hitunganLSB = TCNT0; hitungan = hitunganMSB + hitunganLSB; sprintf(bufferCounter,"%i ", hitungan ); lcd_gotoxy(0,1); lcd_puts(bufferCounter); }; }
Salah satu kegunaan sinyal PWM antara lain untuk mengendalikan Kecepatan putaran Motor DC. Gambar berikut ini menunjukan berbagai bentuk PWM dan efek terhadap kecepatan Motor DC yang berbeda sesuai bentuk pulsa PWM.
Cara pembentukan sinyal PWM
Nilai pada register Counter TCNT akan terus menerus naik sampai nilai maximum, lalu kembali ke 0. begitu seterusnya selama sinyal clock diberikan kepada timer. Nilai OCR diset untuk mengatur pembentukan PWM.
saat nilai TCNT > nilai OCR maka pin OC mengeluarkan sinyal HIGH ,
saat nilai TCNT < nilai OCR maka pin OC mengeluarkan sinyal LOW.
Gambar berikut menunjukan tiga buah nilai OCR yang berbeda ,yg menghasilkan sinyal output PWM berbeda pula pada pin OC.
Cara Membuat PWM pada CodeWizard di Codevision spt pada gambar berikut:
#include// Declare your global variables here void main(void) { // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T PORTB=0x00; DDRB=0x08; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 62.500 kHz // Mode: Phase correct PWM top=FFh // OC0 output: Non-Inverted PWM TCCR0=0x63; TCNT0=0x00; OCR0=0x40; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; while (1) { // Place your code here }; } 5. Membuat Delay dengan Timer. #include interrupt [TIM0_OVF] void timer0_ovf_isr(void) { delay = delay + 1 } void main(void) { // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 3.906 kHz // Mode: Normal top=FFh TCCR0=0x05; TCNT0=0xD9; // Timer0 enable TIMSK=0x01; // Global enable interrupts #asm("sei") while (1) { //program utama disini delay(100); //delay 1 detik (100*10ms=1000ms) }; } Void delay(int delay_ms) { TCNT0=0xD9; //interval timer = 10 ms delay=0 while(delay<=delay_ms) { //muter2 disini } }
Kesimpulan cara Pengesetan register TCCR