Puzzing A-D PWM code.

Discussion in 'Embedded Systems and Microcontrollers' started by MaxHeadRoom, Jul 19, 2018.

  1. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    I have the Pic Mechatronics and also the BLDC development boards that includes code with several examples.
    Looking over the Project5 which is a simple pot control of a DC motor with single output PWM.
    The manual states that 8 A-D bits are sufficient for this control.
    I am puzzled as to what is actually intended for the SetMotorSpeed: routine which just captures the 8MSB of the A-D, one, the ADCON0 GO_DONE bit is not tested for completion.
    But the bit shuffling of the result as shown in the short set routine has me stumped.
    Why not just read the 12bit A-D and use it for the PWM registers?
    The routines appears to work as intended, so I am missing something.
    I have trimmed the whole program down to the relevant routine.


    Code (Microchip Assembler):
    1. ;  
    2. ;          16F917.lkr                                                        
    3. ;          using 16F917 Pic                                                          
    4. ;************************************************************************************
    5. ;                                                                    
    6. ;    Notes:  This project controls the speed of a brushed DC motor.  POT1 is used to
    7. ;            set the speed of the motor.  The optical interrupter provides speed
    8. ;            feedback.  This feedback is fed into the T1CKL pin and the speed of the
    9. ;            motor is measured.  The speed is then displayed on the LCD as RPM / 10^3.                                                      
    10. ;                                                                    
    11.  
    12. ;**********************************************************************
    13. STARTUP    code
    14.     goto    Initialize
    15.  
    16.  
    17.  
    18. ; Finish setting up A-to-D Module
    19.         movlw    b'00000001'        ; left justified, AN0 selected, module on
    20.         movwf    ADCON0      
    21. ; Configure Capture Compare PWM Module 2
    22.         clrf    CCPR2L
    23.         movlw    b'00001100'        ; pwm mode
    24.         movwf    CCP2CON
    25. ; Turn on Timer 2
    26.         bsf     T2CON,TMR2ON    ; turn on PWM
    27.  
    28. ;************************************************************************************
    29. ; Main - Every 23.4ms POT1 is measured and moved into the dutycycle registers for
    30. ;  CCP2.  CCP2 drives the brushed dc motor, thereby controlling the speed.  Timer 1
    31. ;  is clocked by the Optical Interrupter.  Every 3/4 of a second the value in Timer 1
    32. ;  is converted to RPM and displayed as: RPM / 10^3.
    33. ;
    34. ;************************************************************************************
    35. Main:
    36.       ;
    37.  
    38.         call    SetMotorSpeed
    39.         call    MeasureSpeed
    40.         btfsc    STATUS,C
    41.         call    DisplaySpeed
    42.    
    43.         goto    Loop
    44.  
    45. SetMotorSpeed:
    46.         movf    ADRESH, W
    47.         movwf    DutyCycle
    48.         bsf        ADCON0,GO_DONE
    49.         bsf        P1                    ; Turn on motor
    50.         swapf    DutyCycle, W            ;  bits 4 and 5 of CCP2CON
    51.         andlw    0x30
    52.         iorlw    0x8D
    53.         movwf    CCP2CON
    54.         rrf     DutyCycle, F            ; move most significant 6 bits of duty cycle into
    55.         rrf     DutyCycle, W            ;  CCPR2L
    56.         andlw    0x3F
    57.         movwf    CCPR2L
    58.         return
    59.  
    60. MeasureSpeed:
    61.  
     
  2. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    The two LSBs of the PWM duty cycle are in CCP2CON <5:4>. Lines 50 to 53 move the appropriate bits from DutyCycle to CCP2CON.
    Lines 54 to 57 shift those bits out of DutyCycle and place the remaining bits in CCPR2L.
    Not included in the code you posted is the PR2 setting which I would expect to be 0x3F.
    ADCON0,GO_DONE is set immediately after the ADC result is read to trigger the next reading. If it is known that the loop time is longer than the ADC conversion time then there is no need to check if the conversion has completed.
     
  3. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    PR2 is 0x3f.
    I will run it through the de-bugger again and see the result, I just don't know why not read all 12 bits and enter them direct in the PWM registers?
    I ran it simulated and got weird results.
    Max.
     
  4. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    There woud still be some bit twiddling needed as the PWM is max 10 bits and the lower 2 of those 10 need to be in CCP2CON.
    That program is using the PWM as only 8 bits and that may be so as to be able to use a suitable frequency. Lower PWM resolution allow higher PWM frequency.
     
  5. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    I am aiming on a super low PWM freq of 20Hz, processor clock is internal 32kHz.
    Max.
     
  6. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    The formulae in the datasheet will let you calculate a suitable timer prescale value and period (PR2). Then you can calculate what resolution you will get with those values.
     
  7. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
  8. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    Cheat!
     
  9. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    One thing to watch with some of these programs is whether the same bits jive in the registers, for e.g. the pre-scaler bits may be different in some Micro's.
    Max.
     
  10. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    You need to check the values the program produces though that program says it covers the '917 (if that's the one you are going to use).
     
  11. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    No, 12F1822.
    Max.
     
  12. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    Ah! That isn't in the list.
    You might have to get the slide rule out after all.
     
  13. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    I just checked and compared the relevant registers and made any neccessary changes.
    The basic numbers should be the same.
    I don't quite see what the problem would be using the 12 A-D bit number directly into the PWM registers.
    The two LSB's properly shifted of course.
    Max.
     
  14. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    It's still only a 10 bit PWM so you must lose 2 bits as well.
     
  15. MaxHeadRoom

    Thread Starter Expert

    Jul 18, 2013
    15,725
    4,585
    I missprinted, :( should have been 10bit A-D.
    Max.
     
  16. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    6,221
    1,446
    I didn't check that bit.
     
Loading...