Mục lục:

Bộ đếm tần số độ phân giải cao: 5 bước (có hình ảnh)
Bộ đếm tần số độ phân giải cao: 5 bước (có hình ảnh)

Video: Bộ đếm tần số độ phân giải cao: 5 bước (có hình ảnh)

Video: Bộ đếm tần số độ phân giải cao: 5 bước (có hình ảnh)
Video: Bài giảng: Bộ đếm 2024, Tháng mười một
Anonim

Chỉ dẫn này cho thấy một bộ đếm tần số tương hỗ có khả năng đo tần số nhanh và với độ chính xác hợp lý. Nó được làm bằng các thành phần tiêu chuẩn và có thể được thực hiện trong một ngày cuối tuần (tôi mất nhiều thời gian hơn một chút:-))

CHỈNH SỬA: Mã hiện đã có trên GitLab:

gitlab.com/WilkoL/high-resolution-frequency-counter

Bước 1: Đếm tần số ở trường cũ

Đếm tần số trường cũ
Đếm tần số trường cũ
Đếm tần số trường cũ
Đếm tần số trường cũ

Cách truyền thống cũ để đo tần số của tín hiệu là sử dụng cổng AND logic, cấp tín hiệu cần đo vào một cổng và tín hiệu có thời gian cao chính xác 1 giây đến cổng kia và đếm đầu ra. Điều này hoạt động khá tốt đối với các tín hiệu của một vài kHz vào GHz. Nhưng nếu bạn muốn đo tín hiệu tần số thấp với độ phân giải tốt thì sao? Giả sử bạn muốn đo tần số của nguồn điện lưới (ở đây là 50 Hz). Với phương pháp cũ, bạn sẽ thấy số 50 không đổi trên màn hình của mình nếu may mắn, nhưng nhiều khả năng bạn sẽ thấy màn hình chuyển từ 49 thành 50 hoặc 50 thành 51. Độ phân giải là 1 Hz, vậy là xong. Bạn sẽ không bao giờ thấy tần số 50,002 Hz trừ khi bạn sẵn sàng tăng thời gian cổng lên 1000 giây. Đó là hơn 16 phút, cho một phép đo duy nhất!

Một cách tốt hơn để đo tín hiệu tần số thấp là đo khoảng thời gian của nó. Lấy nguồn điện làm ví dụ một lần nữa, có khoảng thời gian là 20 mili giây. Lấy cổng AND logic tương tự, cấp dữ liệu cho nó, chẳng hạn 10 MHz (0,1 đô la Mỹ xung) và tín hiệu của bạn trên cổng khác và xuất ra là 200000 xung, vì vậy khoảng thời gian là 20000,0 uS và chuyển ngược lại thành 50Hz. Khi bạn chỉ đo 199650 xung, tần số là 50.087 Hz, điều đó tốt hơn rất nhiều và thời gian đo chỉ trong một giây. Thật không may, điều này không hoạt động tốt với tần số cao hơn. Lấy ví dụ, bây giờ chúng tôi muốn đo 40 kHz. Với cùng tần số đầu vào 10 MHz như tham chiếu, chúng tôi hiện chỉ đo được 250 xung. Khi chúng ta chỉ đếm 249 xung, phép tính cho ra 40161 Hz và với 251, kết quả là 39840 Hz. Đó không phải là một độ phân giải có thể chấp nhận được. Tất nhiên việc tăng tần số tham chiếu sẽ cải thiện kết quả nhưng có giới hạn đối với những gì bạn có thể sử dụng trong bộ điều khiển vi mô.

Bước 2: Cách đối ứng

Con đường đối ứng
Con đường đối ứng
Con đường đối ứng
Con đường đối ứng

Một giải pháp hoạt động cho cả tần số thấp và cao hơn là bộ đếm tần số tương hỗ. Tôi sẽ cố gắng giải thích nguyên tắc của nó. Bạn bắt đầu với thời gian đo khoảng 1 giây, nó không cần phải chính xác lắm nhưng đó là thời gian hợp lý cho một phép đo. Nạp tín hiệu 1 Hz này vào D-flipflop trên đầu vào D. Không có gì xảy ra trên (các) đầu ra. Kết nối tín hiệu bạn muốn đo với đầu vào ĐỒNG HỒ của D-flipflop.

Ngay sau khi tín hiệu này đi từ THẤP đến CAO, đầu ra của D-flipflop sẽ chuyển trạng thái của đầu vào D sang đầu ra (Q). Tín hiệu RISING này sẽ được sử dụng để bắt đầu đếm tín hiệu đầu vào cũng như tín hiệu đồng hồ tham chiếu.

