PASM counter setup question
turbosupra
Posts: 1,088
I'm trying to set up pin 25 to start as a low output and configured for a counter type of DUTY single-ended mode. Then I'd like to adjust the counter pulse width (and in turn average voltage) by setting frqa. I've gotten this working in spin, but cannot get it working in PASM. Pin9 is also an output and doing something different.
dira binary output on the pst yields
00000010000000000000001000000000
outa binary output on the pst yields
00000000000000000000001000000000
ctra binary output on the pst yields
00011010000000000000000000000000
frqa binary output on the pst yields
01111101001010110111010100000000 (not posX2, but still 1050000000 which should register)
But the pin itself doesn't generate any pwm voltage. What am I doing wrong?
Here is the spin code I'm mimicking
dira binary output on the pst yields
00000010000000000000001000000000
outa binary output on the pst yields
00000000000000000000001000000000
ctra binary output on the pst yields
00011010000000000000000000000000
frqa binary output on the pst yields
01111101001010110111010100000000 (not posX2, but still 1050000000 which should register)
But the pin itself doesn't generate any pwm voltage. What am I doing wrong?
rdlong mafPin, mafPinPtr mov mafPinMask, #1 ' create mask from pin # shl mafPinMask, mafPin or dira, mafPinMask ' sets direction to 1 for an output andn outa, mafPinMask ' sets pin to 0 for a low starting output (or for high) mov ctra, mafPinCfg ' counter to single-ended mode, ctra := %00110 << 26 + CurrentTripSetPin or ctra, mafPinMask ' ctra to use pin 25 mov frqa, posX2
Here is the spin code I'm mimicking
PUB Main pst.start(115200) dira[CurrentTripSetPin]~~ outa[CurrentTripSetPin]~ ctrb := %00110 << 26 + CurrentTripSetPin 'frqx := ( centi_volts * ( POSX / 3.3 / 100) ) << 1 skew := (POSX / 330) ' the equivalent of 1 single centiVolt centiVolts := 27 ' repeat '''''' test values, produces voltages as shown 'frqb := -1 '3.265V***** 4.294B ' 3.21/3.25 'frqb := -2_147483646 '1.655V***** 2.147B ' 1.57/1.62 'frqb := 2_147483647 '1.655V***** 2.147B ' 1.57/1.62 'frqb := 0 '0.000V ' 0.00/0.00 frqb := (((centiVolts * ((POSX / 33) / 10)) + (4 * skew)) << 1) pst.dec(frqb) pst.char(13) pst.dec(centiVolts) pst.char(13) pst.char(13) 'centiVolts += 1 waitcnt(clkfreq + cnt)
Comments
or ctra, mafPin
not
or ctra, mafPinMask
I knew it was something stupid ... ugh!
So can you tell me what the difference is? The values are the same, so it's how they were applied. One is the 25th bit being set to "1" and the other is a cumulative numeric value of 25. Are bits 5..0 summed to get the A pin? Is that what I misunderstood about the register?
ctra for mafPinMask
00011010000000000000000000000000
ctra for mafPin
00011000000000000000000000011001
Table 2-5: CTRA and CTRB Registers
31 -
30..26 CTRMODE
25..23 PLLDIV
22..15 -
14..9 BPIN
8..6 -
5..0 APIN
FRQx = Fout / CLKFREQ * 2^32
FRQx = 2^32 / N
http://forums.parallax.com/showthread.php?87905-The-counters&highlight=frqx+pasm
You can have up to 2^32 different pulse width output settings. I did a voltage range (5v) * 100 divided by 2^32 to get a centiVolt value and that gave me 13015052
or 2^32/(3.3*100) = 13015052
After that (this isn't quite exact because of a slight skew, but it is close) I can just do any value between 0 and 330 (which is 3.3v * 100) multiplied by "centiVolt" to get a corresponding average voltage value.
So 300 = 2.95v and 320 = 3.15v (notice there is an approximate .05 skew)
Next I will probably compute a millivolt value for added accuracy, 2^32/(3.3*1000) = 1301505
2. In your previous math, I don't see why you are bringing the factor of 5V into the math. I think you meant to write 3.3V? If you have that simple RC filter on the Prop pin output, and you want a centivolt multiplier, it is
....frqa = 2^32 * 0.01/3.3 = 13015052
as you have. In general, if you want an output voltage of Vx, then calculate,
....frqa = 2^32 * Vx / 3.3 = ????
3. In reference to the 0.05V skew you observed, the 100kΩ resistor in your RC filter is going to form a voltage divider with the input impedance of your voltmeter, and that will reduce the measured voltage proportionally. The RC values of 100kΩ with 10µF are probably higher than they need to be. Try 10kΩ with 1µF. There are tradeoffs of smoothing, speed and jitter, but even smaller values are suitable for most purposes.
That was a typo, it is supposed to be 3.3v thank you for catching that. (I'll edit the post now)
I will change my R/C components tonight and see how that works, the voltage divider makes sense. Thanks for confirming my suspicions about the register bit locations also, I will have to be more careful when reading the prop manual to make sure I don't make that mistake twice!