Rabu, 29 Juni 2011

PENGHITUNG FREKUENSI (FREQUENCY COUNTER) MENGGUNAKAN CODEVISION AVR

Penghitung frekuensi (Frequency Counter) digunakan untuk menghitung banyaknya gelombang dalam satu detik, sehingga mempunyai satuan Hz (Hertz).

Untuk menghitung pulsa (frekuensi) yang berasal dari luar digunakan sebuah eksternal interupt (EXT INT). EXT INT merupakan fitur AVR Atmega 8535 yang berfungsi untuk mencacah sinyal dari luar.
Secara garis besar agar dapat menghitung sebuah frekuensi gelombang atau pulsa (Hz) mempunyai cara kerja sebagai berikut yaitu sebuah EXT INT untuk menghitung frekuensi dan lamanya perhitungan frekuensi tersebut adalah 1 detik. Sehingga didapat banyaknya frekuensi atau pulsa dalam 1 detik, dengan kata lain Hz.

Untuk itu diperlukan sebuah interupt (EXT INT) dan sebuah timer untuk membuat timer selama 1 detik. Disini saya telah membuat program penghitung frekuensi dan telah berhasil diimplementasikan pada rangkaian sesungguhnya. Untuk eksternal interupt digunakan EXT INT0 dan timernya menggunakan Timer1. Jika masih bingung mengenai timer dan interupsi eksternal, silakan baca tutorial Timer dan Counter serta Interupsi Eksternal AVR. Pada Atmega8535 atau Atmega16 EXT INT0 berasal dari pin INT0 atau PD2. Berikut adalah schematicnya.

 
 

Sedangkan untuk listing program lengkapnya:

int frekuensi=0;
float pulsa;
char temp[8];

#include <mega16.h>
#include <lcd.h>
#include <delay.h>
#include <stdlib.h>

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0×15 ;PORTC
#endasm
#include <lcd.h>

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
frekuensi++;//baca frekuensi yg masuk trus di increament
}

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer 1 value
    TCNT1H=0xD23A >> 8;
    TCNT1L=0xD23A & 0xff;
    pulsa=frekuensi;
    frekuensi=0;
    lcd_clear();
}

void tampilkan_LCD()
{
if (pulsa>=1000)
    {
    pulsa=pulsa/1000;
    ftoa(pulsa,1,temp);
    lcd_gotoxy(0,1);
    lcd_puts(temp);
    lcd_gotoxy(0,5);
    lcd_putsf(“KHz”);
    }
else
   {
    ftoa(pulsa,1,temp);
    lcd_gotoxy(0,1);
    lcd_puts(temp);
    lcd_gotoxy(0,5);
    lcd_putsf(“Hz”);
    }
}

void main(void)
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 11.719 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0×00;
TCCR1B=0×05;
TCNT1H=0xD2;
TCNT1L=0x3A;
ICR1H=0×00;
ICR1L=0×00;
OCR1AH=0×00;
OCR1AL=0×00;
OCR1BH=0×00;
OCR1BL=0×00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
// INT2: Off
GICR|=0×40;
MCUCR=0×02;
MCUCSR=0×00;
GIFR=0×40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0×04;

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

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm(“sei”)

while (1)
      {
      lcd_gotoxy(0,0);
      lcd_putsf(“ElektrO-cOntrOl”);
      tampilkan_LCD();
      };
}

Jika ingin mendapatkan file program dalam bentuk CodeVision AVR silakan download pada link dibawah ini.

File program CodeVision AVR frekuensi counter

Semoga bermanfaat…