Vì vậy, bạn đang đếm chính xác HAI tín hiệu cùng một lúc, tín hiệu bạn muốn đo và một đồng hồ tham chiếu. Đồng hồ tham chiếu này phải có một giá trị chính xác và ổn định, một bộ dao động tinh thể bình thường là tốt. Giá trị không quan trọng lắm miễn là tần suất xuất hiện cao và giá trị của nó được biết đến nhiều.

Sau một thời gian, giả sử vài mili giây, bạn đặt đầu vào D của D-flipflop ở mức thấp trở lại. Ở đầu vào ĐỒNG HỒ tiếp theo, đầu ra Q tuân theo trạng thái của đầu vào, nhưng không có gì khác xảy ra bởi vì bộ điều khiển vi mô được đặt để chỉ phản ứng với tín hiệu RISING. Sau đó, sau khi hết thời gian đo (khoảng 1 giây), bạn đặt đầu vào D CAO.

Một lần nữa ở đầu vào ĐỒNG HỒ tiếp theo, đầu ra Q theo sau và tín hiệu RISING này kích hoạt bộ điều khiển vi mô, lần này để kết thúc việc đếm của cả hai bộ đếm.

Kết quả là hai số. Số đầu tiên là số xung đếm được từ tham chiếu. Như chúng ta biết tần số tham chiếu, chúng ta cũng biết thời gian cần thiết để đếm các xung đó.

Con số thứ hai là số lượng xung từ tín hiệu đầu vào mà chúng ta đang đo. Khi chúng tôi bắt đầu chính xác về các cạnh RISING của tín hiệu này, chúng tôi rất tự tin về số lượng xung của tín hiệu đầu vào này.

Bây giờ nó chỉ là một tính toán để xác định tần số của tín hiệu đầu vào.

Một ví dụ, giả sử chúng tôi có những tín hiệu này và chúng tôi muốn đo đầu vào f. Tham chiếu là 10 MHz, được tạo ra bởi bộ dao động tinh thể thạch anh. f_input = 31.416 Hz f_reference = 10000000 Hz (10 MHz), thời gian đo là khoảng. 1 giây

Trong thời gian này, chúng tôi đếm được 32 xung. Bây giờ, một khoảng thời gian của tín hiệu này có 1 / 31,416 = 31830,9 uS. Vì vậy, 32 khoảng thời gian đã lấy của chúng tôi 1,0185892 giây, tức là chỉ hơn 1 giây.

Trong 1,0186 giây này, chúng ta cũng sẽ đếm được 10185892 xung của tín hiệu tham chiếu.

Điều này cung cấp cho chúng tôi thông tin sau: input_count = 32 reference_count = 10185892 f_reference = 10000000 Hz

Công thức để tính tần suất kết quả là: freq = (input_count * f_reference) / ref_count

Trong ví dụ của chúng tôi, đó là: f-input = (32 * 10000000) / 10185892 = 31,416 Hz

Và điều này hoạt động tốt đối với tần số thấp cũng như tần số cao, chỉ khi tín hiệu đầu vào đến gần (hoặc thậm chí cao hơn) với tần số tham chiếu thì tốt hơn nên sử dụng cách đo "gated" tiêu chuẩn. Nhưng sau đó chúng ta cũng có thể chỉ cần thêm một bộ chia tần số vào tín hiệu đầu vào vì phương pháp tương hỗ này có cùng độ phân giải cho bất kỳ tần số nào (có thể tham chiếu lại). Vì vậy, cho dù bạn đo trực tiếp 100 kHz của phép chia bởi bộ chia 1000x bên ngoài, độ phân giải vẫn như nhau.

Bước 3: Phần cứng và sơ đồ của nó

Phần cứng và Sơ đồ của nó
Phần cứng và Sơ đồ của nó
Phần cứng và Sơ đồ của nó
Phần cứng và Sơ đồ của nó

