Tôi cần đo tần số của sóng vuông có thể thay đổi trong khoảng từ 0 đến 1 MHz và có độ phân giải 0,25Hz.
Tôi chưa quyết định chọn bộ điều khiển nào nhưng rất có thể nó sẽ là một trong 20pin Attiny.
Thông thường cách tôi đo các tín hiệu tần số thấp hơn bằng cách sử dụng hai bộ định thời một được định cấu hình ở chế độ chụp hẹn giờ để ngắt các cạnh tăng của tín hiệu bên ngoài và bộ hẹn giờ khác được thiết lập để ngắt mỗi giây do đó giá trị của bộ đếm thời gian cũ sau 1 giây sẽ bằng tần số của tín hiệu.
Tuy nhiên, phương pháp này rõ ràng không hoạt động để thu các tín hiệu trong khoảng từ 0 đến 1 MHz với độ phân giải 0,25Hz cho điều này, tôi sẽ cần một bộ đếm 22Bit (micrô AFAIK 8 bit chỉ có bộ đếm 8/16 bit).
Một ý tưởng tôi đã có là phân chia tín hiệu trước khi áp dụng nó vào vi mô nhưng điều này sẽ không thực tế vì tín hiệu sẽ phải chia cho 61 do đó tần số chỉ có thể được cập nhật sau mỗi 61 giây mà tôi muốn nó cứ sau vài giây .
Có phương pháp nào khác cho phép tần số được cập nhật cứ sau 4 giây không?
Cập nhật:
Giải pháp đơn giản nhất là sử dụng ngắt ngoài hoặc chụp hẹn giờ để ngắt trên cạnh tăng của tín hiệu và có isr
một biến số loại tăng long int
. Đọc biến cứ sau 4 giây (để cho phép tần số giảm xuống 0,25Hz để đo).
Cập nhật 2:
Như JustJeff đã chỉ ra, MCU 8 bit sẽ không thể theo kịp tín hiệu 1 MHz để các quy tắc không bị gián đoạn trên mọi cạnh tăng và tăng long int
...
Tôi đã chọn phương pháp được đề xuất bởi timororr. Khi tôi đi xung quanh để thực hiện nó, tôi sẽ đăng lại và chia sẻ kết quả. Cảm ơn tất cả những gợi ý của bạn.
Báo cáo tiến trình:
Iv'e bắt đầu thử nghiệm một số ý tưởng được trình bày ở đây. Đầu tiên, tôi đã thử mã của Abbeyatcu. Có một vấn đề rõ ràng về TCNT1 không được xóa sau khi tần số được tính toán - không phải là vấn đề lớn ...
Sau đó, tôi nhận thấy khi gỡ lỗi mã cứ khoảng 2 đến 7 lần tần số được tính toán của bộ định thời 1 giây (bộ định thời được cấu hình để đếm các sự kiện bên ngoài) thì số lần tràn sẽ bị rút ngắn hai lần. Tôi đặt điều này xuống độ trễ của Timer 0 ISR và quyết định di chuyển khối lệnh if tạo thành ISR thành chính (xem đoạn trích bên dưới) và chỉ đặt cờ trong ISR. Một số gỡ lỗi cho thấy rằng phép đo đầu tiên sẽ ổn nhưng với mỗi lần đọc tiếp theo, số lần tràn của Timer 1 sẽ kết thúc bằng 2. điều mà tôi không thể giải thích - Tôi đã dự đoán nó sẽ không kết thúc ...
int main()
{
while(1)
{
if(global_task_timer_ms > 0 && (T0_overflow == 1))
{
global_task_timer_ms--;
T0_overflow = 0;
}
.....
}
}
Tiếp theo tôi quyết định tôi sẽ cố gắng thực hiện đề xuất timrorrs. Để tạo khoảng thời gian cần thiết (khoảng 15ms giữa mỗi ngắt timer_isr), tôi sẽ phải xếp tầng hai bộ định thời 8 bit vì bộ định thời 16 bit duy nhất trên Atmega16 đang được sử dụng để thu các cạnh tăng của tín hiệu bên ngoài.
Tôi nghĩ giải pháp này sẽ hoạt động hiệu quả và hiệu quả hơn nhiều vì phần lớn chi phí được chuyển sang bộ hẹn giờ và chỉ còn lại một isr ngắn để cpu xử lý. Tuy nhiên, nó không chính xác như tôi mong đợi, các phép đo dịch chuyển qua lại khoảng 70Hz mà tôi không bận tâm ở tần số cao nhưng chắc chắn không thể chấp nhận được ở tần số thấp hơn. Tôi đã không dành hai thời gian để phân tích vấn đề nhưng tôi đoán cách sắp xếp xếp tầng theo thời gian không chính xác vì tôi đã thực hiện một cách sắp xếp tương tự với đề xuất timrorrs trên bộ điều khiển 8051 chậm hơn có 2 bộ định thời 16 bit và kết quả khá chính xác.
Bây giờ tôi đã quay trở lại đề xuất của Abbeyatcu, nhưng tôi đã chuyển tính toán tần số sang isr Timer 0 (xem đoạn trích bên dưới ), mã này đã tạo ra các phép đo phù hợp và chính xác hợp lý. Với độ chính xác một chút, độ chính xác phải xấp xỉ +/- 10Hz.
ISR(TIMER0_OVF_vect)
{
TCNT0 = TIMER0_PRELOAD; //Reload timer for 1KHz overflow rate
if(task_timer_ms > 0)
{
task_timer_ms--;
}
else
{
frequency_hz = 1.0 * TCNT1;
TCNT1 = 0;
frequency_hz += global_num_overflows * 65536.0;
global_num_overflows = 0;
frequency_hz /= (TASK_PERIOD_MS / 1000.0);
task_timer_ms = TASK_PERIOD_MS;
}
}
Nếu có ai có bất kỳ đề xuất nào khác Tôi mở cho họ mặc dù tôi không phải sử dụng phạm vi ... Tôi cũng không còn có ý định nhận độ phân giải 0,25%, có vẻ như không có nhiều điểm với mức độ chính xác mà tôi có vào lúc này .