PWMOUT on 18M2 with 50 percent duty

piclt

Member
I am trying to program pwmout on an 18M2+ using ......

PWMOUT PWMDIV64, pin, period, duty_cycles

Period has to be integer 0 to 255 and duty_cycles has to be an integer 0 to 1024
and it turns out that if the duty_cycles integer value is always kept twice the period integer value it will always generate a 50% duty square wave train of pulses at a frequency depending on the period integer value.

So.... pwmout pwmdiv64, B.3, 254, 508 ..... is the lowest frequency obtainable

and ..... pwmout pwmdiv64, B.3, 127, 254 ...... will be a higher frequency approx. double that frequency.
PWMDIV64, PWMDIV16 etc gives coarse freq. control by dividing by 16 or 64 etc.
There is not a command to enter a period value on its own but there is a command to enter PWMDUTY on its own.
And the manual recommends using PWMDUTY to change duty rather than another PWMOUT command as PWMOUT stops and starts the timer each time whereas PWMDUTY just varies the duty value on a continuous train.

So in my case if I want a continuous train I would need a command to enter a period value along with 2 times that value for duty_cycles.

When I issue new PWMOUTs .... I can get glitches etc at where the transitions takes place, not bad, but sometimes noticeable....

Is there a way of talking directly to the actual registers for period that would do this either by basic code or assembler etc so that when pwmout is started it would just continually read the period and duty values and follow them if they changed without issueing another pwmout command. ......????
 

AllyCat

Senior Member
Hi,

Actually, the "period" variable starts counting from zero (to give a period of 4) so the lowest possible frequency with a Duty Cycle of 50% is : pwmout pwmdiv64, B.3, 255, 512 .

Yes you can write directly to many of the hardware registers with the POKESFR commands (and read with PEEKSFR) and in fact many commands such as PWMOUT are only a slightly disguised POKESFR command. However, PWMDUTY is quite a complex command, it consumes quite a lot of Program Memory (do a Syntax check with and without it) and it takes a long time (many ms) to execute, so personally I only use it where a timing glitch may cause a problem.

You cannot usefully use "Assembler" in PICaxe Basic, but the PEEK/POKESFR commands do permit many other (sometimes faster) functions to be achieved, with reference to the Advanced Technical Details in the appropriate Base PICaxe Data Sheet

Cheers, Alan.
 

piclt

Member
Thanks for reply..... yes, not much difference between 255 and 254.....I used 254 because divisable by 2......??
But the same problem I cannot issue a change period command without issuing a new pwmout command.....? PWMDUTY is Ok I can send it ok.
I looked at PEEKSFR to try and read the registers as I changed the PWM but probably looking at wrong registers. I looked the datasheet ( I wish I could read datasheets) and it told me .....PR2, or PR4, or PR6 are the Period registers at address 01Bh, 416h and 41Dh. The manual says to use bytes for peeksfr so I did ...... peeksfr $1B,b20 etc for each. The values I got were 01B = 255, 416=38 and 41D=0 when sertxd to terminal.
so need some guidance on how to do this or find the info to do it, please.
 

AllyCat

Senior Member
Hi,

A period of zero cycles is not useful, so the PIC internally adds 1 to the register value, and then multiplies it by 4 to give a maximum period of 255+1 * 4 = 1024 "timeslots",which will always be even. ;) However, AFAIK a duty value of 1024 is not valid (only a 10 bit register, maximum 1023) so if you want to drive the PWM to a full 100% (as opposed to just setting the pin High) then the maximum period register should be 254 (i.e. 1020 timeslots), allowing a 100% duty cycle with a register value of 1021 to 1023.

PR4 and PR6 appear to be in Bank 8, which is not accessible with the M2's SFR coding. Each bank has a "weight" (i.e. multiplier) of $20 (decimal 32), i.e. Bank zero maps to $00 - $1F , Bank 1 to $20 to $3F , etc. up to Bank 7 = $E0 to $FF. So only your PEEKSFR $1B ,... can be correct; did you actually write 255 or 254 to it (e.g. as the PWMDUTY period value) ? I don't use 18M2s myself, and don't know which internal counter/timers are actually used for the PWM channels. I think there might be some clues in the old "paper" Manual 2 : Appendix 4 - "Possible Conflicting Commands".

Cheers, Alan.
 

piclt

Member
Thanks for reply....... I will need to read up a bit.
But I will not be running at 100%.....at 100% or near it you get very narrow glitches due to one pulse stopping and the next with very narrow space.
Maybe I am not explaining my problem very well so here is a test prog......
This is a test prog I was running......its just copied and mod from the manual. attached is wave trace recorded on audacity to get a look at it.
It starts with period 150 and duty twice that value at 300 and give 50% duty...OK
It then changes the duty cycles using pwmduty and %duty changes.....OK and the period or freq. stays the same......and the pwm timer is not stopped and started and no glitches.
I want to be able to change the freq, without changing the duty% and without starting pwmout again..... just a command like "pwmfreq" or write directly to the register. I will probably be running at 50% for all freqs.

