Shop OBEX P1 Docs P2 Docs Learn Events
PWM module — Parallax Forums

PWM module

ValioValio Posts: 29
edited 2009-06-14 19:55 in General Discussion
Hi all!


I need PWM function (1-phase) in my controller with precious timing (quartz-stabilized as SX do), but SX28 have very small (8-bit) counter for that purpose. Have no idea how to implement exact timing ticks with code (maybe someone could share idea).


But the documentation mention two 16-bit PWM build-ins on SX42/52, and there are no any practice example with brief explanations nor for hardware timing mode neither for software timing mode . How to trigger output by hardware and method to trigger by code ?

The R1 и К2 can be accessed through mode registers, as I discovered, and RB.6 & RC.2 are outputs for T1 и Е2 respectively.

Regards.

Comments

  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-06-07 11:28
    You can create a PWM routine that uses a [noparse][[/noparse]synthesized] 16-bit variable in the ISR; as my friend puts it, "It's a SMOP" (small matter of programming). Perhaps you could be more specific vis-a-vis your PWM requirements (frequency and duty cycle input requirements), that way others can offer more concrete feedback.
  • ValioValio Posts: 29
    edited 2009-06-07 21:32
    I want to make kinda of oscillator for my communication device.

    But it have precious timing requirement. So I need to build square-wave
    CMOS generator that parameters are: n1: count of ticks for "1"
    and n2: count of ticks for "0" logic, so it runs repetitiously,
    nothing more else.

    I have to use LCD display and 4x4 keyboard to input those two parameters
    The value of them are located in range : 50-300 vs 150-3000 ticks
    for logic "1" and "0" respectively. I almost wrote LCD+kb editor,
    but timing of PWM is an actual problem for me. So I need help
    me to preciously count values, stored in 2 doublebyte variables,
    and toggle an output bit. That's all.


    Previously I want to use SX28 due to DIP package, but for SX18-28 arch
    isn't possible provide exact emulation of 16-bits timers, due to running
    on single 8-bit RTCC register.

    Regards.
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-06-08 12:40
    "Precious" is not an engineering unit I'm familiar with (grin) -- what do you need in terms of actually PWM timing? Writing a PWM generator in the ISR with 16-bit variables is not a difficult task.
  • ValioValio Posts: 29
    edited 2009-06-08 14:22
    Im not sure that clearly understood you, but all I need from this module - is exact timing (deep) regulation made on 8-bit registers.

    Besides, I tried to build PWM on SX48, but it failed to simulate:


    
            ORG    $00
    
            mov w,#$ff;
            reti                ;    interrupt exit
    
    ;------------------------ INITIALIZATION ROUTINE -----------------------
    
    Initialize
            mov    fsr,#$20;
            mov    w, #(ticks_hi >> 8);
            mov    duty_hi+1,w
            mov    w, #(ticks_hi & $FF);
            mov    duty_hi+0,w
            mov    w, #(ticks_lo >> 8);
            mov    duty_lo+1,w
            mov    w, #(ticks_lo & $FF);
            mov    duty_lo+0,w
    
            
            mov    W,#$14            ; Write T1/T2  R1CML
            mov    M,W
            mov    !RB, duty_lo;
    
            mov    W,#$15            ; Write T1/T2  R1CMH
            mov    M,W
            mov    !RB, duty_lo+1;
    
            mov    W,#$12            ; Write T1/T2  R2CML
            mov    M,W
            mov    !RB, duty_hi;
    
            mov    W,#$13            ; Write T1/T2  R2CMH
            mov    M,W
            mov    !RB, duty_hi+1;
    
    
            ; Use T1 timing only (RB.6 out)/ (T2 out - RC.2)
            mov    W,#$1F    ;MODE=1Eh to write RB direction
            mov    M,W    ;registers
            mov    W,#$BF    ;W = 1011 1111 
            mov    !RB,W    ;RB.6 - output
    
            ; TTL/CMOS Selected Registers:
            mov    W,#$1D    ;MODE=1Eh to write LVL_B
            mov    M,W    ;
            mov    W,#$BF    ;W = 1011 1111/0-CMOS|1-TTL
            mov    !RB,W    ;RB.6 - output
    
            mov    W,#$1E ;MODE=1Eh to write port pullup
            mov    M, W ;registers
            mov    W,#$40 ;W = 0100 0000
            mov    !RB,W ;enable pullups for RA.6 ?????
    
            ; Schmitt Trigger Select:
            mov    W,#$1C    ;MODE=1Ch to write ST_B
            mov    M,W    ;
            mov    W,#$FF    ; 1-Disable
            mov    !RB,W    ; all disable
    
    
            mov    !rb,#%10111111        ;make rb.6 as output
            mov    !option,#%0100000       ;disable rtcc interrupt
            ;    setb !option.6
    
            ; Timer T1 Control A Register : $17 - Write T1CNTA (Mov !RB,W)
            mov    W,#$17
            mov    M,W
            mov    !RB, #%00000100; T1CMIE: T1 Comp intr R1/R2 enble
    
            ; Timer T1 Control B Register : $16 - Write T1CNTB (mov !RB,W)
            mov    W,#$16
            mov    M,W
            mov    !RB, #%00000001    ; 1:1 Prescaler, 01=PWM mode
            ; Timer T1 Control B Register (T1CNTB)    
    
    ;---------------------------- MAIN PROGRAM -----------------------------
    
    Main
    
    :loop        ;
            jmp    :loop
    
    
    



    What is wrong with code ?
  • JonnyMacJonnyMac Posts: 9,213
    edited 2009-06-09 02:22
    You said you wanted to have pin off for some amount of time and then on for some amount of time. What the timing resolution for these units?
  • ValioValio Posts: 29
    edited 2009-06-09 20:37
    Maybe support team would like to help me ? Simple question - how to use internal PWM future on SX48/52 ?



    JonnyMac, as I wrote - 50-300 ticks for log. "1" ( with 75Mhz quartz) and 150-3000 ticks for logic "0".


    HOW I CAN CONTACT SUPPORT TEAM ? NO RESPONSE AT ALL FOR ANY QUESTIONS.
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-06-09 22:57
    What do you want to know about using the SX48 TIMERS to generate PWM? There are two 16 bit timers available. I've used them on a couple projects with SX/B and they worked out well. If you only need a couple the built-in hardware ones are nice since the Interrupt routine and other code is completely free to do other things. Once you set the on/off times for the timers they just run and will toggle the state of their assigned pin. One thing you may need to do is mask their interrupt if you don't want them. I was using an ISR based serial routine and since I didn't care about the Timer interrupts I just masked them off. Otherwise the extra interrupts messed up receiving serial data.

    Depending on your needs you can simulate PWN on any number of pins by using your own Interrupt routine to keep track of the counts. The nice thing about this route is that you can use any pin instead of the couple pins dedicated to the hardware timers.

    The help file for SX/B has some information about the timers and there is a great deal more in the SX48 datasheet and another great source is Programming the SX Microcontroller by Gunther Daubach.

    For the timer do you know the duty cycle and frequency you are tring to get? Not just ticks, but on for a number of ms and off for a number of ms?

    Robert
  • ValioValio Posts: 29
    edited 2009-06-10 10:42
    I carefully read the SX48/52 manual and wrote a demo code according
    to manual (I listed it in my prev. post), but it doesnt work.

    If it not a problem, can you show a demo code or explain me
    why my is not working.

    Thanks a lot.
  • Shawn LoweShawn Lowe Posts: 635
    edited 2009-06-10 11:00
    Valio-
    I have been following this thread, and while I can't help you do to my inexperience with the SX, I'm trying to learn.

    What is a "tick"? Is it a clock cycle? And you want to run this SX chip at 75 Mhz? 50 clock cycles @ 75 Mhz is .66 microseconds or 1.5 Mhz. So, do you want a PWM routine that runs at 1.5 Mhz (Maximum)?

    I am sorry if I am confusing this situation (and thread) more, but as I said, I am trying to learn.

    Thanks

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Shawn Lowe


    When all else fails.....procrastinate!
  • BeanBean Posts: 8,129
    edited 2009-06-10 11:28
    It mostly depends on what PWM resolution you need.

    If you need 8 bits, then that is 256 levels, so you would want so setup the timers so that the on-time plus off-time always equal 256.

    So for 50% PWM, the on-time and off-time would be 128.

    The PWM rate will be the clock frequency / 256 (assuming no prescaler). So for 75 MHz that would be about 293 KHz (pretty snappy).

    You must be careful when you are changing the on-time and off-time. Because if you set the value lower, and the timer is already past the new value...The output will not toggle until the timer counts the WHOLE way to 65535 and wraps around to the new value.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • ValioValio Posts: 29
    edited 2009-06-10 13:52
    Gentlemen,

    I numerously explained what I need - precious, high-stability
    digital generator of impulses with variable width.

    Is there anyone who can help me and share working demo code that
    show how to program PWM mode of 16-bit registers of SX48/52 chip ?

    Documentation doesnt have any demo on 16-bit PWM,
    just short explanation and registors description.
    I tried to make code according but it doesnt work.

    Bean, maybe you can forward my request to Ubicom developer team ?

    Thanks.

    Post Edited (Valio) : 6/10/2009 2:00:14 PM GMT
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-06-10 15:34
    Hello,

    You've explained a PORTION of what you want to do at a high level but there are still questions that you need to answer in order for people to be more helpful. Even though you feel you have given all the required information there some pieces missing. I asked the question below but didn't see a response:

    [noparse][[/noparse]quote]For the timer do you know the duty cycle and frequency you are tring to get? Not just ticks, but on for a number of ms and off for a number of ms?

    There is a LOT of talented people on these forums and a lot are willing to help. When they ask for information that may not seem important there is often a reason for it even if it may not be immediately clear why that question was asked.

    Some other details that would be useful to know:

    - What language are you going to write your program? Is it going to all be done in assembly? In SX/B? Or in SX/B with some assembly code mixed in?

    - Specifically what is the frequency range you are trying to obtain (lowest to highest). Not specified in ticks but in a frequency or cycles per second.

    - What resolution do you need to achieve between the low and high range?

    - Do you have a graph that shows the actual timing waveforms that you want?
  • ValioValio Posts: 29
    edited 2009-06-10 20:53
    Hello RobotWorkshop!

    I totally cant understand why you insist on ms amount, as far easy operate with clock cycle.

    But let me mention again - I dont need fixed parameters, i wanna change them manually
    with keyb+LCD as it would per need.

    Thanks
    709 x 218 - 4K
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-06-10 21:31
    I wasn't insisting on a ms amount but mentioned since that is more useful than the ticks you had previously mentioned. The questions in my last post about the language you want to use, the frequency range, and the resolution are probably more important. Several of us have asked about the resolution without an answer....

    I've use the timers to drive PWM for controlling a motor and on another project used them to simulate pulses to drive a pair of servos. Having the details about the frequency range and resolution will help determine what clock speed you may want to run the chip and also what values to use for the pre-scaler.

    Some example code fragments (for SX/B) that can be used in an SX48 (I was running at 20Mhz)

    MotRht VAR RB.6 ' Right Motor speed/direction (PWM)
    MotLft VAR RC.2 ' Left Motor speed/directiom (PWM)

    dutyCycle VAR Word ' Should be 18Khz @ 20Mhz clock

    dutyCycle = 49995 ' Overall cycle should be about 50 Hz
    TIMER1 PRESCALE, 3
    TIMER2 PRESCALE, 3

    Then to set the timer and make it run use:

    TIMER1 PWM, 2500, dutyCycle ' Turn motor on

    TIMER1 PWM, 3800, dutyCycle '3750 = 150 (Servo not turning)

    TIMER1 PWM, 5000, dutyCycle 'Turn motor on other direction

    Depending upon your requirements you may have to reset the prescale value as well as the values of the timer itself to get longer or shorter cycles.


    On another application I didn't want the Interrupts generated from Timer one and added some startup code to mask them off:

    ' The following code should disable Interrupts generated by TIMER1
    ASM
    BANK mtrStruct ' Make sure we can access timWrk
    MOV W,#$07 ' Command to read T1CNTA
    MOV M,W
    MOV !RB,W
    AND W,#$DA ' Clear bits 5, 2, and 0
    MOV timWrk,W
    MOV W,#$17 ' Command to write T1CNTA
    MOV M,W
    MOV W,timWrk
    MOV !RB,W
    BANK 0 ' Restore access to BANK 0
    ENDASM

    You could also do this for timer2 if needed

    to turn off the timer you can use:

    TIMER1 TIMER

    You should probably try this all in SX/B first then move it all to assembly if you need to later. With SX/B it is very easy to experiment with the timers.
  • ValioValio Posts: 29
    edited 2009-06-10 22:42
    Sorry, I forgot to mention about language - as you can see from above, i use to write program assembler, o high lvl language like SX/B with asm inline.

    I checked your code - but unfortunately it doesnt work (at least at simulator), I cant catch any interrupts from T1/R1-R2 as far they was allowed. Meanwhile, in your code you are working with 16 bit registers, not 8 bit. I cant see where you load comparison registers R1 and R2 of T1 timer. I need that interrupt occurred when T1 will zeroed and reloaded again as manual says.

    Maybe Bean is able to give me right answer ?


    Thanks anyway.
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-06-11 00:00
    Valio said...
    Sorry, I forgot to mention about language - as you can see from above, i use to write program assembler, o high lvl language like SX/B with asm inline.

    I checked your code - but unfortunately it doesnt work (at least at simulator), I cant catch any interrupts from T1/R1-R2 as far they was allowed. Meanwhile, in your code you are working with 16 bit registers, not 8 bit. I cant see where you load comparison registers R1 and R2 of T1 timer. I need that interrupt occurred when T1 will zeroed and reloaded again as manual says.
    Have you tried any of your examples on real hardware or is all this being done in a simulator?· Why do you need interrupts?· All that was mentioned was that you wanted to change the state of an output pin via the timer.· If the timer is generating the signal there are many cases where you don't need or want Interrupts generated.· My example is done with an SX48 (which uses 16-bit values) since that is what I used myself and that is specifically one of the things you originally inquired about.· The SX28 has a single 8-bit timer and the SX48 has two 16-bit timers.

    When using SX/B the simple commands shown will set all the registers for you.· Once set it will start running and continue to run until you load a new value in it.· You don't need to reload the values after each cycle.· If so that would sort of defeat the whole purpose of a hardware timer to offload the work don't you think?· They are pretty much fire and forget.· No Interrupts required.· The SX/B help file explains the timer commands I used.

    You set the prescale for and the duty cycle for the frequency you want.· The other value that I specified with the duty cycle in the example I provided sets the relationship to on time vs off time.· I have a small robot that I built with my son using the timers with some of the above code and I can assure you it does work.· I never tried it in a simulator but then I often don't bother with that and prefer to load the code on real hardware for testing.

    Honestly there is much more than one right answer to just about any programming problem.· It is all in the way you look at it and the approach you take.· You should be able to use the timers or just roll your own via software in an ISR.· Either way there are hundreds of different ways to code the program to accomplish the task at hand.· What is right for one person may seem silly to another who takes a different approach.· Use whatever works for you and what you are most confortable with.

    Good luck.
    ·
  • Shawn LoweShawn Lowe Posts: 635
    edited 2009-06-11 00:33
    Vailo:

    Did you see this thread?

    http://forums.parallax.com/forums/default.aspx?f=7&m=356137

    There is a program written by Jonnymac that might do what you want (after adjusting speed, ect.)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Shawn Lowe


    When all else fails.....procrastinate!
  • ValioValio Posts: 29
    edited 2009-06-14 19:55
    Ok, thanks.

    I understand two things:

    1) Simulator do not support neither PWM timers nor their generated interrupts. Its bad.

    2) its very hard emulate work of 16-bit pair registers with single 8-bit timer of SX28.

    PS: I do not yet received my SX-Key from abroad. I post a message to Parallax sales team
    to help with sale order payment - but they ignore me - LOL )
    Because I can use only simulator to prepare it for chip programming when it will be possible.
Sign In or Register to comment.