Need help with fast (microsecod timing) code.
Patrick Coleman
Posts: 43
in Propeller 1
Hello all, I'm new to the propeller and BS2, and programming for that matter. Ive read some threads and looked through some obvious sites, but I cant find a solution to this problem.
I need a square wave that I can vary from 5uS to 20uS. I just need to type the values in, then compile, I'm replacing some of my 555 timers and I want to start with a simple program for this application.
Heres my attempted code:
CON
_CLKMODE = XTAL1 + PLL4X 'low-speed crystal x 4
_XINFREQ = 5_000_000 'external crystal of 5 MHz
PUB main
dira [0] := 1
repeat
outa[0]:=1
waitcnt(clkfreq/100000+cnt)
outa[0]:=0
waitcnt(clkfreq/100000+cnt)
I have a 5Mhz crystal attached, but I'm not sure if its doing anything.
the physical circuit and other code does work. Oscilloscope says slower waves are possible.
Please help.
I need a square wave that I can vary from 5uS to 20uS. I just need to type the values in, then compile, I'm replacing some of my 555 timers and I want to start with a simple program for this application.
Heres my attempted code:
CON
_CLKMODE = XTAL1 + PLL4X 'low-speed crystal x 4
_XINFREQ = 5_000_000 'external crystal of 5 MHz
PUB main
dira [0] := 1
repeat
outa[0]:=1
waitcnt(clkfreq/100000+cnt)
outa[0]:=0
waitcnt(clkfreq/100000+cnt)
I have a 5Mhz crystal attached, but I'm not sure if its doing anything.
the physical circuit and other code does work. Oscilloscope says slower waves are possible.
Please help.
Comments
for square waves also look at
https://www.parallax.com/downloads/an001-propeller-p8x23a-counters
There are timer modes for generating square waves.
A few lines of code will set them up, and you can get 80MHz/N with possible 12.5ns edge jitter on non binary N.
If other code works, the 5MHz is ok.
Ive read the PDF before, and I see it can go fast (12.5ns), but is this related to the clock register?
Do I load it with values, then use it?
I also meant to say that id like to control the high and low time separately.
EDIT:
the following code did work up to 62uS:
CON
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
Pin = 0
Frequency = 40_000
PUB main
dira [0] := 1
repeat
outa[0]:=1
waitcnt(clkfreq/200000+cnt)
outa[0]:=0
waitcnt(clkfreq/200000+cnt)
but I thought a 100kHz wave would be possible with a propeller.
(note: the syntax may need some tweaking. It's been a while since Spin...)
The basic idea is that you want your calculation of the next waitcnt point to not be extra on top of the waitcnt delay. If it is you'll get a slower and irregular frequency. As long as the loop can execute before the delay time point comes up this code will work. If you make the delay too short then you'll miss the window and have to wait 53seconds+ for it to roll over.
Software generated pulses of 100KHz and higher are possible with PASM, but not spin. You would have to use the counters in spin to get to that frequency.
http://obex.parallax.com/search/signal generator.
This particular one may do what you want and more.
http://obex.parallax.com/object/688
Assembly code will be needed to update the HI/LO times 'live', and there will be some lower limit on PWM times.
If you have spare pins, you could use 2 pins and an external XOR gate, and use Counter-phase control to generate PWM,
and that would have a LSB step of 12.5ns
Ive looked at that code, and it looks like it does what I want, I just don't know how to get it to work. I see numbers at the top for each waveform, but do I uncomment or change one ?
I'm trying to avoid using my STM32 demo boards, but they do have dedicated timers.
That offers the benefit of the highest resolution, 12.5ns with the 80MHz clkfreq. There are 400 clock transitions in your 5µs/100kHz scenario, which is not that many really given that you want to have varying times of high and low.
There is a demo there, PWM_3ctrx_demo.spin. To use it in your one program you can include it as an object and then call its method that does the dirty work.
Test: http://obex.parallax.com/object/482
(I see it ramps an LED from pin 6, so ill need to change that.)
I'm still new at programming, hence moving on from the BS2 and trying to avoid the STM32. I'm going to look in more detail at this code, it looks complicated. but seems to do the high speed PWM thing.
EDIT:
I don't know if I can figure this out, its complicated and I think I'm just going to screw it up.
Hardware counter (NCO single-ended) and you can set and forget,
unless you need constant ramping up-down of the Hz after each cycle as then you will be very busy updating the FRQa values.
But as you have cogs, one can be dedicated to do just that.
The engine-room code is a little complex, but you just call it like this :
freak.PWMctrx3(pin,frequency,percent)
Very simple to use.
If you are ok with only 0..50% range, then you can save a pin, and have up to 8 of these running.
I'm still not sure, I cant seem to 2 of the 3 files from : [url="http://obex.parallax.com/object/482"[/url]
the one I can get to work is just the simple LED ramping one.
how do a call the freak.PWMctrx3(pin,frequency,percent) ? keep in mind ive only had a few days with spin.
That uses 3 counters at 2/COG, means you can fit 2 generators into 3 COGS or 4 into 6 or 5 into 8
How many channels do you need for " replacing some of my 555 timers" ?
The Counter phase approach used by Tracy, is pretty much the only way to get 2%~98% on 5us, as SW tracking code likely has higher minimum times.
The HW approach of Counter phase allows 400 steps of Duty Cycle for 0.25% step size at 5us.
Patrick, you're asking how to use it. Can you explain a bit more what your goal is, as you say, "I'm replacing some of my 555 timers and I want to start with a simple program for this application." What application?
On the Prop1, having a adjustable freq square wave is way simpler than pwm as P1 does not have hardware pwm settings.
As picture below show, pwm have a fixed freq but its duty can be adjusted (but is not a signal you would use with a transformer).