1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

16F88 PWM and A/D conversion

Discussion in 'Microcontrollers' started by williB, Jun 5, 2005.

  1. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    Thanks Motion ..
    I shall try that , after i repair the damage i did to the programmer last night ..
    Not sure if i burnt the chip or wether i burnt the 74LS241 or one of the flip flops or wether i just need to work on the programming of the programmer ..something happened because it isnt working like it was ..bummer..
     
  2. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    I cant wait to try this out.. i fixed the hardware of the programmer , now i am rewriting some the software..
     
  3. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    Mike this code works on a F628 ,but not on an F88 why ??
    What could be wrong ??


    Code (text):
    ;******************************************************************

            org   0x0000

    RESET   clrf    STATUS          ;                                 |B0
            clrf    PORTA           ; clear Port A data latches       |B0
            clrf    PORTB           ; clear Port B data latches       |B0
            movlw   h'07'           ;                                 |B0
            movwf   CMCON           ; turn comparator off             |B0
            bsf     STATUS,RP0      ; select bank 1                   |B1
            clrf    TRISA           ; port A all outputs              |B1
            clrf    TRISB           ; port B all outputs              |B1
            bcf     STATUS,RP0      ; select bank 0                   |B0
    ;
    ;  setup PWM (looks like CCPR1L uses Tosc while PR2 uses Tcyc)
    ;
            clrf    T2CON           ; TMR2 prescale:1                 |B0
            movlw   d'100'          ; same as (100*4)>>2              |B0
            movwf   CCPR1L          ; 100 usecs, 50% duty cycle?      |B0
            bsf     STATUS,RP0      ; select bank 1                   |B1
            movlw   d'200'-1        ; 200 1.0 usec 'ticks'            |B1
            movwf   PR2             ; Period=200 usecs, Freq=5.0 KHz  |B1
            bcf     STATUS,RP0      ; select bank 0                   |B0
            movlw   b'00001100'     ;                                 |B0
            movwf   CCP1CON         ; put CCP module in PWM mode      |B0
            bsf     T2CON,TMR2ON    ; turn on TMR2                    |B0
    ;
    ;  now test to see if the LED on RB3 is glowing at 50% brightness
    ;
    LOOP    goto    LOOP            ; loop indefinately               |B0
    ;
    ;***************************************************************
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA

    Willi,

    Are you sure it's not workin'? Are you checkin' the right pin? The CCP1 pwm output pin can be configured as RB0 or RB3 with a configuration bit setting... Have you taken a look at the Data Sheets?

    I can take a closer look in awhile after finishing up a Flight Plan I'm workin' on...

    Regards, Mike
     
  6. upand_at_them

    upand_at_them Member

    Joined:
    Apr 23, 2005
    Messages:
    609
    Likes:
    8
    Location:
    Pennsylvania, U.S.
    I don't know if it matters, but turning off the comparators on a 16F88 also includes setting ANSEL to 0.

    Mike
     
  7. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    Willi,

    It works on my 20-MHz 16F88 proto' board and I only modified the file slightly... I added a clrf ANSEL instruction (bank 1) to turn off the ADC module, which shouldn't have affected PWM, and I modified T2CON for prescale=16 for this particular 20-MHz board and I also set PR2=100 for a 320-usec period (frequency = 3125-Hz)...

    Good luck... Regards, Mike

    <added>

    If you omit the _CCP1_RB0 or _CCP1_RB3 setting in your config' line, the configuration will default to CCP1 on RB0...

    Code (text):
            __CONFIG  _CONFIG1, _CCP1_RB0&_LVP_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC
            __CONFIG  _CONFIG2, _IESO_OFF & _FCMEN_OFF

     
     
  8. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    How did it change to Pin RB0.. :oops:
     
  9. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    It does in fact work..
    eureka !! .. damn me !
     
  10. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    Thank you !! to everyone who offered suggestions ..
    The ADC section WORKS PERFECTLY
    The PWM works from compleatly off to full on !!...amazing ..
    Mike your code is flawless
    thank you all again ..
     
  11. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    Code (text):
    results of my PWM LED test..
     i adjusted  the PWM to keep the current at 2mA...

    Elapsed time /-/ Voltage on 2.2 F capacitance..

    20 min             3.56 V     2mA
    30 min             2.97 V     2mA
    40 min             2.30 V     2mA
    45 min             2.05 V     2mA
    47 min             1.94 V     2mA
    48 min             1.88 V     2mA
    48 min 30 sec      1.83 V  1.8 mA
     
    after 48 min 30 sec the caps ran out of power and i no longer could control the amount of current used by the LED ...
    i used a rechargable battery was to boost the usable voltage from the caps. its voltage was not enough to power the LED by itself ..
    i connected the PWM output from the PIC16F88 to the gate of a FET which was used to drive the LED circuit which had only a 1.0 ohms resistor....
    i used a varible resistor connected to the ADC input of the PIC to control the current..
     
  12. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    Could this be why i am getting intermittant blips in the PWM signal??..because i still havnt tried this yet..
    what i have done with the PWM is
    controlled a motor speed..
    controlled the rate of discharge of current from the super caps to a pair of NiMH batteries..
    I have also been able controll the cranking force of my hand generator, by adjusting the dutycycle ..
    and of course my LEDs
    i tell ya this Varible PWM is the greatest thing since sliced bread..
     
  13. motion

    motion New Member

    Joined:
    Jul 14, 2003
    Messages:
    560
    Likes:
    0
    Location:
    Quezon City.PH
    The PWM duty is double-buffered and essentially glitch-free. I would suspect the A/D conversion part more than the PWM. It's hard to tell without knowing more details like your current source code.

    Not exactly. However put in a low cost PIC, it did open a lot possibilities.
     
  14. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    i could post it , but there are zero comments in it , because i had a hard copy from mike's code..
     
  15. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    ok this is my PWM code which reads the ADC of the 16F88..
    Notice that The list directive is for a F84, and the .inc file is commented out..
    its a long story , but the short of it is i am running MPASM under dos on a different machine , the one with my programmer on it ..
    anyway with the appropriate equates it really doesnt matter what is up at the top of the program..
    so i listed all the equates that i needed..not all of the F88 equates though ..
    oh the comments can be found on the preceding pages of this thread..


    Code (text):

            LIST    P=16F84
          ;  include "P16F628A.inc"

                               
    TEMP    EQU     0x0c
    ADON    EQU     0X00
    ADIF    EQU     0X06
    GO_DONE EQU     0X02
    TMR2ON  EQU     0X02
    RP0     EQU     0x05
    RP1     EQU     0x06
    W                            EQU     H'0000'
    F                            EQU     H'0001'

    ;----- Register Files------------------------------------------------------

    INDF                         EQU     H'0000'
    TMR0                         EQU     H'0001'
    PCL                          EQU     H'0002'
    STATUS                       EQU     H'0003'
    FSR                          EQU     H'0004'
    PORTA                        EQU     H'0005'
    PORTB                        EQU     H'0006'
    PCLATH                       EQU     H'000A'
    INTCON                       EQU     H'000B'
    PIR1                         EQU     H'000C'
    PIR2                         EQU     H'000D'
    TMR1L                        EQU     H'000E'
    TMR1H                        EQU     H'000F'
    T1CON                        EQU     H'0010'
    TMR2                         EQU     H'0011'
    T2CON                        EQU     H'0012'
    CCPR1L                       EQU     H'0015'
    CCPR1H                       EQU     H'0016'
    CCP1CON                      EQU     H'0017'
    RCSTA                        EQU     H'0018'
    TXREG                        EQU     H'0019'
    RCREG                        EQU     H'001A'
    ADRESH                       EQU     H'001E'
    ADCON0                       EQU     H'001F'

    OPTION_REG                   EQU     H'0081'
    TRISA                        EQU     H'0085'
    TRISB                        EQU     H'0086'
    PIE1                         EQU     H'008C'
    PCON                         EQU     H'008E'
    PR2                          EQU     H'0092'
    TXSTA                        EQU     H'0098'
    SPBRG                        EQU     H'0099'
    EEDATA                       EQU     H'009A'
    ANSEL                        EQU     H'009B'
    CMCON                        EQU     H'009C'
    EECON2                       EQU     H'009D'
    ADRESL                       EQU     H'009E'
    ADCON1                       EQU     H'009F'



            org     0x00                    
                                            ;this is where the program starts
            clrf    PORTA      
            clrf    PORTB
            CLRF    STATUS
            movlw   0x07
            movwf   CMCON
            bsf     STATUS ,RP0          ;bank 1
            CLRF    TRISA
            CLRF    TRISB
            BCF     STATUS ,RP0

            CLRF    T2CON
            MOVLW   D'000'
            MOVWF   CCPR1L
            BSF     STATUS,RP0
            MOVLW   d'255'-1
            MOVWF   PR2
            BCF     STATUS,RP0
            MOVLW   b'00001100'
            MOVWF   CCP1CON
            BSF     T2CON,TMR2ON

            BSF     STATUS,RP0
            MOVLW   b'00000001'
            MOVWF   TRISA
            MOVLW   b'00000001'
            MOVWF   ANSEL
            MOVLW   b'01000000'
            MOVWF   ADCON1
            BCF     STATUS,RP0
            MOVLW   b'01000000'
            MOVWF   ADCON0

    LOOP    CALL    ADC
            MOVWF   CCPR1L
            GOTO    LOOP

    ADC     BSF     ADCON0,ADON
            BCF     PIR1,ADIF
            MOVLW   d'13'
            MOVWF   TEMP
    ACQ     DECFSZ  TEMP,F
            GOTO    ACQ
            BSF     ADCON0,GO_DONE
    ADX     BTFSC   ADCON0,GO_DONE
            GOTO    ADX
            MOVF    ADRESH,W
            BCF     ADCON0,ADON
            RETURN


            end

     
     
  16. motion

    motion New Member

    Joined:
    Jul 14, 2003
    Messages:
    560
    Likes:
    0
    Location:
    Quezon City.PH
    I don't see anything wrong with the code. What I find unusual is the fact that you turn OFF the A/D converter at the end of each conversion. You don't save much power because only after usec later, you turn it back ON. In the meantime, power is disconnected to the ADC module and the sampling capacitor must charge from scratch.

    I don't know exactly your application but if the analog signal is coming from a potentiometer, the wiper in motion could momentarily disconnect and you could have a high value reading.

    Anyway, you can try my suggestion. I have modified the code to do so. It is really simpler than your code.

    Code (text):

            LIST    P=16F88
          ;  include "P16F628A.inc"

                             
    TEMP    EQU     0x0c
    ADON    EQU     0X00
    ADIF    EQU     0X06
    GO_DONE EQU     0X02
    TMR2ON  EQU     0X02
    TMR2IF  EQU     0X01
    RP0     EQU     0x05
    RP1     EQU     0x06
    W                            EQU     H'0000'
    F                            EQU     H'0001'

    ;----- Register Files------------------------------------------------------

    INDF                         EQU     H'0000'
    TMR0                         EQU     H'0001'
    PCL                          EQU     H'0002'
    STATUS                       EQU     H'0003'
    FSR                          EQU     H'0004'
    PORTA                        EQU     H'0005'
    PORTB                        EQU     H'0006'
    PCLATH                       EQU     H'000A'
    INTCON                       EQU     H'000B'
    PIR1                         EQU     H'000C'
    PIR2                         EQU     H'000D'
    TMR1L                        EQU     H'000E'
    TMR1H                        EQU     H'000F'
    T1CON                        EQU     H'0010'
    TMR2                         EQU     H'0011'
    T2CON                        EQU     H'0012'
    CCPR1L                       EQU     H'0015'
    CCPR1H                       EQU     H'0016'
    CCP1CON                      EQU     H'0017'
    RCSTA                        EQU     H'0018'
    TXREG                        EQU     H'0019'
    RCREG                        EQU     H'001A'
    ADRESH                       EQU     H'001E'
    ADCON0                       EQU     H'001F'

    OPTION_REG                   EQU     H'0081'
    TRISA                        EQU     H'0085'
    TRISB                        EQU     H'0086'
    PIE1                         EQU     H'008C'
    PCON                         EQU     H'008E'
    PR2                          EQU     H'0092'
    TXSTA                        EQU     H'0098'
    SPBRG                        EQU     H'0099'
    EEDATA                       EQU     H'009A'
    ANSEL                        EQU     H'009B'
    CMCON                        EQU     H'009C'
    EECON2                       EQU     H'009D'
    ADRESL                       EQU     H'009E'
    ADCON1                       EQU     H'009F'



            org     0x00
                                            ;this is where the program starts
            clrf    PORTA
            clrf    PORTB
            CLRF    STATUS
            BSF     STATUS ,RP0          ;bank 1. It should be ahead of CMCON
      ifdef __16F628A
            movlw   0x07
            movwf   CMCON
      endif
            CLRF    TRISA
            CLRF    TRISB
            BCF     STATUS ,RP0

            CLRF    T2CON
            MOVLW   D'000'
            MOVWF   CCPR1L
            BSF     STATUS,RP0
            MOVLW   d'255'-1
            MOVWF   PR2
            BCF     STATUS,RP0
            MOVLW   b'00001100'
            MOVWF   CCP1CON
            BSF     T2CON,TMR2ON

            BSF     STATUS,RP0
            MOVLW   b'00000001'
            MOVWF   TRISA
            MOVLW   b'00000001'
            MOVWF   ANSEL
            MOVLW   b'01000000'
            MOVWF   ADCON1
            BCF     STATUS,RP0
            MOVLW   b'01000000'
            MOVWF   ADCON0
            BSF     ADCON0,ADON
            CLRF    PIR1

    LOOP    CALL    ADC
            MOVWF   CCPR1L
            GOTO    LOOP

    ADC     BTFSS   PIR1,TMR2IF
            GOTO    ADC
            BCF     PIR1,TMR2IF

            MOVF    ADRESH,W
            BSF     ADCON0,GO_DONE
            RETURN

            END
     
  17. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    thanks i'll try it , btw the blips i was getting were about one every second , but intermitently , hard to explain..
    they were happening when the potentiometer wasnt moving..
    question::
    in this code below couldnt you just use one MovLW command ?
    since w contains b'00000001' from the first load there really isnt a need to load it again ?since it allready contains 1.. unless it is just for clarity..
    Code (text):

             BSF     STATUS,RP0
            MOVLW   b'00000001'
            MOVWF   TRISA
            MOVWF   ANSEL
     
    Code (text):
     
             BSF     STATUS,RP0
            MOVLW   b'00000001'
            MOVWF   TRISA
            MOVLW   b'00000001'
            MOVWF   ANSEL
           
     
     
  18. motion

    motion New Member

    Joined:
    Jul 14, 2003
    Messages:
    560
    Likes:
    0
    Location:
    Quezon City.PH
    Yes the first sample code is the same as the second. The W register does not lose its value after a MOVWF instruction.
     
  19. motion

    motion New Member

    Joined:
    Jul 14, 2003
    Messages:
    560
    Likes:
    0
    Location:
    Quezon City.PH
    It could be the watchdog timer reset.
     
  20. williB

    williB New Member

    Joined:
    Aug 30, 2004
    Messages:
    2,217
    Likes:
    3
    Location:
    New Jersey
    yeah , it is the same , with the revision , thats ok
    it works good enough for my purposes
     
  21. mrbogeyman

    mrbogeyman New Member

    Joined:
    Feb 9, 2006
    Messages:
    2
    Likes:
    0
    Bump!

    Just thought I would bring this old thread to light as I have a problem in this area.

    I have a few questions that are all related.

    I am using a PIC16F873A with a 4MHz resonator.

    I am currently trying to use PWM to control a servo motor that requires approximately a 0.5-2ms pulse every 20ms. This would also require a resolution of at least 0.01ms.

    What my problem is, is that I cannot seem to get the PWM going slowly enough for my purposes. I have fiddled with the prescalers and postscalers all day to no real avail. And, to be honest, with no real accuracy as I am a little unsure as to how best to calculate the required delay using the appropriate forumulas to equal the exact period required... :?

    So my question is, can a 4MHz resonator provide a pulse this size and at the correct interval? I beleive the frequency is 50Hz for a 20ms period.

    Is using a slower resonator a viable solution?

    Any suggestions, pointers or code would be appreciated.

    Thanks! :D

    p.s. im a noob here :oops:

    I have attached my code, but beware! it is VERY patchy as it is bodged together for testing pusposes. the comments are most likely wrong as i have been changing values left, right and center.
     

    Attached Files:

Share This Page