Em đang làm mạch đếm tần số, sử dụng chip Atmega 16. Về thuật toán thì em dùng Timer 1 là counter còn Timer 0 tạo khoảng đếm 0.1s. Code thì dựa trên code hướng dẫn của Atmel viết cho Atmega 168 ("AVR205 Frequency measurement made easy with Atmel tinyAVR and Atmel megaAVR"). Nhưng mà khi thử bằng Proteus thì sai. Nguồn vào 2.2k mà hiển thị tầm 1.8k trên màn hình LCD, nếu thay đổi tần số nguồn vào còn chả hiện gì . Thử build file code mẫu của Atmel cho Atmega 168 cũng chả đúng gì. Các bác cho em hỏi sai chỗ nào với ạ?
Code:
#include <avr/io.h> #include <compat/ina90.h> // where _NOP, _CLI and _SEI are defined #include <avr/interrupt.h> #include <stdio.h> #include "myLCD.h" #include <util\delay.h> char dis[32]; unsigned int freq_cntr_result; unsigned int freq_cntr_freq_divd_by_10; unsigned int x48_cnt_to_four_ints; //Prototypes void freq_cntr_start_measurement(void); unsigned int freq_cntr_get_result(void); void freq_cntr_clear_result(void); int main() { _SEI(); //! User to decide when to enable interrupts TCCR1A=0x00;//Stop timer 0 TIFR |= (1<<TOV0);//Clear timer 0 overflow flag TCNT1H = 0x00; // clear counter upper 8 bits TCNT1L = 0x00; // clear counter lower 8 TCNT0 = 0; TIMSK = (1<<TOIE0);//Enable timer 0 overflow interrupt TCCR1B = (1<<CS12)|(1<<CS11); // external clock source on T1 pin.Clock on the falling edge TCCR0 = (1<<CS02)|(1<<CS00); // divide by 1024, the largest divisor possible in MEGAx8 x48_cnt_to_four_ints = 0; init_LCD(); while (1) { print_LCD("c");//Thử xem LCD có hoạt động ko? _delay_ms(10); clr_LCD(); //User's code to be inserted here if(freq_cntr_get_result() !=0) { freq_cntr_result = freq_cntr_get_result(); } sprintf(dis,"%d",freq_cntr_result); print_LCD(dis); _delay_ms(10); } return 0; } //end of main unsigned int freq_cntr_get_result(void) { return freq_cntr_freq_divd_by_10; } ISR(TIMER0_OVF_vect) { x48_cnt_to_four_ints++; if(x48_cnt_to_four_ints == 3)TCNT0 = 0xff-13; if(x48_cnt_to_four_ints >= 4) { TCCR1B = 0x00; // stop FREQ_CNTR TCCR0 = 0x00; // ovf_test_and_return_result(); //places result into freq_cntr_freq_divd_by_10 // Test TIFR for 16-bit overflow. If overrange return 0xFFFF if ((TIFR & (1<<TOV1)) !=0) { // Test GATE_CNTR_OVF_FLAG for 16-bit overflow = 0xFFFF freq_cntr_freq_divd_by_10 = 0xFFFF; // This is to return a OVF condition } else { freq_cntr_freq_divd_by_10 = TCNT1L+(TCNT1H<<8); } } }
Comment