• AVR Freaks

Hot![PIC18F K42] "Slow" PWM - [ANSWERED]

Author
peter.einramhof
Starting Member
  • Total Posts : 17
  • Reward points : 0
  • Joined: 2016/03/21 07:01:15
  • Location: 0
  • Status: offline
2019/06/27 04:50:56 (permalink)
0

[PIC18F K42] "Slow" PWM - [ANSWERED]

[EDIT START]
It's solved.
  • I'm using SMT1 clocked at Fosc/4 in Timer Mode with a period of (508 * 525) - 1
  • SMT1_out is fed into CLC1 (just Gate #0, the other Gates are unused, 4-way AND)
  • CLC1_out is used to trigger TMR4 in Monostable Mode (rising edge of CLC1_out)
  • PWM7 uses TMR4 to produce the desired LOW-pulse
Thanks again to mbrowning and NorthGuy! :-)
[EDIT END]
 
Hi there!
 
After a loooooong abstinence from the 8-bit PIC world, I've decided to give it another try.
I'm using the PIC18F47K42 running @ 16MHz to generate a VGA signal.
  • SPI + DMA output the pixel data
  • TMR2 and PWM5 are generating the horizontal sync signal
  • TMR4 and PWM7 are generating the vertical sync signal
TMR2 is being clocked by Fosc/4 with a prescaler of 4, PR2 is set to 126, so the period is (4 * 127) = 508 instructions cycles.
After each period an interrupt is fired. As part of the interrupt service routine either the DMA is triggered (visible part of the frame) or TMR4 + PWM7 are started (one shot, during the invisible part of the frame).
 
Everything is working fine, but having to deal with TMR4/PWM7 in the interrupt service routine is unnecessary overhead.
It should be possible to have a rather "slow" PWM that is set up once at start-up and running "purely in hardware" after that.
 
One period of this PWM would be (525 * 508) = 266,700 cycles long.
The PWM's HIGH time needs to be (523 * 508) = 265,684 cycles, the LOW time (2 * 508) = 1016 cycles.
When I say "cycles", I'm referring to instruction clock cycles i.e. Fosc/4 (62.5ns)
With a prescaler of 4, these numbers can be reduced a bit, i.e. (525 * 127) = 66,675 (Fosc/16) cycles for the period,
66,421 cycles for the PWM HIGH time, and 254 cycles for the LOW time.
 
I have thought of concatenating two timers, where one timer's overflow output serves as clock input to the second timer.
But this second timer needs to be a 16-bit timer (1 period = 525 clocks), have a settable period, and be PWM-capable.
As far as I know, the 16-bit timers TMR1/3/5 are neither PWM-capable nor do they have a period register.
I suppose "crazy" constructions such as using TMR1 together with CCP1 (toggle output) and CCP2 (toggle output and reset TMR1) and fusing the CCPx outputs via CLC to produce a PWM are possible, but this seems quite cockamamie.
 
Is there a simple, elegant solution which I have missed?
 
Cheers,
Peter.
 
post edited by peter.einramhof - 2019/06/28 16:20:26
#1