14 komentar:

  1. kok gak bisa yaaaa programnya???
    keluar nol terus nilainya…gmana tuh??
    pdahal saya udh buat persis seperti yang digambar

    BalasHapus
  2. anda coba pakai simulasi apa hardware yg sesungguhnya... soalnya saya coba pada hardware yg sesungguhnya dan berhasil
    soalnya klo disimulasikan tidak akan presisi karena clock komputer dan mikro berbeda jauh

    BalasHapus
  3. saya menggunakan simulasi proteus.....kalo di hardwarenya saya akan buat pembacaan rpm utk 2 motor menggunakan encoder 46 lubang yg telah saya buat.....kira2 listing programnya sama ya yg kayak di aatas,tinggal ditambah 1 interupt lagi utk motor 2, int0=motor1,int1=motor2....
    kira2 begitu utk rancangan yg akan saya buat...trimakasih

    BalasHapus
  4. oh iya sekalian mau nanya,cara membuat delay dengan menggunakan fitur timer/counter gmana ya???
    soalny kalo pake delay biasa gk presisi waktu delaynya tuh,makany mnrut saya apakah bisa membuat delay dengan menggunakan fitur timer yg ada di mikro itu???

    BalasHapus
  5. untuk 2buah motor DC anda tinggal menambahkan sebuah INT lagi.
    sebenarnya instruksi delay pada codevision AVR itu lumayan presisi, tetapi yg membuatnya tidak presisi adalah instruksi2 program dibawah instruksi delay.. dikarenakan setiap instruksi program mempunyai waktu proses.
    silakan liat tutorial AVR ---> timer dan counter untuk

    BalasHapus
  6. owwwww...begitu ternyata....jadi kalo memakai 2 interrupt sekaligus,timernya pake yg timer1 kan utk proses pembacaan kecepatannya???oh iya ftoa itu gunanya utk apa ya???kok harus memakai float utk pulsanya???
    terimakasih ya atas informasinya.....sangat berguna utk ta saya.....hehehehe....
    thank youu..

    BalasHapus
  7. oh iya hampir lupa nanya satu lagi....
    jika pembacaan kecepatan motor CW (searah jarum jam) dengan kecepatan motor CCW(balik arah jarum jam) gimana ya utk proses pembacaannya itu,apakah sama aja dgn listing program anda utk menghitung kecepatan motor dgn encoder itu????
    trimakasih...

    BalasHapus
  8. iya, menggunakan 2 buah INT dan sebuah timer untuk mendapatkan pulsanya tiap 1 detik (bisa timer0 atau timer1).
    sebenarnya bisa saja menggunakan integer, tetapi batasan tipe data integer adalah 65535.
    ftoa adalah float to array, saya gunakan untuk merubah tipe data float ke array, fungsinya sih cuma buat nampilin aja di LCD.
    tapi jika anda menggunakan tipe data integer maka untuk menampilkan di LCD pakai itoa (integer to array)... contoh:
    itoa(pulsa,temp);

    klo untuk arah putaran CW/CCW tidak ada bedanya... yg penting encoder motor DC anda tidak ada perbedaan ketika membaca kecepatan, apakah CW atau CCW...

    BalasHapus
  9. sippp dehh.....mudah2an bisa bermanfaat utk ta saya....terimakasih ya atas smua infonya......

    BalasHapus
  10. slamat pagi,,,saya udh mencoba program diatas,ttapi ada kendala,,,ketika saya jalankan pertama rpm yg ddapat bisa brubah ketika motor dipelankan,,,,namun setelah bbrapa sekon(anggap 40s) tiba2 rpmny mentok gitu aja,alias gk ad prubahan sma sekali ketika dipercept maupun di perlambat motornya......

    kira2 aapa y masalhny tuh???

    BalasHapus
  11. Nah…thx banget sebelumnya mungkin pembahasan saudara bisa membantu saya. begini saya masih bingung tentang input frekuensi yg dimaksudkan berbentuk pulsa.. apakah yang dimaksudkan gelombang kotak kah… atau bisa berbentuk masukan dari tegangan AC langsung bentuk sinusoida..
    mohon diskusinya karena penting untuk penyelesaian project saya. thx.. mohon waktu dan diskusinya… kalau berkenan bisa kabari saya ya… maaf merepotkan sebelumnya.
    mungkin akan lama jika kita berdiskusi disini. no.saya 085326406840. trimakasih banyak…

    BalasHapus
  12. mas, kalau mau bikin penghitung frekuensi yang bisa menampilkan angka dibelakang koma(misalnya 50.5 Hz) gimana ya?

    BalasHapus
  13. program diatas udah nampilin dalam satuan koma kok...

    BalasHapus
  14. nama saya:firman..
    mas nanya...
    misalnya masukan frekuensi yang ingin dihitung besarnya sekitar 50 kHz, mikro masih bisa menghitung tidak ya..???untuk program diatas bisa ndak ya..???
    terimakasih atas jawabanya....

    BalasHapus