Xin chào các bạn!
Trong bài viết này, tôi xin hướng dẫn với các bạn cách đo tần số của tín hiệu sử dụng module INPUT CAPTURE được tích hợp trong bộ TIMER1 của vi điều khiển Atmega8.
Chú ý : Source code bài viết dưới đây được biên dịch bằng phần mềm CodeVisionAVR để biên dịch code không lỗi xin vui lòng Download bảnCodeVisionAVR Tại Đây
I.INPUT CAPTURE.
Chế độ Input Capture liên quan đến thanh ghi ICR1 (Input Capture Register 1) trong TIMER1.Input Capture xảy ra khi có 1 sự kiện trên chân ICP1 (chân 14 của Atmega8), khi đó:
- Giá trị của thanh ghi TCNT1 sẽ được chép vào thanh ghi ICR1.
- Cờ ICF1 được bật (lên 1).
- Ngắt INPUT CAPTURE sẽ xảy ra khi được kích hoạt.
Sự kiện trên chân ICP1 được xác định bằng bit ICES1 trong tranh ghi TCCRB:
- ICES1 = 1: cạnh lên của tín hiệu sẽ kích hoạt Input Capture.
- ICES1 = 0: cạnh xuống của tín hiệu sẽ kích hoạt Input Capture.
II.ĐO TẦN SỐ TÍN HIỆU SỬ DỤNG INPUT CAPTURE.
1.CÁCH ĐO.
Với Input Capture, chúng ta có thể đo tần số của tín hiệu như sau:
Chúng ta kích hoạt ngắt Input Capture. Như vậy mỗi khi Input Capture xảy ra, chúng ta chỉ cần vào trình phục vụ ngắt của Input Capture và đọc giá trị thanh ghi ICR1 qua đó có thể tính được khoảng thời gian giữa 2 lần Input Capture à Tần số tín hiệu.
2.THIẾT LẬP INPUT CAPTURE TRONG CodeVisionAVR.
Trong trình biên dịch CodeVisionAVR đã hỗ trợ cho chúng ta thiết lập Input Capture một cách dễ dàng:
Tạo Project mới àchọn CodeWizardAVRàchọn Timers àchọn Timer1
Trong bảng này, các bạn có thể chọn kiểu tín hiệu vào ICP1 ở Input Capt, kích hoạt ngắt tràn TIMER1 và Input Capture ở Interrupt on
3.CODE MẪU.
#include <main.h>
#include <var.h>
// TRINH PHUC VU NGAT TRAN TIMER1
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
Timer1_Over += 0xffff;
}
// TRINH PHUC VU NGAT INPUT CAPTURE
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
Chu_Ky = Timer1_Over + ICR1 - Icp1;
Icp1 = ICR1;
Timer1_Over = 0;
}
void main(void)
{
unsigned char Lcd_Buff_F[15];
unsigned long int T;
float F;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// KHOI TAO TIMER1
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge // Input Capture: Canh xuong
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x24; // Kich hoat ngat tran TIMER1 và ngat Input Capture
// KHOI TAO LCD1602
// Connections specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTD Bit 4
// RD - PORTD Bit 3
// EN - PORTD Bit 2
// D4 - PORTB Bit 4
// D5 - PORTB Bit 5
// D6 - PORTB Bit 6
// D7 - PORTB Bit 7
// Characters/line: 16
// Global enable interrupts
#asm("sei") // SET BIT NGAT TOAN CUC
lcd_init(16);
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts("MINHHAGROUP ");
while (1)
{
T = (float)(Chu_Ky);
F = 1000000/T;
lcd_gotoxy(0,1);
sprintf(Lcd_Buff_F,"TAN SO: %5.1f",F);
lcd_puts(Lcd_Buff_F);
// Place your code here
}
}
Các bạn có thể xem Code mẫu và mô phỏng Tại đây: