The issue of controlling the pulse width using PWM on the pyb.Timer library

Hello, I want to use pyb.Timer to control the precise pulse width function. However, the pulse width accuracy of the pulse_width_percent method is not sufficient. Therefore, I attempted to use pulse_width to control the precise pulse width. I set the pulse_width to 3000, and the PWM frequency to 50Hz. On the oscilloscope, I observed that the pulse width was approximately 1500us.Then I changed the frequency to 100Hz, the pulse width remains unchanged.
Here is my code and the measured images:

import pyb,time

timer = pyb.Timer(2, freq=50)
ch1 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin("P4"), pulse_width=1000000)

while True:
    a=1

I would like to know the calculation formula between the “pulse_width” and the actual pulse width.Could you give me some help? Thanks!

Sorry, the code used in the above picture for the test is this one.

import pyb,time

timer = pyb.Timer(4, freq=50)
ch1 = timer.channel(1, pyb.Timer.PWM, pin=pyb.Pin("P7"), pulse_width=3000)

while True:
    a=1

Later, I also tested the P4 pin of Timer2, using the first piece of code in this topic.

Hi, the issue here is that the pulse width value is pretty much directly passed to the timer without any scaling to an actual value. class Timer – control internal timers — MicroPython 1.25 documentation

So, it’s literally going to be a value based on the timer freq that will be different per camera. I’ve asked Damien to work on getting machine.PWM working on the STM32 line of processors so the PYB module can be left behind for this.

Anyway:

import pyb,time

pulse_width = 3000 # in us

timer = pyb.Timer(4, freq=50)

freq = timer.source_freq()
period = timer.period()
prescaler = timer.prescaler()
print(freq, period, prescaler)

# caluclate pulse width in timer ticks (accounting for prescaler)
p = int((pulse_width * (freq / (prescaler + 1))) / 1000000) - 1

ch1 = timer.channel(1, pyb.Timer.PWM, pin=pyb.Pin("P7"), pulse_width=p)

while True:
    pass

This gives 3000 us exact. I checked on my scope.