Can someone explain how to alter your duty cycle on your PWM pins using the Maple rev5 based on the instrument you are controlling? For example if my pwm controlled component operates on 300MHz but the Maple operates on 16MHz how can we calculate, on the maple, how to change our duty cycle to fit the needs of the component? The issue is correctly programming the maple.
PWM dutyCycle
(10 posts) (3 voices)-
Posted 4 years ago #
-
I'm not sure what you mean.
The Maple runs at 72MHz. So the shortest possible pulse is much slower than 300MHz.
The duty cycle of a PWM signal is set with pwmWrite
http://leaflabs.com/docs/lang/api/pwmwrite.html#lang-pwmwriteThe signature is:
void pwmWrite(uint8 pin, uint16 duty_cycle)
so the duty-cycle is a number in the range 0 to 65,535, with 0 being continuously off, and 65,535 continuously on. Everything else is duty_cycle periods of the underlying timer's count period.Do you mean pwm frequency?
Posted 4 years ago # -
I'm sorry I wrote that completely wrong! Ok so maple run's off of 72MHz, and I am trying to control a servo. I'm guessing the maple is running extremely to fast to control the servo. So I'm assuming it is as simple as connecting the servo directly yo the maple's VCC, GND, and whatever pin I choose to use for control. For instance if I choose pin5 for my PWM control. I just simply write:
void pwmWrite(uint8 FanPin, uint16 37768)would this be what I need to control the PWM at half the rate?
And yes, how would I set the frequency?Posted 4 years ago # -
For a normal (analogue) model servo, you want a pulse frequency of close to 50Hz, i.e. 20 millisecond cycle duration (Some seem to work with 16millisecond).
Then the pulse needs to be between 1 millisecond and 2 milliseconds long, with 1.5 milliseconds being centre '90 degrees'.
There is documentation of a Maple timer interface here:
http://leaflabs.com/docs/libmaple/api/timer.htmlThe documentation is so baroque, ugly and complex, that I can't see the wood for the trees. Maybe you will have better luck.
Timer's are 16 bits, so ideally, it will count to 65,536 in 20 milliseconds, or at 50Hz.
For a simple square wave, that needs a prescaler of 21.97, so lets call that 22. That is less than 1% error, which servos should easily cope with. For a symetric PWM signal, it is half that, i.e. 11 (I'm a bit busy to check which one it is)
So the 72MHz clock is divided by 22, (or 11) to give 3,273 KHz basic count rate. So each count is about 0.3 micoseconds
That will need the "void timer_set_prescaler(timer_dev * dev, uint16 psc)" function.
Then the timer will give the right servo signal frequency.
Then the angle is a value between 1msec and 2msec. Which would be pwmWrite values of
1msec/0.3microsec = 3273
1.5msec/0.3micros = 4909
2msec/0.3microsec = 6546HTH
{Start Rant: The documentation for Timer is very hard to navigate. Grrr. End Rant.}
Posted 4 years ago # -
LOL thanks alot. I can understand the frustration. Well I actually found out that my code was working, BUT my pin 5 was bad...probably a cause by my negligence. At any rate, I can control my servos BUT I am trying to control a fan. This may be a wiring issue, due to lack of documentation for the fan we bought, but I want to try every approach before I assume that the choice in fan was bad.
Posted 4 years ago # -
perhaps the hand written docs for the timers are more useful?
http://leaflabs.com/docs/lang/api/hardwaretimer.html#lang-hardwaretimer
unfortunately, the setPeriod function had a bug introduced in 0.0.11 by accident. You can use this function instead:
/* 0.0.11 breaks timer setPeriod, so lets provide a working version here */ uint16 timer_set_period(HardwareTimer timer, uint32 microseconds) { if (!microseconds) { timer.setPrescaleFactor(1); timer.setOverflow(1); return timer.getOverflow(); } uint32 cycles = microseconds*(72000000/1000000); // 72 cycles per microsecond uint16 ps = (uint16)((cycles >> 16) + 1); timer.setPrescaleFactor(ps); timer.setOverflow((cycles/ps) -1 ); return timer.getOverflow(); }
and you can incant the setperiod like this:
#define AUDIO_RATE 15 /* timer period in us */ ... // Setup Timer Timer2.setChannel1Mode(TIMER_OUTPUTCOMPARE); /* 0.0.11 IDE bug, setPeriod is no good */ //Timer2.setPeriod(AUDIO_RATE); // in microseconds timer_set_period(Timer2,AUDIO_RATE); Timer2.setCompare1(1); // overflow might be small Timer2.attachCompare1Interrupt(handler_t);
Posted 4 years ago # -
btw, thats for a timer interrupt. If you just need the PWM frequency changed, you can just call timer_set_period and jump straight to pwmWrite ... I just pulled this from a sketch I happened have handy.
Posted 4 years ago # -
thanks alot!
Posted 4 years ago # -
poslathian - is their a bug in
void setPrescaleFactor(uint32 factor)
?If not, that can be used to set the prescaler, and nothing else should be needed; pwmWrite should 'Just Works' (TM:-)
It happens that a 50Hz frequency for the model servo is quite close to the clock divided by 65,536 (the normal reload value) pre-scaled by 11 or 22, depending on whether the timer is in 'up counting' mode (prescale 22), or 'up/down counting' mode (prescale 11.
The only question is whether the timers are set up for 'symmetric' PWM using 'Center-Aligned' 'up/down counting' mode, or simple 'up counting' mode, which effects the prescale value used.
The documentation for timer_mode at
http://leaflabs.com/docs/libmaple/api/timer.html#project0timer_8h_1a28110292f2481f7b44d1517fb4ce3c15
says the default for the timer is 'TIMER_PWM'.Edit:
I checked the code fortimer_int
and the counter is in 'up-count' mode, so the appropriate prescaler value 22.(I realise this calculation is MCU clock dependant, but, at the moment all LeafLabs boards, and mine, run at 72MHz :-)
Posted 4 years ago # -
I had a look at the timer setup, 'void timer_init(timer_dev_num timer_num, uint16 prescale)`
in libmaple timers.c & timer.h, the mode is:
timer->CR1 = ARPE; // No clock division // Do not buffer auto-reload preload // Edge aligned // Upcounter // Do not stop counter at update event // Update events enabled (etc, see bits [1:2]) // Counter disabled for now
and APRE is:
#define ARPE BIT(7) // Auto-reload preload enable
This means the counter in the timer is in 'up-count' mode, and not 'up/down count' mode, so the prescaler is 22.
Posted 4 years ago #
Reply
You must log in to post.