Код MicroPython
import rp2
from machine import Pin
import time
PIN_NUM = 6
INITIAL = 0xFFFFFFFF # стартовое значение для счетчика
@rp2.asm_pio()
def freq_counter():
pull() # берём INITIAL из TX-FIFO
mov(y, osr) # заполняем У чтобы не дергать фифо каждый раз
wrap_target() # переходим в основной цикл
mov(x, y) # заполняем Х для вычитания из него кол-ва тактов прошедших за момент низкого уровня
wait(1, pin, 0) # ждём первого фронта
wait(0, pin, 0) # ждём первого спада
label("count_loop")
jmp(pin, "done") # если фронт — выходим
jmp(x_dec, "count_loop") # иначе декремент X, и назад (считаем сколько тактов сигнал был в 0)
label("done")
mov(isr, x) # сохраняем остаток в ISR
push() # отправляем в RX-FIFO
wrap()
sm = rp2.StateMachine(
0, freq_counter,
freq=100_000_000, # скорость ПИО = 100 МГц
in_base=Pin(PIN_NUM),
jmp_pin=Pin(PIN_NUM)
)
sm.put(INITIAL) # даём INITIAL
sm.active(1)
while True:
while not sm.rx_fifo(): # ждём, когда PIO пульнет результат
pass
ticks = INITIAL - sm.get() # читаем число тактов
freq = 100_000_000 // ticks if ticks else 0
print(f"Частота: {freq / 1000000:.3f} МГц, Такты: {ticks}")
time.sleep(0.2)
При этом, скорее всего, часть тактов занимаемых инструкциям подсчета не учитывается.
Как учесть эту погрешность, т.к сейчас при стабильном клоке в 1мгц на входе частота подсчитывается под 3мгц.
Если на входе 8 МГц, то вообще не удаётся считать — вывода нет, хотя запас должен быть, и даже большой: ведь частота дискретизируемого сигнала как минимум в 5 раз меньше частоты дискретизации, чего должно хватать.