Need Help with Simple PWM Program.
Patrick Coleman
Posts: 43
Hello !
Background:
Im needing help with some programming. I need to move pat the basic stamp series, and I don't like the STM32 / arm development environment. its really convoluted.
Id like to learn this new Propeller IC and its C / SPIN programming.
Question:
Is there a simple PWM program I can write which follows the pseudo code below (I need it in C, I think its faster than spin):
I need to start learning, but cant find any examples, but for those that are for steppers and servos.
I also don't want the "count-clock-cycles-and-waste-them" program method, that's lame.
Background:
Im needing help with some programming. I need to move pat the basic stamp series, and I don't like the STM32 / arm development environment. its really convoluted.
Id like to learn this new Propeller IC and its C / SPIN programming.
Question:
Is there a simple PWM program I can write which follows the pseudo code below (I need it in C, I think its faster than spin):
Start
Pin Z high for X microseconds.
Pin Z low for Y microseconds.
repeat endlessly . . .
I need to start learning, but cant find any examples, but for those that are for steppers and servos.
I also don't want the "count-clock-cycles-and-waste-them" program method, that's lame.
Comments
To get a description of each of these three functions start up SimpleIDE and click on the HELP button at the top. Select Simple Library Reference and in the following page near the top and click on simpletools.h under the Utilities heading. Scroll down to the Timed I/O subsection and find pwm_start, pwm_set, andpwm_stop. Click on these links for a detailed description.
On the Prop it's pretty normal to use waitcnt in a loop to get precise timing, so I'd write your code like this:
You'd have to be careful to keep the high & low times to probably 10 microseconds or better, because Spin isn't terribly fast.
but my oscilloscope says it doesn't work ?
im also looking here: https://propsideworkspace.googlecode.com/hg/Learn/Simple Libraries/Utility/libsimpletools/html/simpletools_8h.html#a57f683188c3dd35ee0574ff349835682
Depending on the memory model, that may not be enough time. Try bumping it to 100 us and then if that doesn't work, 10,000 us.
Parts of this code were extracted from my robot project where I use a pair of LM18200 motor drivers.
I do not use the pwm_stop function since the motor routines actually reside in a while(1) loop.
Repeat the pwm_set() function when you want to change speed with a new 3rd parameter
I tossed in a few definitions because many C programmers loathe seeing numbers in the code, but I did violate that twice here
From looking at your code, I suspect that your only mistake is not setting your pin as an output. When the Prop starts up, all pins are inputs by default.
Note that I am directly setting the pin outputs instead of using pulse_out.
Your original code used pulse_out(), which only does the timing for you on the high side - it turns on the output, waits, then turns it off, so you could use that instead, like this:
low() and high() set the DIRA register. Source
Since you've used the BASIC Stamp then you will find Spin to be very easy to learn since it's about 3/4 the same as PBASIC.
The Propeller Education Kit text is the best introduction to Spin that I've seen though I do wish Andy had used Constants more.
Since Spin is the Propeller's native language most code is written in Spin and uses Assembly (PASM) when speed is needed.
https://www.parallax.com/product/122-32305
I myself never felt comfortable with C but Andy's Propeller C Tutorials on the Learn website are very well written and made C a lot friendlier.
http://learn.parallax.com/propeller-c-tutorials
JonnyMac mentioned the Cog Counters and Andy wrote a whole chapter on using them in the Propeller Education Text (Chapter 7).
https://www.parallax.com/sites/default/files/downloads/122-32305-PE-Kit-Labs-Fundamentals-Text-v1.2.pdf
now ive got a primitive program running, my oscilloscope says so. But . . . it only runs in ram I guess. as soon as I unplug the USB cord the propeller stops working ! when I press the load to EEPROM and run button it just gives an error.
code here:
its junk code but does what I want, which is a transformer waveform to play with a time period.
Ooops.
so it wont run even in ram programmed then disconnected with the battery attached, and the USB cord out ?
No. Pulling out the USB cord will usually reset propeller.
so im looking at your guys' code examples.
Ive tried this:
but my oscilloscope says it doesn't work.
I need to vary the on and off time pretty wide. Id like to use C , as I cant understand spin or how to open those file type.
I've never been presented a specification with the term, "pretty wide." How do you define that?
If you can't understand Spin I maintain you don't have a chance at learning C. Sorry if that seems harsh, but Spin is far easier (and in my opinion, more elegant). Spin was designed for the multi-core Propeller and is tightly aligned with the architecture. Please believe me that learning Spin will not be a waste of your time, even if C does become the best choice for your application. Learn the Propeller, then learn how to apply your language choice to it.
FTR, delays in the Propeller are handled with a command called waitcnt -- anything offered by a HLL is a wrapper for this.
As I've stated many times, you can use the Propeller counters to generate pulses; if you do this within a precisely-time loop (possible with waitcnt), you get a nice PWM output. I've attached another demo; this one uses an external version of my 2-channel pwm engine (yes, still in Spin). This version lets you change the frequency 1 to 38kHz, and the duty cycle (0.1 to 100.0 in 0.1Hz increments). Open a terminal window to change a parameter (see the DAT section with parser info for commands).
You can load this into and program the Propeller with Propeller Tool or Propeller IDE -- both a are available from Parallax.
Maybe Dave or one of the other C gurus will port a version of my pwm object to a C library (I don't use C which is why I don't have the library already).
All waits are implemented as some variant of this:
It'll go a little faster if you pre-calc the delay, since CLKFREQ on the Prop isn't a constant, though it's very typically 80,000,000.
In Spin, the language overhead per statement is just under 400 clocks, so you need to wait a minimum of that, or you'll end up waiting until the clock register rolls over, which takes about 53 seconds.
In C, it depends on what you're compiling as. CMM is about 2x the speed of Spin. LMM is nearly machine language speed, so a wait of 30 or 40 clocks minimum would likely be enough.
You said before "the waveform doesn't have enough high or low range using the pause() function" - Pause can wait for an arbitrary amount of time - minutes, seconds, microseconds, . . . so it seems unlikely that's an issue.
At its simplest, PWM in C is this (most of the text is comments):
1 uS increments and 200 kHz with variable duty cycle (up to 90%). 5 uS or there abouts would be 200 kHz. the STM32 has hardware timers that are programmed, I think in the way JasonDorie shows.
My crystal says 5.000 does that mean I'm running my prop at 5MHz unless I'm upping it with a PLL ? (I don't know if I am.)
It does seem like the code overhead is a limiting factor, I think, from what my oscilloscope says. At some point I see a 50% fast wave, that refuses to go faster in Hz (fewer uS).
I'm with JonnyMac.
Using PASM for programming the Propeller, you should be able to get an ON time of any number from 1 usec or longer, to as long as you like, and for an OFF time, the same thing. So just pick your numbers, and you can get 12.5 nano second granularity.
PASM code would be in the order of a dozen or two instructions..... so, time to learn assembler. We can help if you pursue that route.
Cheers,
Peter (pjv)
That's only a single clock cycle at 80 MHz. You'll only be able to get that kind of granularity with a counter right? And the counters can be set from any language - spin, pasm, C, tachyon, etc etc etc
You can get single clock granularity from the WAITCNT instruction. But I doubt you could get a programmed ON or OFF period as short as 1 usec from Spin.
Not sure about C or Tachyon as I am unfamiliar with those.
The hardware counters can also work.
Cheers,
Peter (pjv)