Shop OBEX P1 Docs P2 Docs Learn Events
8 PWM ports — Parallax Forums

8 PWM ports

Macgman2000Macgman2000 Posts: 59
edited 2005-04-07 19:14 in General Discussion
Hello, I am new to the SX. I was reading an example file that has 8 simulataneous PWM outputs that are interrupt driven at 1us.
I don't understand how this works. What is happening during the add and what does the rl temp do?

I would appreciate any insight you can give as to how this works.

Best Regards,


add·acc0,duty0··;2·update pwm0
··rl·temp···;1
··add·acc1,duty1··;2·update pwm1
··rl·temp···;1
··add·acc2,duty2··;2·update pwm2
··rl·temp···;1
··add·acc3,duty3··;2·update pwm3
··rl·temp···;1
··add·acc4,duty4··;2·update pwm4
··rl·temp···;1
··add·acc5,duty5··;2·update pwm5
··rl·temp···;1
··add·acc6,duty6··;2·update pwm6
··rl·temp···;1
··add·acc7,duty7··;2·update pwm7
··mov·w,<<temp··;1
··mov·rb,w···;1·output pwm states
··mov·w,#-50···;1·repeat every 1us
··retiw····;3 (32)·interrupt exit

Comments

  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2005-04-06 20:06
    I think I understand this...

    When you add the duty cycle value to the acc eventually you are going to overflow causing the Carry flag to be set.
    Now the rate at which you will overflow depends on the value of your duty cycle for that particular channel.

    rl temp rotates the Carry flag (this is a bit value) one place into the temp byte progressively shifting down (8-times, once for each channel)

    the mov w,<<temp moves the temp BYTE value into the W register, but also because of the << operator rotates the Carry flag into temp
    before the move into the W register.

    the mov rb, w then moves the value in the W register out to the PORTS where you see it as PWM


    A higher value for the duty the more frequent the Carry flag is set.

    suppose values below

    255 - CF set every time PWM is 100%
    127 - CF is set every other time PWM is 50%
    64 - CF is set every fourth time PWM is 25%
    0 - CF never gets set PWM is 0%


    Very clever JonW… I believe that this was code he wrote as an example.


    Hint:
    You could expand this very easily into more than 8-channels by introducing a second
    'temp' variable.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe - Mask Designer III

    National Semiconductor Corporation
    Latest Company News
    (Communication Interface Division)
    500 Pinnacle Court, Suite 525
    Mail Stop GA1
    Norcross,GA 30071

    Post Edited (Beau Schwabe) : 4/6/2005 8:46:20 PM GMT
  • Macgman2000Macgman2000 Posts: 59
    edited 2005-04-06 21:00
    Thanks Beau!

    So when you get a carry bit set...what happens to the data in the·ACC0 register? If you add value 64 four times you have a carry condition bit set.·I don't see where the low part of the cycle comes in if you are always·setting a carry bit.

    Best Regards,
    Nick
    ·
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2005-04-06 21:15
    If there is no carry, the Carry Flag is cleared.
    The data in the Acc register rolls over.... ie.

    Assume that the duty0 is set at 85 (This is not 85%, rather 33.3%)

    1st pass of "add acc0,duty0" acc0 = 85 C=0
    2nd pass of "add acc0,duty0" acc0 = 170 C=0
    3rd pass of "add acc0,duty0" acc0 = 255 C=1
    4th pass of "add acc0,duty0" acc0 = 85 C=0
    5th pass of "add acc0,duty0" acc0 = 170 C=0
    6th pass of "add acc0,duty0" acc0 = 255 C=1

    You see that the pattern for "C" is 1 in 3 or 33.3%

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe - Mask Designer III

    National Semiconductor Corporation
    Latest Company News
    (Communication Interface Division)
    500 Pinnacle Court, Suite 525
    Mail Stop GA1
    Norcross,GA 30071
  • Macgman2000Macgman2000 Posts: 59
    edited 2005-04-06 23:54
    Thanks Beau for clearing that up.

    I·was under the impression that carry needed to be cleared manually.·I guess I am used to clearing the carry before rotating left and didn't see the low cycle side of it.

    Best Regards,
    Nick
    ·
  • PJMontyPJMonty Posts: 983
    edited 2005-04-07 00:02
    Beau,

    Just to be pedantic, the actual sequence when using a value of 85 is this:

    1st pass of "add acc0,duty0" acc0 = 85 C=0
    2nd pass of "add acc0,duty0" acc0 = 170 C=0
    3rd pass of "add acc0,duty0" acc0 = 255 [b]C=0[/b]
    4th pass of "add acc0,duty0" acc0 = 84 [b]C=1[/b]
    5th pass of "add acc0,duty0" acc0 = 169 C=0
    6th pass of "add acc0,duty0" acc0 = 254 C=0
    7th pass of "add acc0,duty0" acc0 = 83 C=1
    



    You only get the carry when your total exceeds 255. There is also no way to generate a 100% signal using this technique. The highest value you can add for an 8 bit counter is 255. If you start with a value of 0 and add 255, you get a total of 255 and no carry. For all the remaining accumulations, the carry will be set, and the total will decrement by one each time until the 255th accumulation which will bring it back to zero, and the cycle repeats. Here's a small taste:

    0 + 255 = 255 C = 0
    255 + 255 = 254 C = 1
    254 + 255 = 253 C = 1
    253 + 255 = 252 C = 1
    


    etc, etc, etc.

    Folks often think of an 8 bit system (with values ranging from 0 to 255) as mapping to the equivalent of 0 to 1, or 0 to 100. However, to get to "1" in binary for "N" bits, you actually need "N+1" bits. The moment the most significant bit is set, you have reached "1". This means that you basically have only half the resolution you think you do. If you have 8 bits, then 0 to 127 maps as 0 to 1, which is the same as having only 7 bits of resolution. If you want 8 bits of resolution, you really need 9 bits. If this seems confusing, consider the same thing in base 10. If you wanted to map the integer range 0 to 10 to equal 0 to 1, you would need 11 digits, not 10. If you only have 10 digits, you can only hold the following values:

    0, 1, 2, 3, 4, 5, 6, 7, 8, 9

    As you can see, if we can only hold 10 digits in base ten, we never actually get to 10.

    Of course, all of this only really applies if you're trying to do integer mathematics, which is precisely what the PWM accumulator is doing.
      Thanks, PeterM
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2005-04-07 02:39
    PeterM,

    Thanks.. I realized after posting and squirmed a bit about correcting my mistake, but decided that what
    I said got the point across.

    ...Right so PeterM is correct... C should be delayed by one pass in accordance to my above posting.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe - Mask Designer III

    National Semiconductor Corporation
    Latest Company News
    (Communication Interface Division)
    500 Pinnacle Court, Suite 525
    Mail Stop GA1
    Norcross,GA 30071
  • PJMontyPJMonty Posts: 983
    edited 2005-04-07 17:39
    Beau,

    You're absolutely right that your post got the point across. I was being pedantic simply so that no one was surprised later. In particular, that fact that there is no way to have the PWM stay high 100% of the time is the sort of thing that would end up as someone telling me that there is a problem with the debugger because, "the PWM output bit goes low sometimes even when I give it a value of 255!"
      Thanks, PeterM
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-04-07 19:14
    Yeah but 99.6% duty cycle aint bad. Though I understand you are heading off potential confusion.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Sign In or Register to comment.