Shop OBEX P1 Docs P2 Docs Learn Events
SX48 Questions (PWM with internal timer) — Parallax Forums

SX48 Questions (PWM with internal timer)

bennettdanbennettdan Posts: 614
edited 2007-06-13 03:09 in General Discussion
Hello,
·· I am new to the SX line of chips but very interested in using them in a couple of new projects.
··
· The SX48 proto board running at 50mhz is what I am looking at. I want to use this for PWM control of a solenoid at about 17-18 khz, the question is can I use the onboard timer for PWM and still be able to process some sensors and other input signals?

Also would the SX/B compiler able to use the internal timer or do I have to start learning assembly?

Thanks for any help..

Post Edited By Moderator (Bean (Hitt Consulting)) : 5/23/2007 11:47:50 AM GMT

Comments

  • JonnyMacJonnyMac Posts: 8,943
    edited 2007-05-23 05:41
    SX/B provides simplified access to the timer(s) on the SX48 and may help you; when you download the SX-Key IDE SX/B is included -- check the help file (an update was just posted in this forum) for details.
  • BeanBean Posts: 8,129
    edited 2007-05-23 11:43
    Bennettdan,
    · You can use SX/B. Look up the TIMER command in the help file.
    · Basically you will use "TIMER1 PWM, value, 2778" value can be from 0 to 2777.
    · 2778 = 50MHz / 18KHz.
    · Remember that timer1 uses pin RB.6 for output and timer2 uses pin RC.2 for output.
    · Also remember to make the pin an output.

    · Once you issue the TIMER1 PWM command you don't have to do anything else. The SX48 will continue to generate the PWM, you can read sensors all day long.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • bennettdanbennettdan Posts: 614
    edited 2007-05-23 15:36
    Bean,
    Thanks for the tip is that able to be done with SX/B or do I have to use assembly?
  • BeanBean Posts: 8,129
    edited 2007-05-23 16:04
    Can easily be done in SX/B.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • bennettdanbennettdan Posts: 614
    edited 2007-05-23 16:29
    Thanks again Bean I think the SX will be great for my project.
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2007-05-28 02:47
    There does seem to be one thing to watch out for when trying to use the TIMER to do PWM that can drive you crazy. I had looked at the HELP file for the correct syntax. I went by the main structure of the command itself and tried something like:

    TIMER1 PWM Spd, Duty

    The help file should probably be updated to show the comma right after the PWM since none of the other commands like the prescaler seem to need it and one might expect that the PWM isn't supposed to have it either! If you leave that comma out it will happily compile your program without errors but you'll never get what you expect out of your program.

    I just read this post and noticed that there should be a comma after PWM like:

    TIMER1 PWM,Spd, Duty

    Adding the comma just fixed a problem that I was chasing down on and off all day. I missed the actual example and would have caught it sooner if the compiler had flagged it as an error. I kept overlooking the same thing. Now it works great!

    I hope this note saves someone else some time.

    Robert
  • bennettdanbennettdan Posts: 614
    edited 2007-05-28 04:02
    Robert,
    Thanks for the tip I will be learing the SX/B very soon ...
  • BeanBean Posts: 8,129
    edited 2007-05-28 12:37
    Robert,
    I'll make sure the next release catches the missing comma. Thanks for posting your experience.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2007-05-28 15:26
    There is one other question I have about the TIMERs and their use of the output ports. I haven't seen it specifically mentioned but it implies that whenever the timer is actually active that it drives the output pins itself according to what TIMER mode it is using at the time. I suppose a note for the TIMERx CLEAR should also be added that once it occurs that pins that the TIMER was using revert back to the normal control of the user program.

    Robert
  • bennettdanbennettdan Posts: 614
    edited 2007-06-09 03:29
    Bean,
    What if I want to run lower frequencys like say 292hz would I use the timer like this?
    TIMER1 PWM, value, 170941 where value = 0 to 170941 or do I have scale this value somehow?
  • BeanBean Posts: 8,129
    edited 2007-06-09 11:52
    The values must be 65535 or less. If you require a larger value, then you need to use the prescaler option too.
    For your values you would have to use a prescale of 1:4 and use 42735 for 170941.

    TIMER1 PRESCALE, 2 ' 2 = 1:4 prescaler
    TIMER1 PWM, value, 42735 ' Value = 0 to 42735

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • bennettdanbennettdan Posts: 614
    edited 2007-06-09 13:02
    Bean,
    Thats what I though but the Help file in SX/B was not very clear about using the prescaler.
    Thanks again.
    One more question though I have a need for three PWM outputs and their is only two Timers would a ISR be better for the third PWM and how would you setup for a 0-100% duty say with a 32hz pulse?
  • BeanBean Posts: 8,129
    edited 2007-06-09 14:22
    Assuming you only need 8-bits (256 levels) of PWM you would setup the interrupt with a rate of 8192 (32 * 256).

    PwmPin PIN RA.0 OUTPUT ' Change to whatever SX pin you want but make sure you have OUTPUT
    
    pwmCnt   VAR BYTE
    pwmValue VAR BYTE ' Set this variable to whatever PWM duty cycle you want
    
    INTERRUPT 8192
      INC pwmCnt
      IF pwmCnt > pwmValue THEN
        pwmPin = 0
      ELSE
        pwmPin = 1
      ENDIF
    RETURNINT
    
    



    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • bennettdanbennettdan Posts: 614
    edited 2007-06-09 16:04
    Bean,
    The pwmValue is set between 0-8192 right?
    Thanks again so If I wanted to have say 10bits I could use and interrupt of 1024*32 =32768 then set the value 0-32768?
  • BeanBean Posts: 8,129
    edited 2007-06-09 16:19
    No, from 0 to 255.

    For 10 bits the value would be 0 to 1023 (you will have to use WORD variables, and modify the code·too).

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • bennettdanbennettdan Posts: 614
    edited 2007-06-09 17:40
    I see what you mean about the 0-255 and 0- 1023 thanks for the help I will set it up and if the base Frequency is a little off on the scope I can scale it up and down with the 8192 value to be right on?
  • bennettdanbennettdan Posts: 614
    edited 2007-06-12 02:57
    Bean,
    What if I want to run a couple of PWM channels with different frequencys can I use mutiple ISRs? Also will I still be able to use the serin and serout commands?
  • JonnyMacJonnyMac Posts: 8,943
    edited 2007-06-12 03:39
    You'll need to determine the lowest common denominator -- timing-wise -- run your ISR at that and then divide it up for your various VPs. Here's a butt-simple example:

    ' =========================================================================
      INTERRUPT 1_000
    ' =========================================================================
    
      INC led1Timer
      IF led1Timer = 100 THEN
        TOGGLE Led1
        led1Timer = 0
      ENDIF
    
      INC led2Timer
      IF led2Timer = 133 THEN
        TOGGLE Led2
        led2Timer = 0
      ENDIF
    
      IF led3Timer = 221 THEN
        TOGGLE Led3
        led3Timer = 0
      ENDIF
    
      RETURNINT
    



    The ISR runs every millisecond; LED #1 gets toggled every 100 ms, LED #2 gets toggled every 133 ms, and LED #3 gets toggled every 221 ms. The example is not really practical, but demonstrates that for each of your VPs you may need to keep track of separate dividers.
  • bennettdanbennettdan Posts: 614
    edited 2007-06-12 22:07
    Could I do something like this? 32hz, 61hz, and 292hz

    INTERRUPT 74752
    INC pwmCnt32hz
    If pwmCnt32hz = 8192 THEN
    pwmCnt32hz = 0
    ELSE pwmCnt32hz > pwmValue32hz THEN
    32hzpwmPin = 0
    ELSE
    32hzpwmPin = 1
    ENDIF
    INC pwmCnt61hz
    IF pwmCnt61hz = 15616 THEN
    pwmCnt61hz = 0
    ELSE pwCnt61hz > pwmValue61hz THEN
    61hzpwmPin =0
    ELSE
    61hzpwmPin = 1
    ENDIF
    INC pwmCnt292hz
    IF pwmCnt292hz = 74752 THEN
    pwmCnt292hz = 0
    ELSE pwCnt292hz > pwmValue292hz THEN
    292hzpwmPin =0
    ELSE
    292hzpwmPin = 1
    ENDIF
    RETURNINT
  • BeanBean Posts: 8,129
    edited 2007-06-12 22:18
    · Well you cannot start a variable (or pin) name with a digit.

    · And you need to adjust your values, for higher Hz rates you need LOWER reset values.
    32 Hz would be 2336 (not 8192), 61 hz would be 1225 (not 15616) and 292 Hz would be 256 (not 74752).
    Just take 74752 / hz to get the reset value.


    · And you won't be able to use the SERIN or SEROUT command with an interrupt.j

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    “The United States is a nation of laws -· poorly written and randomly enforced.” - Frank Zappa

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • bennettdanbennettdan Posts: 614
    edited 2007-06-12 23:05
    Bean,
    Thanks again as usual I see what you mean about the resets so I was not to far out in left field just went backwards with my timming.

    Thanks for the tip about the variable not starting with a digit.

    Am I correct about the interrupt running at the 74752 (256*292)?

    Thanks Jonny for your help also you got me started in the right direction.

    Post Edited (bennettdan) : 6/12/2007 11:13:32 PM GMT
  • bennettdanbennettdan Posts: 614
    edited 2007-06-13 02:06
    Bean,
    You said I cant use serout and serin commands what about using shiftout and shiftin to read from a ADC chip?

    Also do you know of any examples on how to setup a serial link to a PC and still using the ISR?

    Thanks again
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2007-06-13 02:36
    You do have to be careful using the built-in SX/B SERIN and SEROUT commands in conjunctions with interrupts because asynchronous serial communication is a very time dependant process. However, SHIFTIN and SHIFTOUT are synchronous communications commands that communicate relative to a shared clock signal. This to a very large degree allows the clock rate to run fast or slow without affecting the integrity of the data sent. (Of course there are limitations.) You should be fine using SHIFTIN and SHIFTOUT with running interrupts.

    There are many examples of using interrupts for serial communications in the forums. I found many helpful answers in response to my post about Adding a Background UART to SX/B.

    You can Cut-and-Paste UART code from several posted examples. Be sure to call the UART code in your ISR with the right timing for your selected baud rate.

    - Sparks
  • bennettdanbennettdan Posts: 614
    edited 2007-06-13 03:09
    Thanks for the links Sparks.
Sign In or Register to comment.