18F4431 Quaduature Encoder


Closed Thread
Results 1 to 29 of 29

Hybrid View

  1. #1
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Using the PCPWM

    HI All,
    This explanation has been the best one that I have found concerning the use of the PCPWM. That said, there still seems to be a bit of mystery surrounding it's use, at least to me. I mapped out the formulas in Excel, but I am still having trouble getting my head around the details. I'm trying to make a generic H-bridge for low frequencies and keep running into the wall. An 18F1330 with two pots, a switch, and the FETs with drivers. One Pot is for Frequency, the other is for Duty. The switch controls if the output is pulsed DC or cycles both ways. I'm not understanding the interaction of the frequency to the Duty. I can control the Freq just fine, but it makes a mess of the duty. Currently, the application needs it to run from 3 Hz to 100Hz with control from low power to high power (~5%-95% duty). I can see that there is a dependency with the PWM resolution, but I'm not sure how to manage it. I can get the PTPER values within 0-4096, but the resolution gets out of range. I'm thinking I need to find some way to scale the Duty to the PTPER values, and adjust accordingly, but I haven't managed to make it click. Any suggestions?
    Code:
    '****************************************************************
    '*  Name    : PCPWM_1330_H-bridge84.BAS                         *
    '*  Author  : Mark Rokus                                        *
    '*  Notice  : Copyright (c) 2012 Controlled Surroundings Inc.   *
    '*          : All Rights Reserved                               *
    '*  Date    : 6/9/2012                                          *
    '*  Version : 1.0                                               *
    '*  Notes   : 18F1330 to drive H bridge:                        *
    '*          : (2)L6378 drivers to (4) FDP22N50N N-FETs          *
    '* used PCPWM_1330_H-bridge5 to test Hardware on separate FETS
    '* New rewrite using ints
    '* moved switch to RB3, rewire drivers complementary
    '* NOTE: Int not working, Not going into AC
    '*          Freq and Duty not correct
    '****************************************************************
    '                            18F1330                                                             
    '              ---------------------u----------------------
    '    Freq    -1|RA0/AN0/INT0                  RB3/INT3/CMP1|18-   Switch      
    '    Duty    -2|RA1/AN1/INT1                  RB2/INT2/CMP2|17-   Pad      
    '    Pad     -3|RA4/TOCKI/AN2                 RA7/OSC1/CLKI|16-   Pad     
    '    Vpp     -4|RA5/MCLR/vpp              RA6/OSC2/CLKO/AN3|15-   Pad           
    '    Gnd     -5|-- VSS                                VDD++|14-   5 vdc         
    '    Tx      -6|RA2/TX/CK                      RB7/PGD/PWM5|13-    PGD      
    '    Rx      -7|RA3/RX/DT                      RB6/PGC/PWM4|12-    PGC      
    '   Pad      -8|RB0/PWM0                           RB5/PWM3|11-   Q1/Q4 PWM      
    '   Pad      -9|RB1/PWM1                           RB4/PWM2|10-   Q2/Q3 PWM        
    '              |___________________________________________|
    
    #CONFIG
        CONFIG OSC = INTIO2        ;Internal oscillator, port function on RA6 and RA7
    #ENDCONFIG
    DEFINE OSC 4                  ' Actually @ 2MHz 
    OSCCON  = %11011100         ' INTOSC primary, 2MHz
    '****** Hardware Serial Setup ***************
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 8   ' 57600 Baud @ 2MHz, -3.55%
    SPBRGH = 0
    BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    '***************************************
    TRISA   = %00000011          ' PortA : outputs except RA.0/RA.1= AN
    TRISB   = %00001000          ' all outputs ex: RB.3 switch i/p  
    INTCON    = 0                      ' 
    INTCON2 = 0                     
    CMCON   = 0                      ' Comparators off
    clear
    '**** Analog setup   ****
        ADCON1 = %00001100   ' AN0,AN1 Analog: VDD ref. RA4 & RA6 DIO
        ADCON2 = %10010001   ' Right justified, 8 Tad, Fosc/8
    '***** PWM Setup ? ********************
        PTCON0 = %00001110      ' 1:1 post, Fosc/256 (1:64) pre, UpDown(...00 free)
        PTCON1 = %11000000      ' PWM Time Base timer on, Count Down      
        PWMCON0 = %00110111     ' 0-3 PWM,  complementary
        PWMCON1 = 1             ' 1:1 postscale, updates enabled, overrides sync 
        DTCON = 0               ' zero dead-time  
        PTCON1 = %10000000      ' PWM time base is ON, counts up
        FLTCONFIG = 0           ' disable fault A 
        OVDCONS      =    %00000000    ' 
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        '   Variable definition
    ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
    PORTB = 0                   ' clear port latch
    Fraw         var    word          ' Raw reading for Frequency
    Freq         var    word        ' Frequency of PWM
    Draw         var    word        ' Raw reading for Duty
    Duty         Var    Word        ' Duty of PWM
    Sw             var    PORTB.3        ' switch input for AC or Positive only
    '************************************************
    Start:
        hserout  ["1330_H-bridge83",13,10]
        pause 500    
    '*************************************
    PosOnly: 
        If sw = 0 then ac            ' mode check                
      ADCON0 = %00000011            ' Start conversion on AN0
        WHILE ADCON0.1=1             ' Wait for it to complete 
        WEND   
         Fraw.HighByte = ADRESH     ' get result from AN0
         Fraw.LowByte = ADRESL      '     
      ADCON0 = %00000111            ' Start conversion on AN1
        WHILE ADCON0.1=1             ' Wait for it to complete 
        WEND    
         Draw.HighByte = ADRESH     ' get result from AN1
         Draw.LowByte = ADRESL      '      
         Freq = (Fraw) max 3        ' 
         Duty = (Draw*3) max 1        '   
             PTPERH = Freq.highbyte 'load timer: Freq low byte
             PTPERL = Freq.lowbyte     ' Freq low byte
               PDC1H = Duty.HighByte  ' PWM duty on Out1
             PDC1L = Duty.LowByte
              OVDCOND = %00001000         ' enable PWM3 OUT1 (Q1/Q4 on RB5)           
            hserout ["Duty ",dec duty," PosFreq ",dec Freq]
            goto PosOnly                ' Loop 
    '***************************************************************************
    AC:        ' sequence for generating Alternating pulses     
    PosAlt:                                'drive Positive pulse on bridge      
            If sw = 1 then posonly    ' mode check
            PIR3.4 = 0               ' reset PWM Int flag
              while PIR3.4 = 0
             OVDCOND = %00001000       ' enable PWM3 OUT1 (Q1/Q4 on RB5)
              ADCON0 = %00000011     ' Start conversion on AN1
             WHILE ADCON0.1=1      ' Wait for it to complete 
             WEND    
             Fraw.HighByte = ADRESH ' get result from AN0
            Fraw.LowByte = ADRESL  '     
            Freq = Fraw max 3           ' 
             PTPERH = Freq.highbyte  'load timer: Freq low byte
              PTPERL = Freq.lowbyte     ' Freq low byte
            wend                       ' one cycle until Int 
    NegAlt:                              ' drive Negative pulse on bridge
            PIR3.4 = 0                ' reset PWM Int flag
              while PIR3.4 = 0
             OVDCOND = %00000100    ' enable PWM1 OUT2 (Q2/Q3 on RB4)               
               ADCON0 = %00000111     ' Start conversion on AN0
             WHILE ADCON0.1=1       ' Wait for it to complete 
             WEND
            Draw.HighByte = ADRESH     ' get result from AN1
             Draw.LowByte = ADRESL      '         
              Duty = (Draw) max 1        ' 
                PDC1H = Duty.HighByte  ' PWM duty on Out1
             PDC1L = Duty.LowByte
             wend                       ' one cycle until Int    
            hserout ["Duty ",dec duty," ACFreq ",dec Freq]
            goto AC                  ' Loop         
    end
    So I guess the question is: Can anyone explain the relationship between PTPER and PDCx in this dynamic environment in a way that I'm not seeing?
    Thanks
    Bo

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: 18F4431 Quaduature Encoder

    Hi,
    Basically, when you change the frequency (which you do when you change the PTPER) you also change the resolution. So, if you set the duty cycle to 50% at one frequency and then change the frequency the actual dutycyle will also change.

    Basically the module is counter and two comparators. When the counter starts at 0 the output is set, when it "hits" the value of the first comparator the outputs is cleared and when the counter "hits" the value of the second compartor the PWM cycle starts over. In this case the value "in" the first comparator is your PDCx (duty)and the value in the second comparator is your PTPER (period) registers.

    If the counter was an 8 bit counter and you had your second comparator (PTPER) set to 255 then there would be 256 "steps" to one PWM period. If you then set the value "in" the first compartor (PDC) to 127 you'll get a 50% dutycycle because the output will be set when the counter starts at 0 and cleared when it reaches 127, the counter will then continue to 255 and start over at which point the output is again set and so on.

    Now, if you change the value of the second comparator (PTPER) to say 180 there's no longer 256 "steps" to one PWM period, the counter will start over when it "hits" 180 instead of 255 - the PWM period is shorter, PWM frequency is higher. So if you keep the value "in" the first comparator (PDC) unchanged (127) the dutycycle will no longer be 50% because the output will be "on" from 0 to 127 and then off from 127 to 180 at which point the cycle starts over.

    The PWM module is more complec than this, as you've noticed, but the above is a basic explanation of the interaction between PWM period and PWM dutycycle.

    /Henrik.

  3. #3
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Re: 18F4431 Quaduature Encoder

    Thanks for the explanation Henrik.
    The more we pound on this and post the results, the better we can get a handle on it.
    That concept started to peek through the fog eventually. The fact that my frequency and duty had to be changeable made it a bit more confusing for me.

    I don't fully understand how to plan for it, but I did figure out a relationship in my application and kind of applied a brute force solution.

    What I ended up with was this:
    Code:
    '* Working:  1.2Hz to 101Hz, .2% - 97% Duty 
    '****************************************************************
    '                            18F1330                                                             
    '              ---------------------u----------------------
    '    Freq    -1|RA0/AN0/INT0                  RB3/INT3/CMP1|18-   Switch      
    '    Duty    -2|RA1/AN1/INT1                  RB2/INT2/CMP2|17-   Pad      
    '    Pad     -3|RA4/TOCKI/AN2                 RA7/OSC1/CLKI|16-   Pad     
    '    Vpp     -4|RA5/MCLR/vpp              RA6/OSC2/CLKO/AN3|15-   Pad           
    '    Gnd     -5|-- VSS                                VDD++|14-   5 vdc         
    '    Tx      -6|RA2/TX/CK                      RB7/PGD/PWM5|13-    PGD      
    '    Rx      -7|RA3/RX/DT                      RB6/PGC/PWM4|12-    PGC      
    '   Pad      -8|RB0/PWM0                           RB5/PWM3|11-   Q1/Q4 PWM      
    '   Pad      -9|RB1/PWM1                           RB4/PWM2|10-   Q2/Q3 PWM        
    '              |___________________________________________|
    
    #CONFIG
        CONFIG OSC = INTIO2        ;Internal oscillator, port function on RA6 and RA7
    #ENDCONFIG
    DEFINE OSC 4                  ' Actually @ 2MHz 
    OSCCON  = %11011100         ' INTOSC primary, 2MHz
    '****** Hardware Serial Setup ***************
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 8   ' 57600 Baud @ 2MHz, -3.55%
    SPBRGH = 0
    BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    '***************************************
    TRISA   = %00000011          ' PortA : outputs except RA.0/RA.1= AN
    TRISB   = %00001000          ' all outputs ex: RB.3 switch i/p  
    INTCON    = 0                      ' 
    INTCON2 = 0                     
    CMCON   = 0                      ' Comparators off
    clear
    '**** Analog setup   ****************************
        ADCON1 = %00001100        ' AN0,AN1 Analog: VDD ref. RA4 & RA6 DIO
        ADCON2 = %10000000       ' Right justified, 0 Tad, Fosc/2
    '***** PWM Setup  *******************************
        PTCON0 = %00001110      ' 1:1 post, Fosc/256 (1:64) pre, UpDown(...00 free)
        PTCON1 = %11000000      ' PWM Time Base timer on, Count Down      
        PWMCON1 = 1             ' 1:1 postscale, updates enabled, overrides sync 
        DTCON = 0               ' zero dead-time  
        PTCON1 = %10000000      ' PWM time base is ON, counts up
        FLTCONFIG = 0           ' disable fault A 
        OVDCONS      =    %00000000    ' 
    '***** Variable definition  **********************
    PORTB = 0                       ' clear port latch
    Fraw         var    word          ' Raw reading for Frequency
    Freq         var    word        ' Frequency of PWM
    Draw         var    word        ' Raw reading for Duty
    Duty         Var    LONG          
    Sw             var    PORTB.3        ' switch input for AC or Positive only
    '************************************************
    Start:
        hserout  ["1330_H-bridge85",13,10]
        pause 500    
    '************************************************
    Main: 
        If sw = 0 then               ' mode check                
           PWMCON0 = %00110111      ' 0-3 PWM,  independant
           OVDCOND = %00001000        ' enable only PWM3 OUT1 (Q1/Q4 on RB5)       
        else
           PWMCON0 = %00110000      ' 0-3 PWM,  complementary
        endif      
      ADCON0 = %00000011            ' Start conversion on AN0
        WHILE ADCON0.1=1             ' Wait for it to complete 
        WEND   
         Fraw.HighByte = ADRESH     ' get result from AN0
         Fraw.LowByte = ADRESL      '     
      ADCON0 = %00000111            ' Start conversion on AN1
        WHILE ADCON0.1=1             ' Wait for it to complete 
        WEND    
         Draw.HighByte = ADRESH     ' get result from AN1
         Draw.LowByte = ADRESL      '      
         Freq = (Fraw *3) max 38    ' 
         draw = draw +1
         Duty=((freq*Draw)/261) +1
             PTPERH = Freq.highbyte 'load timer: Freq low byte
             PTPERL = Freq.lowbyte     ' Freq low byte
               PDC1H = Duty.HighByte  ' PWM duty
             PDC1L = Duty.LowByte          
    hserout ["D",dec duty,"F",dec Freq]
    goto Main                        ' Loop   
    end
    Like I said, I'm going to have to study my own work just to understand it better, but at least it works like it is suppose to. Yay! That was a few weeks of hair pulling!. Beat your head long enough against the wall, and sometimes you find a door.

    Thanks
    Bo

Similar Threads

  1. Quadrature encoder and ASM Interrupts. questions..
    By godfodder in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 17th March 2013, 14:45
  2. Instant Int and encoder (Elect. Gearing)
    By boroko in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 29th November 2009, 02:29
  3. Reset timer / encoder transition
    By DJEE in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 22nd June 2007, 14:37
  4. encoder HEDL 5540
    By kutsi in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 11th June 2007, 14:00
  5. encoder wowes
    By wallaby in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 6th December 2005, 21:56

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts