PWM in pic 16f877 problem

Thread Starter

pronto

Joined Nov 6, 2017
12
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
 

simozz

Joined Jul 23, 2017
170
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.
 

AlbertHall

Joined Jun 4, 2014
12,625
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.
 

MaxHeadRoom

Joined Jul 18, 2013
30,654
Better to show in CODE.
Code:
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
 

Thread Starter

pronto

Joined Nov 6, 2017
12
Code:
 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 [code]
 
Top