generate PWM in pic 16F876

Discussion in 'Embedded Systems and Microcontrollers' started by Chaabane, Dec 16, 2009.

  1. Chaabane

    Thread Starter Member

    Nov 30, 2009
    37
    0
    Hello,
    i'm trying to generate PWM sginal in pic16F876 using CCP1 module.
    i read a variable resistor via AN0 and based on this value i configure my PWM duty cycle (high level). everything works just fine in Mplab and proteus VSM,but the CCP1/RC2 pin stay in 0 level...
    here is the full code,all the comments are in french, sorry

    can you please give a quick look to my code and help me.
    Thanks
    Code ( (Unknown Language)):
    1.  
    2.  
    3.     LIST     p=16F876
    4.     #include <p16f876.inc>
    5.  __CONFIG    _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
    6.  
    7. ;-----------------------ASSIGNATION--------------------------------
    8. OPTIONVAL     EQU    B'10000000'    ;B'10000111'
    9. INTCONVAL    EQU    B'01000000'
    10. DIRPORTA    EQU    B'00000001'    ; AN0 =entree, le rest sont des sorties
    11. DIRPORTC    EQU    B'00000000'
    12. PIE1VAL        EQU    B'01000010'
    13. T2CONVAL    EQU B'00000011'
    14. CCP1CONVAL    EQU    B'00001100'
    15. ADCON0VAL    EQU B'10000000'
    16. ADCON1VAL    EQU    B'00001110'
    17. tempoval    EQU    D'35'
    18. PR2VAL        EQU H'FF'
    19.  
    20. ;-----------------------MACRO---------------------------------
    21. BANK0    macro        ; passer en banque 0
    22.         bcf STATUS,RP0
    23.         bcf    STATUS,RP1
    24.     endm
    25. BANK1    macro        ;passer en banque 1
    26.         bsf STATUS,RP0
    27.         bcf STATUS,RP1
    28.     endm
    29. BANK2    macro        ;passer en banque 2
    30.         bcf STATUS,RP0
    31.         bsf STATUS,RP1
    32.     endm
    33. BANK3    macro        ;passer en banque 3
    34.         bsf STATUS,RP0
    35.         bsf STATUS,RP1
    36.     endm
    37. ;-----------------------VARIABLES-------------------
    38. ;---------zone de BANK0
    39.     CBLOCK    0x20
    40.     ENDC
    41. ;--------zone commune----------------------------
    42.     CBLOCK 0x70
    43.     tempo : 1
    44.     ENDC
    45. ;-----------------------DEMARRAGE DU RESET------------
    46.     org 0x000
    47.     goto init
    48. ;----------------------INTERRUPTIONS------------------
    49.     org 0x0004
    50.     bsf        STATUS,RP0
    51.     btfss    PIE1,ADIE    ;sauter si l'int AD est autorise
    52.     goto    int_test1    ;no! aller au teste suivant
    53.     bcf        STATUS,RP0
    54.     btfsc    PIR1,ADIF    ;sauter si le flage est 0
    55.     call    int_AD        ;flag=0! traiter cette interruption
    56.     goto    int_test1
    57. ;-------------interruption timer2-----------
    58. int_test1
    59.     bsf        STATUS,RP0
    60.     btfss    PIE1,TMR2IE    ;sauter si l'int TMR2 est autorisee
    61.     goto    restoreg    ;no fin d'int
    62.     bcf        STATUS,RP0    ;banque 0    
    63.     btfsc    PIR1,TMR2IF    ;flag positione ! traiter l'int
    64.     call    int_TMR2
    65.     goto    restoreg
    66.  
    67. restoreg
    68.     retfie                      ; return from interrupt
    69.  
    70. ;---------interruption timer2------------
    71. int_TMR2
    72.     bcf        PIR1,TMR2IF        ;effacer le flage de timer2
    73.     bsf        ADCON0,ADON        ;lancer l'aquisition AD
    74.     bsf        PORTC,5
    75. wait20us                        ;routine de 20 us
    76.     ;movf    tempo,f
    77.     decfsz    tempo,f
    78.     goto     wait20us
    79.     movlw    tempoval
    80.     movwf    tempo
    81.     bsf        ADCON0,GO        ;lancer la conversion AD
    82.     return
    83.  
    84. ;----------interruption convAD-----------
    85. int_AD
    86.     bsf        PORTC,5
    87.     bcf     ADCON0,ADON
    88.     bcf        PIR1,ADIF
    89.     movf    ADRESH,w
    90.     movwf    CCPR1L
    91.     bsf        STATUS,RP0    ;banque 1
    92.     btfss    ADRESL,7
    93.     goto     next_test
    94.     bcf        STATUS,RP0
    95.     bsf        CCP1CON,CCP1X
    96. next_test
    97.     bsf        STATUS,RP0
    98.     btfss    ADRESL,6
    99.     return
    100.     bcf        STATUS,RP0
    101.     bsf        ADRESL,CCP1Y
    102.     return
    103. ;---------------------INITIALISATION---------------------------
    104. init
    105.     BANK0
    106.     clrf    PORTA        ;effacer porta
    107.     clrf    PORTC        ;effacer portc
    108.     movlw    INTCONVAL    ;autorisation de l'int periphirique
    109.     movwf    INTCON    
    110.     movlw    T2CONVAL    ;prediviseur=16,
    111.     movwf    T2CON        
    112.     movlw    CCP1CONVAL    ; en mode PWM
    113.     movwf    CCP1CON        
    114.     movlw    ADCON0VAL    ;frequence de osc =32
    115.     movwf    ADCON0
    116.     clrf    ADRESH
    117.    
    118.     bsf        STATUS,RP0        ; sélectionner banque1
    119.     clrf    ADRESL
    120.     movlw    OPTIONVAL        
    121.     movwf    OPTION_REG
    122.     movlw   DIRPORTA        ;AN0 entree
    123.     movwf    TRISA            
    124.     movlw   DIRPORTC        ;CCP1/RC2 sortie
    125.     movwf    TRISC
    126.     movlw   ADCON1VAL        ;justification a gauche
    127.     movwf    ADCON1            ;1 entree analogique
    128.     movlw    PR2VAL            ;charger PR2 avec H'FF'
    129.     movwf    PR2
    130.     movlw    PIE1VAL            ;masque int AD=1,masque int TMR2=1
    131.     movwf    PIE1
    132.     bcf        STATUS,RP0        ;banque 0
    133.     clrf     TMR2            ;effacer timer 2
    134.     clrf    PIR1            ;effacer flags
    135.     bsf        INTCON,GIE        ;valider interruptions
    136.    
    137.     movlw    tempoval        ;pour la routine de 20 us
    138.     movwf    tempo
    139.     bsf        T2CON,TMR2ON    ;demarer timer2
    140.    
    141.     goto    start            
    142. ;-----------------------program principale----------------------------
    143. start
    144.     goto start
    145.     END
     
  2. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    I haven't looked at the code but could you describe (or post schematic) of how the analog input variable resistor is connected?
     
  3. Chaabane

    Thread Starter Member

    Nov 30, 2009
    37
    0
  4. Chaabane

    Thread Starter Member

    Nov 30, 2009
    37
    0
    Anyone can help me with this ?
     
  5. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Not sure if this helps at all, but it is fully working and tested code for the pic16F628a.
    It is from when I was testing PWM. All it does is polls 10 pins with switches. All are pulled high by either internal pullups or resistors and the switches pull the pins low.
    Maybe you could compare with your code and see what the differences are.
    Code ( (Unknown Language)):
    1.  
    2.     list      p=16f628a            ; list directive to define processor
    3.     #include <p16f628a.inc>        ; processor specific variable definitions
    4.    
    5.     __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_ON
    6.  
    7.  
    8.  
    9. ;***** VARIABLE DEFINITIONS
    10. w_temp        EQU     0x70        ; variable used for context saving
    11. status_temp   EQU     0x71        ; variable used for context saving
    12.  
    13.     cblock 0x20
    14.     count
    15.     count2
    16.     CCPR1Ltemp
    17.     CCP1CONtemp
    18.     endc
    19.  
    20. ;**********************************************************************
    21.         ORG     0x000             ; processor reset vector
    22.         goto    init              ; go to beginning of program
    23.  
    24.  
    25.         ORG     0x004             ; interrupt vector location
    26.         movwf   w_temp            ; save off current W register contents
    27.         movf    STATUS,w          ; move status register into W register
    28.         movwf    status_temp       ; save off contents of STATUS register
    29.  
    30.  
    31. ; isr code can go here or be located as a call subroutine elsewhere
    32.  
    33.  
    34.         movf    status_temp,w     ; retrieve copy of STATUS register
    35.         movwf    STATUS            ; restore pre-isr STATUS register contents
    36.         swapf   w_temp,f
    37.         swapf   w_temp,w          ; restore pre-isr W register contents
    38.         retfie                    ; return from interrupt
    39.  
    40.  
    41. init
    42.     movlw B'00000111'
    43.     movwf CMCON                ;comparitors off    
    44.     movlw B'00000100'
    45.     movwf T1CON                ;enable timer1 internal no prescaler
    46.     BSF STATUS, RP0 ; Bank 1
    47. ;    bsf PIE1, 0                ;timer1 int enabled
    48. ;    BSF STATUS, RP0 ; Bank 1    
    49.     clrf   OPTION_REG      ; weak pull ups
    50.     bcf     STATUS, RP0    ; bank 0    
    51.     movlw   B'01001000'     ; enable timer 1 interrupt and gpio change (not GIE yet)
    52.     movwf   INTCON          ;  
    53.     CLRF TMR1L                 ; Clear Low byte, Ensures no rollover into TMR1H
    54.     clrf TMR1H
    55. ;    CLRF GPIO                 ; Initialize GPIO by
    56.                             ; clearing output
    57.                             ; data latches
    58.     BSF STATUS, RP0         ; Select Bank 1
    59.     movlw 0xFF
    60.     movwf PR2                ;PWM setting
    61.     MOVLW B'11000011'        
    62.     MOVWF TRISA             ; Set RA<1:0 and 7:6> as input all others out
    63.     MOVLW B'11110111'        
    64.     MOVWF TRISB             ; Set all input except RB3 PWM out
    65.  
    66.     BCF STATUS, RP0         ;bank 0
    67.     movlw B'00000100'        
    68.     movwf T2CON                ;timer 2 on, no prescaler or postscaler
    69.     movlw B'00001111'
    70.     movwf CCP1CON
    71.     movlw 0x04
    72.     movwf CCPR1L
    73.    
    74. ;    bsf INTCON, GIE            ;enable interrupts, then sleep
    75.  
    76.  
    77.  
    78.  
    79.  
    80.  
    81. main
    82.     bcf CCPR1Ltemp, 7
    83.     btfss PORTA, 1
    84.     bsf CCPR1Ltemp, 7
    85.     bcf CCPR1Ltemp, 6
    86.     btfss PORTA, 0
    87.     bsf CCPR1Ltemp, 6
    88.     bcf CCPR1Ltemp, 5
    89.     btfss PORTB, 7
    90.     bsf CCPR1Ltemp, 5
    91.     bcf CCPR1Ltemp, 4
    92.     btfss PORTB, 6
    93.     bsf CCPR1Ltemp, 4
    94.     bcf CCPR1Ltemp, 3
    95.     btfss PORTB, 5
    96.     bsf CCPR1Ltemp, 3
    97.     bcf CCPR1Ltemp, 2
    98.     btfss PORTB, 2
    99.     bsf CCPR1Ltemp, 2
    100.     bcf CCPR1Ltemp, 1
    101.     btfss PORTB, 1
    102.     bsf CCPR1Ltemp, 1
    103.     bcf CCPR1Ltemp, 0
    104.     btfss PORTB, 0
    105.     bsf CCPR1Ltemp, 0
    106.     movf CCP1CON, W            ;just in case
    107.     movwf CCP1CONtemp
    108.     bcf CCP1CONtemp, 5
    109.     btfss PORTA, 7
    110.     bsf CCP1CONtemp, 5
    111.     bcf CCP1CONtemp, 4
    112.     btfss PORTA, 6
    113.     bsf CCP1CONtemp, 4
    114.     movf CCP1CONtemp, W            
    115.     movwf CCP1CON
    116.     movf CCPR1Ltemp, W            
    117.     movwf CCPR1L
    118.  
    119.  
    120.  
    121.  
    122.  
    123.  
    124.  
    125.  
    126.  
    127.  
    128.  
    129.  
    130.  
    131.  
    132.  
    133.     goto main
    134.  
    135.  
    136.  
    137.  
    138.  
    139.  
    140.  
    141.  
    142.  
    143.  
    144.  
    145.         END                       ; directive 'end of program'
    146.  
    147.  
    148.  
     
  6. AdamIngleton

    New Member

    Jan 18, 2010
    1
    0
    Thanks for the code Mark, this was exactly what I was looking for. It's great how whenever I need help with something I always find what I'm looking for here.

    Bowtrol | Web Marketing
     
    Last edited: May 13, 2010
Loading...