4 Replies Related Threads

    mbrowning
    Just a Member
    • Total Posts : 1424
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: [PIC18F K42] "Slow" PWM 2019/06/27 07:19:40 (permalink)
    +1 (1)
    I used the SMT with two CLCs and one even timer to generate a similar signal (1PPS). In my case, I setup SMT in counter mode and clocked from 16MHz internal clock (through CLC1), set SMT1PR for 16,000,000 divide. SMT outputs a brief pulse at rollover, which is applied to T6ers through CLC3. T6 is used to stretch the pulse - so essentially SMT rollover sets the period and T6 rollover sets the pulse width.
     
    You could probable adapt this for your timing:

     
     
     
        CLC1SEL0    = 0x05;            // HFINTOSC (16MHz)
        CLC1SEL1 = CLC1SEL2 = CLC1SEL3 = 0x06;    // LFINTOSC
        CLC1GLS0    = 0x02;            // CLC1SEL0 (CLCIN0) gated to CLC1 Gate 0
        CLC1GLS1 = CLC1GLS2 = CLC1GLS3 = 0x00;    // unused gates output 0
        CLC1POL        = 0x0e;            // invert unused gates to output 1
        CLC1CON        = 0x82;            // enable 4-input AND

    // initialize SMT
        SMT1CON0    = 0x80;            // enable SMT
        SMT1PR        = 15999999UL;    // set period register div by 16,000,000
        SMT1CLK        = 0x01;
        SMT1SIG        = 0x16;            // input is CLC1
        SMT1CON1    = 0x48;            // repeat = 1, mode = counter
        SMT1CON1    = 0xc8;            // GO = 1

    // initialize CLC3
        CLC3SEL3    = 0x13;            // SMT1_out
        CLC3GLS3    = 0x80;            // lcxg4 = SMT1 (S = SMT1_out)
        CLC3GLS2    = 0x00;            // lcxg3 = 0 (R = 0)
        CLC3GLS1    = 0x00;            // lcxg2 = 0 (D = 0)
        CLC3SEL0    = 0x12;            // TMR6_out
        CLC3GLS0    = 0x02;            // lcxg1 = T6 (CLK = T6)
        CLC3POL        = 0x00;            // no inversions
        CLC3CON        = 0x94;            // D-FF with S & R

    // initialize T6
        T6CLKCON    = 0x03;                // HFINTOSC (16MHz)
        T6RST        = 0x13;                // ers = CLC3
        T6PR        = 249;                // div by 250
        T6HLT        = 0x01;                // Hardware gate, active-high
        T6CON        = 0xff;                // pre by 128, post by 16, tmr6 on

        PIR1bits.SMT1PRAIF    = 0;
        PIR1bits.SMT1IF        = 0;

     
     edit - I used SMT counter mode because it uses the SMT1SIG input which has an external (pin) input. My final design used a 10MHz external oscillator (with 10,000,000 divide) and I wanted to get everything working without major changes (just changed the SIG input to CLC_out and changed the PR setting).
     
    You could use timer mode, and set clock input for Fosc/4 direct input, not needed the convoluted CLC method I used.
    So you would need SMT, one CLC, and one even timer
    post edited by mbrowning - 2019/06/27 07:48:52

    Oh well - there's always next year
    #2
    peter.einramhof
    Starting Member
    • Total Posts : 17
    • Reward points : 0
    • Joined: 2016/03/21 07:01:15
    • Location: 0
    • Status: offline
    Re: [PIC18F K42] "Slow" PWM 2019/06/27 07:25:06 (permalink)
    0
    Hi!
     
    Thanks for the hint!
    I'll try it out. :-)
     
    Cheers,
    Peter.
     
    #3
    NorthGuy
    Super Member
    • Total Posts : 5495
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: [PIC18F K42] "Slow" PWM 2019/06/27 15:21:10 (permalink)
    +1 (1)
    I think CCP can pulse the output. Then you can use a CLC as an SR latch which sets on TMR1 overflow and resets on CCP output.
    #4
    peter.einramhof
    Starting Member
    • Total Posts : 17
    • Reward points : 0
    • Joined: 2016/03/21 07:01:15
    • Location: 0
    • Status: offline
    Re: [PIC18F K42] "Slow" PWM 2019/06/27 22:20:24 (permalink)
    0
    Thanks NorthGuy!

    That's very close to what I came up with, but a bit more "logical". ;-)

    What would allow for the most elegant solution is if the SMT supported a compare mode using one of its two capture registers i.e. set (clear) an output on a match and clear (set) it on a period match plus reset the SMT.

    Cheers,
    Peter.
    #5
    Jump to:
    © 2019 APG vNext Commercial Version 4.5