init: pwmout pwmdiv64,B.3,150,300 ; start pwm
pause 50 ;div64 to get low freq

main: pwmduty B.3,150 ; set pwm duty
pause 50 ; pause 50ms

pwmduty B.3,50 ; set pwm duty
pause 50 ; pause 50ms

goto main ; loop back to main

PWM1.jpg
 

AllyCat

Senior Member
Hi,

If you want to change the frequency but keep the duty cycle the same, then both the period and duty registers will need to be updated (with duty = period + 1 * 2 for a 50% duty cycle). Two separate POKESFR commands will probably cause a glitch because the Interpreted commands will be separated by perhaps 0.5 ms. I don't recall how long the PWMOUT command takes to execute (but it's much less than PWMDUTY).

So I don't know if it's possible to avoid glitches (because the PICaxe interpreter must always execute much slower than Assembler or Machine Code). But when we were developing code to create Modulated Infra Red commands (by turning a 40 kHz PWM output Off and On), it appeared that the "chip" (hardware) always completed a PWM cycle before changing the duty cycle (because it didn't ever seem to generate "partial" pulses). The relevant thread is HERE and contains a few further links which might be relevant.

Cheers, Alan.
 

hippy

Technical Support
Staff member
I don't know if it's possible to avoid glitches (because the PICaxe interpreter must always execute much slower than Assembler or Machine Code)
I am not sure it is possible and there is not a PICAXE command which allows just the frequency to be changed. It may be possible to simply POKSFR registers but needing multiple registers to be poked means there is always the possibility of an undesirable configuration and glitches during the process of doing that. That would likely be particularly noticeable if changing the divisor and frequency setting.
 

piclt

Member
I think the glitches I was getting was probably due to the combination of some of the settings
With the prog below I can scan up and down through the freqs. from about 60Hz to about 4Khz smoothly.
So maybe pwmout is OK to use at every change of period/duty etc..... although it says in the online manual for to use pwmduty command to change duty...???

Regards the registers.... I cannot get anywhere with them peeking or poking. Is the 18M2+ a PIC16F1847......I downloaded the datasheet and it tells me the PR2 register is the Timer2 pwm Period and its address is 01Bh so in a fornext loop I pokesfr $1B, xxx etc various values and I cannot see anything happen. Am I reading the correct datasheet and addresses....????

init:;
#picaxe 18m2
setfreq m16

main:
for b0=5 to 255 step 5 ; b0 is the period
w1=b0*2 ;calculate the DUTY = period x2=50%
pwmout pwmdiv64,B.3,b0,w1
pause 1000 ; pause 100ms
next b0
;goto main ; loop back to main

for b0=255 to 5 step -5 ; b0 is the period
w1=b0*2 ;calculate the DUTY = period x2=50%
pwmout pwmdiv64,B.3,b0,w1
pause 1000 ; pause 100ms
next b0
pause 1000
goto main ; loop back to main
 

AllyCat

Senior Member
Hi,
.... it says in the online manual for to use pwmduty command to change duty...???
Yes, but when you are ONLY changing the Duty Cycle. It's to avoid "updating" the period register when it's not required to change. However, there are indications that the modern chips' (hardware) sychronise the updating of the period register to the end of a full cycle anyway.
Regards the registers.... I cannot get anywhere with them peeking or poking. Is the 18M2+ a PIC16F1847......I downloaded the datasheet and it tells me the PR2 register is the Timer2 pwm Period and its address is 01Bh so in a fornext loop I pokesfr $1B, xxx etc various values and I cannot see anything happen. Am I reading the correct datasheet and addresses....????
I think the statement about the PWMOUT command in the User Manual (and online) that:
"* On older PICAXE parts the same internal timer (timer2) is used for both
pwmout and servo, so these commands cannot be used at the same time.
However some newer parts have additional dedicated internal timers that allow
pwmout and servo to work together. This applies to these pwmout channels:
14M2 B.2, B.4 (C.0, C.2 share the servo timer)
18M2 B.3, B.6"

means that those 18M2 PWM outputs do NOT use Timer 2 (because the Servo pulses do).

Also, I'm fairly sure that the PIC's Timer 4 and Timer 6 (PR4 and PR6) are NOT used for the PWM Outputs. It's the Capture and Compare (CCP) Registers that are used for PWM (see section 24 in the PIC data sheet), probably CCP1 and CCP2 because their chip hardware appears to be connected to pins B.3 and B.6 .
setfreq m16
pause 1000 ; pause 100ms
That should create a Pause of 250 ms (i.e. 1000 * 4 / 16) and then there will be a few more ms of delay in each loop caused by the PICaxe's Basic Interpreter.

Cheers, Alan.
 

piclt

Member
Ok, the pause 1000 was me typing.....added an extra 0 for longer pause but didn't update the test info..??
Thanks for the info, all good info, but picaxe must surely use a timer and a comparator and a register to hold the values somewhere....???
Is there any more picaxe techy manuals etc somewhere...???...... and is the 18M2+ a PIC16F1847.....??......with picaxe software mods only or is the hardware different..??
 
Top