Tôi đã thực hiện một vài loại máy đếm tần số. Cách đây rất lâu, tôi đã tạo một bộ điều khiển với ATMEGA328 (bộ điều khiển tương tự như trong Arduino), sau đó với bộ điều khiển vi mô ARM của ST. Phiên bản mới nhất được sản xuất với STM32F407 có tốc độ 168 MHz. Nhưng bây giờ tôi tự hỏi điều gì sẽ xảy ra nếu tôi làm tương tự với một cái nhỏ hơn * nhiều *. Tôi đã chọn ATTINY2313, chỉ có 2kbyte bộ nhớ FLASH và 128 byte RAM. Màn hình tôi có là MAX7219 với 8 màn hình bảy phân đoạn trên đó, những màn hình này có sẵn trên Ebay với giá chỉ 2 Euro. Một chiếc ATTINY2313 có thể được mua với giá khoảng 1,5 Euro, phần còn lại của các bộ phận mà tôi đã sử dụng có giá chỉ xu một chiếc. Đắt nhất có lẽ là hộp dự án bằng nhựa. Sau đó, tôi quyết định làm cho nó chạy bằng pin lithium-ion vì vậy tôi cần thêm bộ ổn định điện áp (LDO) 3.3V vào một mô-đun sạc pin và chính pin. Điều này làm tăng giá một chút, nhưng tôi đoán nó có thể được xây dựng với giá dưới 20 Euro.

Bước 4: Mã

Mật mã
Mật mã
Mật mã
Mật mã

Mã được viết bằng C bằng Atmel (Microchip) Studio 7 và được lập trình thành ATTINY2313 bằng cách sử dụng OLIMEX AVR_ISP (sao chép?). Mở (main.c) trong tệp zip bên dưới nếu bạn muốn làm theo mô tả ở đây.

BAN ĐẦU

Đầu tiên, ATTINY2313 được thiết lập để sử dụng một tinh thể bên ngoài vì bộ dao động RC bên trong vô dụng để đo bất kỳ thứ gì. Tôi sử dụng một tinh thể 10 MHz mà tôi điều chỉnh đến đúng tần số 10 000 000 Hz với một tụ điện có thể thay đổi nhỏ. Việc khởi tạo sẽ đảm nhận việc thiết lập các cổng cho đầu vào và đầu ra, thiết lập bộ định thời và cho phép ngắt và khởi tạo MAX7219. TIMER0 được thiết lập để đếm đồng hồ bên ngoài, TIMER1 đồng hồ bên trong và cũng để nắm bắt giá trị của bộ đếm ở cạnh lên của ICP, đến từ D-flipflop.

Tôi sẽ thảo luận về chương trình chính sau cùng, vì vậy tiếp theo là các quy trình ngắt.

TIMER0_OVF

Khi TIMER0 đếm lên đến 255 (8 bit) và sau đó chuyển về 0, chúng ta cần một ngắt để đếm số lần tràn. Đó là tất cả những gì TIMER0_OVF làm, chỉ cần đếm số lần tràn. Sau đó số này được kết hợp với giá trị của chính bộ đếm.

TIMER1_OVF

TIMER1 có thể đếm tới 65536 (16 bit), do đó ngắt TIMER1_OVF cũng đếm số lần tràn. Nhưng nó còn làm được nhiều hơn thế. Nó cũng giảm từ 152 xuống 0, mất khoảng 1 giây và sau đó thiết lập một chân đầu ra, đi đến đầu vào D của flipflop. Và điều cuối cùng được thực hiện trong quy trình ngắt này là giảm bộ đếm thời gian chờ, từ 765 xuống 0, mất khoảng 5 giây.

TIMER1_CAPT

Đây là ngắt TIMER1_CAPT được kích hoạt mỗi khi D-flipflop gửi tín hiệu cho nó, tại cạnh lên của tín hiệu đầu vào (như đã giải thích ở trên). Logic bắt giữ sẽ lưu giá trị của bộ đếm TIMER1 tại thời điểm chụp, nó được lưu cũng như bộ đếm tràn. Thật không may, TIMER0 không có chức năng bắt đầu vào nên ở đây giá trị hiện tại của nó và giá trị hiện tại của bộ đếm tràn được đọc. Một biến thông báo được đặt thành một biến để chương trình chính của anh ta cho nó biết đây là dữ liệu mới.

Tiếp theo là hai chức năng để điều khiển MAX7219

SPI

Mặc dù có một Giao diện Nối tiếp Đa năng (USI) có sẵn trong chip, tôi đã chọn không sử dụng nó. Màn hình MAX7219 cần được điều khiển thông qua SPI và điều đó có thể thực hiện được với USI. Nhưng bitbanging SPI rất đơn giản nên tôi đã không dành thời gian để làm điều đó với USI.

MAX7219

Giao thức để thiết lập MAX7219 cũng khá đơn giản khi bạn đã đọc hướng dẫn sử dụng của nó. Nó cần một giá trị 16 bit cho mỗi chữ số bao gồm 8 bit cho số chữ số (1 đến 8) tiếp theo là 8 bit cho số nó cần hiển thị.

CHÍNH-PROG

