прога для микроконтроллера-генератора PWM

This commit is contained in:
Vladislav Ostapov 2025-03-31 13:42:34 +03:00
parent f07d4bc6c8
commit 5c7147147b
2 changed files with 114 additions and 0 deletions

View File

@ -11,3 +11,11 @@
Для работы ПО на компьютере необходимо установить `python3`, создать `venv` и установить все библиотеки, что описаны в `common/requirements.txt`. Для работы ПО на компьютере необходимо установить `python3`, создать `venv` и установить все библиотеки, что описаны в `common/requirements.txt`.
Далее просто запустить `common/main.py`. Интерфейс там интуитивно понятный. Далее просто запустить `common/main.py`. Интерфейс там интуитивно понятный.
Для имитации PWM и бенчмаркинга используется второй микроконтроллер - RP2040. На нем запускается программа `common/rp2040-pwm-generator.py`.
Для проверки работоспособности выставляется эталонная частота и эталонная длительность импульса.
Для проверки максимальной скорости работы устанавливается максимально возможная частота PWM и длительность импульса.
# Benchmarking
... результаты ...

View File

@ -0,0 +1,106 @@
# Программа PWM-генератора с кнопкой.
# Запускать строго на отладочной плате RP2040 и Micropython!
# Использование: если синий светодиод горит, значит PWM работает, в противном случае PWM отключен.
# Включать/отключать PWM можно нажатием кнопки USR на плате с микроконтроллером.
import machine
from machine import Pin
import time
from time import ticks_ms
PWM_PIN = 23 # пин PWM
PWM_FREQ = 100 # частота PWM
PWM_DUTY_US = 100000 # длительность каждого импульса в микросекундах
class Button(object):
rest_state = False
# pin = None
# pin_number = 0
RELEASED = 'released'
PRESSED = 'pressed'
DEBOUNCE_TIME = 50
def __init__(self, pin, rest_state = False, callback = None, internal_pullup = False, internal_pulldown = False, debounce_time = None):
self.pin_number = pin
self.rest_state = rest_state
self.previous_state = rest_state
self.current_state = rest_state
self.previous_debounced_state = rest_state
self.current_debounced_state = rest_state
self.last_check_tick = ticks_ms()
self.debounce_time = debounce_time or Button.DEBOUNCE_TIME
if internal_pulldown:
self.internal_pull = Pin.PULL_DOWN
self.rest_state = False
elif internal_pullup:
self.internal_pull = Pin.PULL_UP
self.rest_state = True
else:
self.internal_pull = None
self.pin = Pin(pin, mode = Pin.IN, pull = self.internal_pull)
self.callback = callback
self.active = False
def debounce(self):
ms_now = ticks_ms()
self.current_state = self.pin.value()
state_changed = self.current_state != self.previous_state
if state_changed:
self.last_check_tick = ms_now
state_stable = (ms_now - self.last_check_tick) > self.debounce_time
if state_stable and not state_changed:
self.last_check_tick = ms_now
self.current_debounced_state = self.current_state
self.previous_state = self.current_state
def check_debounce_state(self):
if self.current_debounced_state != self.previous_debounced_state:
if self.current_debounced_state != self.rest_state:
self.active = True
if self.callback != None:
self.callback(self.pin_number, Button.PRESSED)
else:
self.active = False
if self.callback != None:
self.callback(self.pin_number, Button.RELEASED)
self.previous_debounced_state = self.current_debounced_state
def update(self):
self.debounce()
self.check_debounce_state()
onboard_led = Pin(25, mode=Pin.OUT, value=0)
pwm_enabled = False
pwm = machine.PWM(Pin(PWM_PIN), freq=PWM_FREQ)
def pwm_button_callback(pin, state):
global onboard_led, pwm_enabled, pwm
if state == Button.PRESSED:
pwm_enabled = not pwm_enabled
if pwm_enabled:
pwm.duty_ns(PWM_DUTY_US)
print("PWM active!")
onboard_led.value(1)
else:
pwm.duty_u16(0)
print("PWM stoped!")
onboard_led.value(0)
def main():
#lcd = SoftwareLcd()
bu = Button(pin=24, internal_pullup=True, callback=pwm_button_callback)
while True:
bu.update()
#onboard_led.value(onboard_led.value() ^ 1)
#lcd.send_data(0x40)
time.sleep_ms(1)
if __name__ == '__main__':
main()