PWM in pic 16f877 problem

Discussion in 'Embedded Systems and Microcontrollers' started by pronto, Nov 19, 2017.

  1. pronto

    Thread Starter New Member

    Nov 6, 2017
    12
    1
    Hi everyone , i have a mini project with pic 16f877. i want to control the speed and direction of a stepper motor using PWM module in assembly language.i searched in the forum and i found some program but i face a problem : 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 but the CCP1/RC2 pin stay in 0 level...

    Any help please :

    LIST p=16F877
    #include <p16f877.inc>
    __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC

    ;-----------------------ASSIGNATION--------------------------------
    OPTIONVAL EQU B'10000000' ;B'10000111'
    INTCONVAL EQU B'01000000'
    DIRPORTA EQU B'00000001' ; AN0 =entree, le rest sont des sorties
    DIRPORTC EQU B'00000000'
    DIRPORTB EQU B'00000000'
    PIE1VAL EQU B'01000010'
    T2CONVAL EQU B'00000000'
    CCP1CONVAL EQU B'00001100'
    ADCON0VAL EQU B'10000000'
    ADCON1VAL EQU B'00001110'
    tempoval EQU D'35'
    PR2VAL EQU D'255'

    ;-----------------------MACRO---------------------------------
    BANK0 macro ; passer en banque 0
    bcf STATUS,RP0
    bcf STATUS,RP1
    endm
    BANK1 macro ;passer en banque 1
    bsf STATUS,RP0
    bcf STATUS,RP1
    endm
    BANK2 macro ;passer en banque 2
    bcf STATUS,RP0
    bsf STATUS,RP1
    endm
    BANK3 macro ;passer en banque 3
    bsf STATUS,RP0
    bsf STATUS,RP1
    endm
    ;-----------------------VARIABLES-------------------
    ;---------zone de BANK0
    CBLOCK 0x20
    ENDC
    ;--------zone commune----------------------------
    CBLOCK 0x70
    tempo : 1
    WAIT1:1
    WAIT2:1
    WAIT3:1
    ENDC
    ;-----------------------DEMARRAGE DU RESET------------
    org 0x000
    goto init
    ;----------------------INTERRUPTIONS------------------
    org 0x0004
    bsf STATUS,RP0
    btfss PIE1,ADIE ;sauter si l'int AD est autorise
    goto int_test1 ;no! aller au teste suivant
    bcf STATUS,RP0
    btfsc PIR1,ADIF ;sauter si le flage est 0
    call int_AD ;flag=0! traiter cette interruption
    goto int_test1
    ;-------------interruption timer2-----------
    int_test1
    bsf STATUS,RP0
    btfss PIE1,TMR2IE ;sauter si l'int TMR2 est autorisee
    goto restoreg ;no fin d'int
    bcf STATUS,RP0 ;banque 0
    btfsc PIR1,TMR2IF ;flag positione ! traiter l'int
    call int_TMR2
    goto restoreg

    restoreg
    retfie ; return from interrupt

    ;---------interruption timer2------------
    int_TMR2
    bcf PIR1,TMR2IF ;effacer le flage de timer2
    bsf ADCON0,ADON ;lancer l'aquisition AD
    bsf PORTC,5
    wait20us ;routine de 20 us
    ;movf tempo,f
    decfsz tempo,f
    goto wait20us
    movlw tempoval
    movwf tempo
    bsf ADCON0,GO ;lancer la conversion AD
    return

    ;----------interruption convAD-----------
    int_AD
    bsf PORTC,5
    bcf ADCON0,ADON
    bcf PIR1,ADIF
    movf ADRESH,w
    movwf CCPR1L
    bsf STATUS,RP0 ;banque 1
    btfss ADRESL,7
    goto next_test
    bcf STATUS,RP0
    bsf CCP1CON,CCP1X
    next_test
    bsf STATUS,RP0
    btfss ADRESL,6
    return
    bcf STATUS,RP0
    bsf CCP1CON,CCP1Y
    return
    ;---------------------INITIALISATION---------------------------
    init
    BANK0
    clrf PORTA ;effacer porta
    clrf PORTC ;effacer portc
    CLRF PORTB
    movlw INTCONVAL ;autorisation de l'int periphirique
    movwf INTCON
    movlw T2CONVAL ;prediviseur=16,
    movwf T2CON
    movlw CCP1CONVAL ; en mode PWM
    movwf CCP1CON
    movlw ADCON0VAL ;frequence de osc =32
    movwf ADCON0
    clrf ADRESH

    bsf STATUS,RP0 ; sélectionner banque1
    clrf ADRESL
    movlw OPTIONVAL
    movwf OPTION_REG
    movlw DIRPORTA ;AN0 entree
    movwf TRISA
    movlw DIRPORTC ;CCP1/RC2 sortie
    movwf TRISC
    MOVLW DIRPORTB
    MOVWF TRISB
    movlw ADCON1VAL ;justification a gauche
    movwf ADCON1 ;1 entree analogique
    movlw PR2VAL ;charger PR2 avec H'FF'
    movwf PR2
    movlw PIE1VAL ;masque int AD=1,masque int TMR2=1
    movwf PIE1
    bcf STATUS,RP0 ;banque 0
    clrf TMR2 ;effacer timer 2
    clrf PIR1 ;effacer flags
    bsf INTCON,GIE ;valider interruptions

    movlw tempoval ;pour la routine de 20 us
    movwf tempo
    bsf T2CON,TMR2ON ;demarer timer2

    goto start

    ;*** TEMPO 20MS ***
    TEMPO3 ;TEMPO DE 500µS
    MOVLW D'165'
    MOVWF WAIT1
    T1
    DECFSZ WAIT1,f
    GOTO T1
    NOP
    RETURN

    TEMPO2 ;TEMPO DE 20MS
    MOVLW D'250'
    MOVWF WAIT2
    T2
    CALL TEMPO3
    DECFSZ WAIT2,f
    GOTO T2
    NOP
    RETURN

    TEMPO ;TEMPO DE 20MS
    MOVLW D'50'
    MOVWF WAIT3
    T3
    CALL TEMPO2
    DECFSZ WAIT3,f
    GOTO T3
    NOP
    RETURN


    ;=================================== SENS NEGATIF ============================================
    NEGATIF

    CLRF PORTB

    movlw b'00000100' ; position 0

    movwf PORTB

    call TEMPO


    movlw b'00000001' ; position -90

    movwf PORTB

    call TEMPO


    movlw b'00001000' ; position -180

    movwf PORTB

    call TEMPO


    movlw b'00000010' ; position -270

    movwf PORTB

    call TEMPO

    RETURN

    ;-----------------------program principale----------------------------
    start

    goto start
    END
     
  2. simozz

    Member

    Jul 23, 2017
    102
    27
    I don't have a board ready to test with the PIC16877 (and I can't check the data-sheet right now) but you might compare these source codes from mikroe.com to chek what's wrong in your code.
    Hope it helps.

    PS: you should use the code tags to format the source code into the forum.
     
  3. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    7,928
    1,955
    How are you going to control a stepper motor using a PWM signal? They need a sequence of outputs to drive them and to reverse the motor you must reverse the sequence.

    You have a subroutine, NEGATIF, which looks like it might provide such a sequence but it is never called.
     
    absf likes this.
  4. MaxHeadRoom

    Expert

    Jul 18, 2013
    18,410
    5,653
    Better to show in CODE.
    Code (ASM):
    1. LIST p=16F877
    2. #include <p16f877.inc>
    3. __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
    4.  
    5. ;-----------------------ASSIGNATION--------------------------------
    6. OPTIONVAL EQU B'10000000' ;B'10000111'
    7. INTCONVAL EQU B'01000000'
    8. DIRPORTA EQU B'00000001' ; AN0 =entree, le rest sont des sorties
    9. DIRPORTC EQU B'00000000'
    10. DIRPORTB EQU B'00000000'
    11. PIE1VAL EQU B'01000010'
    12. T2CONVAL EQU B'00000000'
    13. CCP1CONVAL EQU B'00001100'
    14. ADCON0VAL EQU B'10000000'
    15. ADCON1VAL EQU B'00001110'
    16. tempoval EQU D'35'
    17. PR2VAL EQU D'255'
    18.  
    19. ;-----------------------MACRO---------------------------------
    20. BANK0 macro ; passer en banque 0
    21.              bcf STATUS,RP0
    22.              bcf STATUS,RP1
    23.               endm
    24. BANK1 macro ;passer en banque 1
    25.                  bsf STATUS,RP0
    26.               bcf STATUS,RP1
    27. endm
    28. BANK2 macro ;passer en banque 2
    29.               bcf STATUS,RP0
    30.               bsf STATUS,RP1
    31. endm
     
  5. pronto

    Thread Starter New Member

    Nov 6, 2017
    12
    1
    @simozz thank you for your answer that help a lot but i didn't find the problem yet :(
     
  6. pronto

    Thread Starter New Member

    Nov 6, 2017
    12
    1
    @AlbertHall yes i know i forget it but this isn't the solution of my problem :(
     
  7. pronto

    Thread Starter New Member

    Nov 6, 2017
    12
    1
    @MaxHeadRoom i really like to show my code like you did by i didn't know how to do it
     
  8. pronto

    Thread Starter New Member

    Nov 6, 2017
    12
    1
    Code (Text):
    1.  LIST p=16F877
    2. #include <p16f877.inc>
    3. __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
    4.  
    5. ;-----------------------ASSIGNATION--------------------------------
    6. OPTIONVAL EQU B'10000000' ;B'10000111'
    7. INTCONVAL EQU B'01000000'
    8. DIRPORTA EQU B'00000001' ; AN0 =entree, le rest sont des sorties
    9. DIRPORTC EQU B'00000000'
    10. DIRPORTB EQU B'00000000'
    11. PIE1VAL EQU B'01000010'
    12. T2CONVAL EQU B'00000000'
    13. CCP1CONVAL EQU B'00001100'
    14. ADCON0VAL EQU B'10000000'
    15. ADCON1VAL EQU B'00001110'
    16. tempoval EQU D'35'
    17. PR2VAL EQU D'255'
    18.  
    19. ;-----------------------MACRO---------------------------------
    20. BANK0 macro ; passer en banque 0
    21. bcf STATUS,RP0
    22. bcf STATUS,RP1
    23. endm
    24. BANK1 macro ;passer en banque 1
    25. bsf STATUS,RP0
    26. bcf STATUS,RP1
    27. endm
    28. BANK2 macro ;passer en banque 2
    29. bcf STATUS,RP0
    30. bsf STATUS,RP1
    31. endm
    32. BANK3 macro ;passer en banque 3
    33. bsf STATUS,RP0
    34. bsf STATUS,RP1
    35. endm
    36. ;-----------------------VARIABLES-------------------
    37. ;---------zone de BANK0
    38. CBLOCK 0x20
    39. ENDC
    40. ;--------zone commune----------------------------
    41. CBLOCK 0x70
    42. tempo : 1
    43. WAIT1:1
    44. WAIT2:1
    45. WAIT3:1
    46. ENDC
    47. ;-----------------------DEMARRAGE DU RESET------------
    48. org 0x000
    49. goto init
    50. ;----------------------INTERRUPTIONS------------------
    51. org 0x0004
    52. bsf STATUS,RP0
    53. btfss PIE1,ADIE ;sauter si l'int AD est autorise
    54. goto int_test1 ;no! aller au teste suivant
    55. bcf STATUS,RP0
    56. btfsc PIR1,ADIF ;sauter si le flage est 0
    57. call int_AD ;flag=0! traiter cette interruption
    58. goto int_test1
    59. ;-------------interruption timer2-----------
    60. int_test1
    61. bsf STATUS,RP0
    62. btfss PIE1,TMR2IE ;sauter si l'int TMR2 est autorisee
    63. goto restoreg ;no fin d'int
    64. bcf STATUS,RP0 ;banque 0
    65. btfsc PIR1,TMR2IF ;flag positione ! traiter l'int
    66. call int_TMR2
    67. goto restoreg
    68.  
    69. restoreg
    70. retfie ; return from interrupt
    71.  
    72. ;---------interruption timer2------------
    73. int_TMR2
    74. bcf PIR1,TMR2IF ;effacer le flage de timer2
    75. bsf ADCON0,ADON ;lancer l'aquisition AD
    76. bsf PORTC,5
    77. wait20us ;routine de 20 us
    78. ;movf tempo,f
    79. decfsz tempo,f
    80. goto wait20us
    81. movlw tempoval
    82. movwf tempo
    83. bsf ADCON0,GO ;lancer la conversion AD
    84. return
    85.  
    86. ;----------interruption convAD-----------
    87. int_AD
    88. bsf PORTC,5
    89. bcf ADCON0,ADON
    90. bcf PIR1,ADIF
    91. movf ADRESH,w
    92. movwf CCPR1L
    93. bsf STATUS,RP0 ;banque 1
    94. btfss ADRESL,7
    95. goto next_test
    96. bcf STATUS,RP0
    97. bsf CCP1CON,CCP1X
    98. next_test
    99. bsf STATUS,RP0
    100. btfss ADRESL,6
    101. return
    102. bcf STATUS,RP0
    103. bsf CCP1CON,CCP1Y
    104. return
    105. ;---------------------INITIALISATION---------------------------
    106. init
    107. BANK0
    108. clrf PORTA ;effacer porta
    109. clrf PORTC ;effacer portc
    110. CLRF PORTB
    111. movlw INTCONVAL ;autorisation de l'int periphirique
    112. movwf INTCON
    113. movlw T2CONVAL ;prediviseur=16,
    114. movwf T2CON
    115. movlw CCP1CONVAL ; en mode PWM
    116. movwf CCP1CON
    117. movlw ADCON0VAL ;frequence de osc =32
    118. movwf ADCON0
    119. clrf ADRESH
    120.  
    121. bsf STATUS,RP0 ; sélectionner banque1
    122. clrf ADRESL
    123. movlw OPTIONVAL
    124. movwf OPTION_REG
    125. movlw DIRPORTA ;AN0 entree
    126. movwf TRISA
    127. movlw DIRPORTC ;CCP1/RC2 sortie
    128. movwf TRISC
    129. MOVLW DIRPORTB
    130. MOVWF TRISB
    131. movlw ADCON1VAL ;justification a gauche
    132. movwf ADCON1 ;1 entree analogique
    133. movlw PR2VAL ;charger PR2 avec H'FF'
    134. movwf PR2
    135. movlw PIE1VAL ;masque int AD=1,masque int TMR2=1
    136. movwf PIE1
    137. bcf STATUS,RP0 ;banque 0
    138. clrf TMR2 ;effacer timer 2
    139. clrf PIR1 ;effacer flags
    140. bsf INTCON,GIE ;valider interruptions
    141.  
    142. movlw tempoval ;pour la routine de 20 us
    143. movwf tempo
    144. bsf T2CON,TMR2ON ;demarer timer2
    145.  
    146. goto start
    147.  
    148. ;*** TEMPO 20MS ***
    149. TEMPO3 ;TEMPO DE 500µS
    150. MOVLW D'165'
    151. MOVWF WAIT1
    152. T1
    153. DECFSZ WAIT1,f
    154. GOTO T1
    155. NOP
    156. RETURN
    157.  
    158. TEMPO2 ;TEMPO DE 20MS
    159. MOVLW D'250'
    160. MOVWF WAIT2
    161. T2
    162. CALL TEMPO3
    163. DECFSZ WAIT2,f
    164. GOTO T2
    165. NOP
    166. RETURN
    167.  
    168. TEMPO ;TEMPO DE 20MS
    169. MOVLW D'50'
    170. MOVWF WAIT3
    171. T3
    172. CALL TEMPO2
    173. DECFSZ WAIT3,f
    174. GOTO T3
    175. NOP
    176. RETURN
    177.  
    178.  
    179. ;=================================== SENS NEGATIF ============================================
    180. NEGATIF
    181.  
    182. CLRF PORTB
    183.  
    184. movlw b'00000100' ; position 0
    185.  
    186. movwf PORTB
    187.  
    188. call TEMPO
    189.  
    190.  
    191. movlw b'00000001' ; position -90
    192.  
    193. movwf PORTB
    194.  
    195. call TEMPO
    196.  
    197.  
    198. movlw b'00001000' ; position -180
    199.  
    200. movwf PORTB
    201.  
    202. call TEMPO
    203.  
    204.  
    205. movlw b'00000010' ; position -270
    206.  
    207. movwf PORTB
    208.  
    209. call TEMPO
    210.  
    211. RETURN
    212.  
    213. ;-----------------------program principale----------------------------
    214. start
    215.  
    216. goto start
    217. END [code]
     
  9. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    7,928
    1,955
  10. pronto

    Thread Starter New Member

    Nov 6, 2017
    12
    1
    @AlbertHall and how can i modify my thread ? i don't see any Edit button here
     
  11. MaxHeadRoom

    Expert

    Jul 18, 2013
    18,410
    5,653
    Actually assembly is not documented, you place CODE=asm in brackets.
    Max.
     
Loading...