Điều cuối cùng là giải thích chương trình chính. Nó chạy trong một vòng lặp vô hạn (while (1)) nhưng chỉ thực sự làm điều gì đó khi có thông báo (1) từ quy trình ngắt hoặc khi bộ đếm thời gian chờ đã chạy xuống 0 (không có tín hiệu đầu vào).

Điều đầu tiên cần làm khi thông báo biến được đặt thành một, là đặt lại bộ đếm thời gian chờ, sau khi tất cả chúng ta biết rằng có tín hiệu hiện diện. D-flipflop được đặt lại để sẵn sàng cho lần kích hoạt tiếp theo sẽ đến sau thời gian đo (đợi một giây).

Các số được đăng ký trong ngắt chụp được thêm vào để cung cấp số lượng tham chiếu và số lượng tần số đầu vào. (chúng ta phải đảm bảo rằng tham chiếu không bao giờ có thể bằng 0 vì chúng ta sẽ chia cho nó sau này)

Tiếp theo là tính toán tần suất thực tế. Tôi chắc chắn không muốn sử dụng số nổi trên một bộ vi điều khiển chỉ với 2kbyte flash và chỉ 128 byte ram mà tôi sử dụng số nguyên. Nhưng tần số có thể là 314,159 Hz, với một số số thập phân. Do đó, tôi nhân tần số đầu vào không chỉ với tần số tham chiếu mà còn với một hệ số nhân, sau đó thêm một số vào vị trí của dấu thập phân. Những con số này sẽ rất lớn khi bạn làm điều đó. Ví dụ. với đầu vào 500 kHz, tham chiếu 10 MHz và hệ số nhân 100, điều này cho kết quả là 5 x 10 ^ 14, điều đó thực sự rất lớn! Chúng sẽ không có ngôn ngữ phù hợp với số 32 bit, vì vậy tôi sử dụng các số 64 bit sẽ lên đến 1,8 x 10 ^ 19 (hoạt động tốt trên ATTINY2313)

Và điều cuối cùng cần làm là gửi kết quả đến màn hình MAX7219.

Mã biên dịch thành khoảng 1600 byte, vì vậy nó phù hợp với flash 2048 byte có sẵn trong ATTINY2313.

Thanh ghi cầu chì sẽ đọc như thế này:

ĐÃ MỞ RỘNG 0xFF

0xDF CAO

THẤP 0xBF

Bước 5: Độ chính xác và độ chính xác

Độ chính xác và độ chính xác
Độ chính xác và độ chính xác
Độ chính xác và độ chính xác
Độ chính xác và độ chính xác
Độ chính xác và độ chính xác
Độ chính xác và độ chính xác

Độ chính xác và độ chính xác là hai con thú riêng biệt. Độ chính xác ở đây là bảy chữ số, độ chính xác thực tế là gì phụ thuộc vào phần cứng và hiệu chuẩn. Tôi đã hiệu chỉnh tần số 10 MHz (5 MHz trên điểm kiểm tra) bằng một bộ đếm tần số khác có bộ dao động GPS.

Và nó hoạt động khá tốt, tần số thấp nhất mà tôi đã thử là 0,2 Hz, cao nhất là 2 MHz. Nó là ngay tại chỗ. Trên 2 MHz, bộ điều khiển bắt đầu mất ngắt, không thực sự ngạc nhiên khi bạn biết rằng ở tín hiệu đầu vào 2 MHz, TIMER0 tạo ra hơn 7800 ngắt mỗi giây. Và ATTINY2313 cũng phải làm những việc khác, ngắt từ TIMER1, với 150 lần ngắt khác mỗi giây và tất nhiên là thực hiện các tính toán, điều khiển màn hình và D-flipflop. Khi bạn nhìn vào thiết bị thực tế, bạn sẽ thấy rằng tôi chỉ sử dụng bảy trong số tám chữ số của màn hình. Tôi làm điều này vì một số lý do.

Đầu tiên là việc tính toán tần số đầu vào là một phép chia, nó hầu như sẽ luôn có phần dư, mà bạn không thấy vì nó là một phép chia số nguyên. Thứ hai là bộ dao động tinh thể thạch anh không được ổn định nhiệt độ.

Các tụ điện điều chỉnh nó đến đúng 10 MHz là gốm, rất nhạy cảm với sự thay đổi nhiệt độ. Sau đó, có một thực tế là TIMER0 không có tích hợp logic bắt và các hàm ngắt đều mất một khoảng thời gian để thực hiện công việc của chúng. Tôi nghĩ bảy chữ số dù sao cũng đủ tốt.

Đề xuất: