sameh4
Posts: 40
Joined: Wed Nov 29, 2017 6:58 pm

Reasoning about PWM for a DC Motor Driver

Mon Dec 11, 2017 7:06 pm

I am learning how to directly program the PWM controller to set the speed and direction of a DC Motor.

The concepts are not 100% new to me because I've used Pi hats like this one https://www.pololu.com/product/2756 from Pololu and they have some startup code in python that's easy to learn. But that's based on using a Linux OS.

I am back to the Broadcom Peripherals Manual https://www.raspberrypi.org/app/uploads ... herals.pdf

And this good article on PWM https://www.embedded.com/electronics-bl ... Modulation

Also spent time looking at the WiringPi library's code and the RPIO code and even found this very simple and straight forward implementation in C++ https://gist.github.com/aboarya/94f836f ... m-cpp-L384

The information I've gathered so far is:
1) PWM Mode 0 can be enabled on GPIO pins 12 and 18, which map to Pi pins 32 and 12 on the board respectively
2) PWM0 aka MSEN0 can be used on channels 1 and 2, using the RNG1 and DAT1 registers for channel 1 and RNG2 and DAT2 for channel 2
3) Bits 0 and 1 of the CTL register enable and set the mode for channel 1
4) Bits 8 and 9 of the CTL register enable and set the mode for channel 2 ; the manual's CTL register table has a misprint here as best I can tell
5) The RNGi registers can be used to set the period, in MSEN0 this is the M in N/M
6) The DATi register can be used to set the N in the N/M for MSEN0
7) N and M here can be unsigned integers
Looking at the below code, a couple of things I still dont get

Code: Select all

//set divisor
  *(clk + PWMCLK_DIV) = 0x5A000000 | (this->divisor << 12);
1) The C++ code sets the PWM Clock Divisor. I couldn't find any info in the manual on this:
2) What is the clock register and what is this value ? 0x5A000000
3) What is the clock divisor?
4) Where can I find this info on the Broadcom BCM2835 and/or other Pi's? I could not even find the CLOCK's base address
Finally, I am looking for guidance on good heuristics about the PWM formula in terms of a DC motor. Let's assume I want to power up a small DC motor to drive a single wheel of small robot car with a 9V battery.

What are good choices for the frequency such that changing the duty cycle percentage in the value of DAT1 will change the speed of the robot in a **reasonable way?

dwelch67
Posts: 944
Joined: Sat May 26, 2012 5:32 pm

Re: Reasoning about PWM for a DC Motor Driver

Mon Dec 11, 2017 9:50 pm

is there one universal answer?

The pwm frequency is ideally faster than the motor/system can respond to, otherwise it sits there and oscillates or wiggles. But it doesnt want to be so fast that it is filtered out as noise. You can of course intentionally put your own filter in the system to turn it into a smoother control voltage.

I imagine if you sweep the frequency range you can find the edges at least, I have not actually messed with the PWM (yet) on the pi so dont know what the min and max frequency range is (period, not counting the duty cycle effects)

sameh4
Posts: 40
Joined: Wed Nov 29, 2017 6:58 pm

Re: Reasoning about PWM for a DC Motor Driver

Tue Dec 12, 2017 12:10 am

I came across this document that's targeted for the BCM2835 Audio clocks, but it looks like there's a lot of great info there.

https://www.scribd.com/doc/127599939/BC ... dio-clocks

Firstly now I know the real address of the CM_PWMCTL register. How to enable/disable the clock. As well as the address of the PWM divisor (but not yet what a divisor is )

Looks there's a lot of info there that's new to me, so I need to read it more carefully before writing some code. Will post back here what I was able to find.

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 8 guests