Dudas sobre pic 16f877a

Hola a todos
muchas gracias por aber despejado mis dudas anteriores hoy bengo con una nueva duda
muchas gracias de antemano y disculpen la malisima ortografia
acabo de modificar un pequeño programa que usa el modulo de ccp1 en PWM del pic16f877a todos los puertos como salidas ecepto Rb1 Rb2 como entradas con 2 pulsadores a gnd y dos resistencias referenciadas a 5v de2.7k la señal de entrada es a 0 o gnd. El problema es que solo modifida el ancho cuando pulso el boton el led conectado a Rc2 enciende progresibamente pero cuando dejo de pulsarlo el se apaga y segun el progarama esto no deveria de suceder deveria de quedarse en el mismo estado en el que se suelta el boton

les agradeceria mucho la ayuda

este es el codigo en asm
simula bien tanto en proteus como en mplab

Código:
;************************************************************************************
; Main.asm file generated by New Project wizard
;
; Created:   jue jul 28 2016
; Processor: PIC16F877A
; Compiler:  MPASM (Proteus)
;************************************************************************************

	LIST P=16F877A
#include p16f877a.inc                ; Include register definition file

;************************************************************************************
;                      **** VARIABLES ****
;************************************************************************************

Reg_X EQU 0x20
Reg_gral EQU 0x21
reg1 EQU 0x22
reg2 EQU 0x23
reg3 EQU 0x24
reg4 EQU 0x25
CTL  EQU 0x26
CTH  EQU 0x27

;************************************************************************************
;                      **** DEFINITIONS ****
;************************************************************************************

#DEFINE banc0 bcf STATUS,5
#DEFINE banc1 bsf STATUS,5

;************************************************************************************
;                      **** RESET and INTERRUPT VECTORS ****
;************************************************************************************

Reset org 0x00 ; Aquí comienza el micro.-
	goto INICIO ; Salto a inicio de mi programa.-
	org 0x04 ; Atiendo Interrupcion.-
;	goto ISR
 ; **** Programa Principal ****
	org 0x05
	
;************************************************************************************
;                      **** CODE SEGMENT ****
;************************************************************************************

INICIO
	banc0 ;banco 0
	clrf Reg_X
	clrf PORTA
	clrf PORTB
	clrf PORTC
	clrf PORTD
	clrf PORTE
	banc1 ;Cambio al banco 1
	movlw b\'00000110\'
	movwf ADCON1
	MOVLW b\'00000000\'
	MOVWF TRISD ;Configura todo el puerto D como salida.
	MOVLW b\'00000000\'
	MOVWF TRISC ;Configura todo el puerto B como salida
	movlw b\'00000000\'
	movwf TRISA ; Puero A como salidas
	movlw b\'00000110\' ; PB4-PB7 como entradas
	movwf TRISB ; PB0-PB3 como salidas
	movlw b\'00000000\'
	movwf TRISE
	
	MOVLW 0x1F ;carga periodo
	MOVWF PR2 ;lo establece para el PWM
	banc0 ;Vuelve al banco 0.
	MOVLW 0x04 ;configura Timer 2
	MOVWF T2CON ;preescalador 1/1, habilita Timer 2
	MOVLW .12
	MOVWF CCP1CON
	clrf CCPR1L
	
;************************************************************************************
;************************************************************************************	
	
	
Esp0
	btfss PORTB,1 ;Checa Botón RB0
	CALL incre ;si está presionado incrementa CT
	
Esp1 
	btfss PORTB,2 ;si no se ha presionado Checa botón RB1
	CALL decre ;si está presionado Decrementa CT
	btfss Reg_X,0
	GOTO Esp0

;************************************************************************************
;************************************************************************************

	MOVLW 0xCF ;máscara
	ANDWF CCP1CON,1 ;limpia los dos msbits del CT real
	movf CTL,0 ;máscara
	andlw 0x03 ;limpia los 6 bits altos en CTH
	movwf Reg_gral
	SWAPF Reg_gral,W ;copia los 2 bits bajos de CTH en el nibble alto de W
	IORWF CCP1CON,1 ;pone bits que deben ser 1 en los dos msb del CT real
;**** con esto queda actualizada la parte alta del CT real
	bcf STATUS,C
	rrf CTL,0
	movwf Reg_gral
	bcf STATUS,C
	rrf Reg_gral,0 ;si no se ha presionado obtiene copia de CT parte baja
	MOVWF CCPR1L ;actualiza parte baja del CT real
;**** a continuación actualiza la parte alta del CT real
	CALL pau0 ;pausa para moderar la velocidad de incremento/decremento
	bcf Reg_X,0
	GOTO Esp0 ;repite

;************************************************************************************
;************************************************************************************

incre
	bsf Reg_X,0
	INCF CTL,1 ;incrementa parte baja de la copia de CT
	BTFSS STATUS,Z ;checa si se recicló a cero
	RETURN ;si no, retorna
	INCF CTH,1 ;si se hizo cero incrementa parte alta de CT
	return

;************************************************************************************

decre
	bsf Reg_X,0
	DECF CTL,1 ;decrementa parte baja de la copia de CT
	COMF CTL,W ;copia negado de CTL a W (para ver si CTL=0xFF)
	BTFSS STATUS,Z ;checa si W es cero
	return ;si no, retorna
	
	movf CTH,0
	sublw .0
	btfsc STATUS,Z
	goto Cero
	DECF CTH,1 ;si sí, Decrementa parte alta de CT
	return
	
Cero
	clrf CTL
	return

;************************************************************************************
;************************************************************************************

;** pausa de 50 miliseg. aproximadamente

pau0
	MOVLW 0xFF	; Carga los registros
	MOVWF reg1 ; reg1, reg2 y reg3
; con los valores 10, 20 y 30

tres
	MOVLW 0xF0; respectivamente
	MOVWF reg2
dos MOVLW 0x09
	MOVWF reg3
uno DECFSZ reg3,1 ; Comienza a decrementar
	GOTO uno ; cuando termine
	DECFSZ reg2,1 ; regresará a la siguiente
	GOTO dos ; línea de código
	DECFSZ reg1,1 ; de donde fue llamado
	GOTO tres
	RETURN

;************************************************************************************

pau
	MOVLW 0xFF
	MOVWF reg4
	nop
	DECFSZ reg4,1
	GOTO $-2
	RETURN

;************************************************************************************

      END ...
 
Última edición por un moderador:
¿Qué frecuencia se supone que elegiste para el PWM?
¿A qué frecuencia está funcionando el oscilador?
¿De cuántos milisegundos es la pausa?

Si usas RB1 y RB2 con pulsadores hacia negativo, puedes usar las resistencias pull-up internas.
 
Hola. La frecuencia del PWM es 156.3 KHz y la del pic 20 MHz
Lo de la pausa, no estoy seguro. :confused:



La pausa es de 379.6 milisegundos

Hola otra vez, gracias por leer y responder.
En el datasheet no indica si el CCPR1L hay que actualizarlo constantemente o una vez puesto el dato ya no es necesario actualizarlo, porque el programa hace consulta en el bit 0 del registro Reg_X (btfss Reg_X,0) y este bit sólo cambia tras pulsar en uno de los pulsadores y se borra tras actualizar el ciclo de trabajo.



Con estas modificaciones el programa funciona bien, al parecer ese era el problema, porque acabo de probarlo en protoboard funcionó bien. :unsure:

Desearía que comenten, y si alguien tuvo el mismo problema, que lo comente.
Las líneas que están en rojo son los del problema, porque en base a este bit se hacía la actualización del PWM, por ende, sólo cuando se modificaba el dato a ser cargado en CCPR1L.

Quisiera saber si todos los PIC tienen este problema o es mi código el que está mal.

Muchas gracias por sus sabias respuestas.


PHP:
;************************************************************************************
; Main.asm file generated by New Project wizard
;
; Created:   jue jul 28 2016
; Processor: PIC16F877A
; Compiler:  MPASM (Proteus)
;************************************************************************************

    LIST P=16F877A
#include p16f877a.inc                ; Include register definition file

;************************************************************************************
;                      **** VARIABLES ****
;************************************************************************************

Reg_X EQU 0x20
Reg_gral EQU 0x21
reg1 EQU 0x22
reg2 EQU 0x23
reg3 EQU 0x24
reg4 EQU 0x25
CTL  EQU 0x26
CTH  EQU 0x27

;************************************************************************************
;                      **** DEFINITIONS ****
;************************************************************************************

#DEFINE banc0 bcf STATUS,5
#DEFINE banc1 bsf STATUS,5

;************************************************************************************
;                      **** RESET and INTERRUPT VECTORS ****
;************************************************************************************

Reset org 0x00 ; Aquí comienza el micro.-
    goto INICIO ; Salto a inicio de mi programa.-
    org 0x04 ; Atiendo Interrupcion.-
;    goto ISR
 ; **** Programa Principal ****
    org 0x05
    
;************************************************************************************
;                      **** CODE SEGMENT ****
;************************************************************************************

INICIO
    banc0 ;banco 0
    clrf Reg_X
    clrf PORTA
    clrf PORTB
    clrf PORTC
    clrf PORTD
    clrf PORTE
    banc1 ;Cambio al banco 1
    movlw b'00000110'
    movwf ADCON1
    MOVLW b'00000000'
    MOVWF TRISD ;Configura todo el puerto D como salida.
    MOVLW b'00000000'
    MOVWF TRISC ;Configura todo el puerto B como salida
    movlw b'00000000'
    movwf TRISA ; Puero A como salidas
    movlw b'00000110' ; PB4-PB7 como entradas
    movwf TRISB ; PB0-PB3 como salidas
    movlw b'00000000'
    movwf TRISE
    
    MOVLW 0x1F ;carga periodo
    MOVWF PR2 ;lo establece para el PWM
    banc0 ;Vuelve al banco 0.
    MOVLW 0x04 ;configura Timer 2
    MOVWF T2CON ;preescalador 1/1, habilita Timer 2
    MOVLW .12
    MOVWF CCP1CON
    clrf CCPR1L
    
;************************************************************************************
;************************************************************************************    
    
    
Esp0
    btfss PORTB,1 ;Checa Botón RB0
    CALL incre ;si está presionado incrementa CT
    
Esp1 
    btfss PORTB,2 ;si no se ha presionado Checa botón RB1
    CALL decre ;si está presionado Decrementa CT
;    btfss Reg_X,0 omiti las consultas al bit
;    GOTO Esp0 para que el PWM se actualise constatemente

;************************************************************************************
;************************************************************************************

    MOVLW 0xCF ;máscara
    ANDWF CCP1CON,1 ;limpia los dos msbits del CT real
    movf CTL,0 ;máscara
    andlw 0x03 ;limpia los 6 bits altos en CTH
    movwf Reg_gral
    SWAPF Reg_gral,W ;copia los 2 bits bajos de CTH en el nibble alto de W
    IORWF CCP1CON,1 ;pone bits que deben ser 1 en los dos msb del CT real
;**** con esto queda actualizada la parte alta del CT real
    bcf STATUS,C
    rrf CTL,0
    movwf Reg_gral
    bcf STATUS,C
    rrf Reg_gral,0 ;si no se ha presionado obtiene copia de CT parte baja
    MOVWF CCPR1L ;actualiza parte baja del CT real
;**** a continuación actualiza la parte alta del CT real
    CALL pau0 ;pausa para moderar la velocidad de incremento/decremento
    btfss PORTB,1
    goto $-1
    btfss PORTB,2
    goto $-3
    bcf Reg_X,0
    GOTO Esp0 ;repite

;************************************************************************************
;************************************************************************************

incre
    bsf Reg_X,0
    INCF CTL,1 ;incrementa parte baja de la copia de CT

    BTFSS STATUS,Z ;checa si se recicló a cero
    RETURN ;si no, retorna
    INCF CTH,1 ;si se hizo cero incrementa parte alta de CT
    return

;************************************************************************************

decre
    bsf Reg_X,0
    DECF CTL,1 ;decrementa parte baja de la copia de CT
    COMF CTL,W ;copia negado de CTL a W (para ver si CTL=0xFF)
    BTFSS STATUS,Z ;checa si W es cero
    return ;si no, retorna
    
    movf CTH,0
    sublw .0
    btfsc STATUS,Z
    goto Cero
    DECF CTH,1 ;si sí, Decrementa parte alta de CT
    return
    
Cero
    clrf CTL
    return

;************************************************************************************
;************************************************************************************

;** pausa de 50 miliseg. aproximadamente

pau0
    MOVLW 0xFF    ; Carga los registros
    MOVWF reg1 ; reg1, reg2 y reg3
; con los valores 10, 20 y 30

tres
    MOVLW 0xF0; respectivamente
    MOVWF reg2
dos MOVLW 0x09
    MOVWF reg3
uno DECFSZ reg3,1 ; Comienza a decrementar
    GOTO uno ; cuando termine
    DECFSZ reg2,1 ; regresará a la siguiente
    GOTO dos ; línea de código
    DECFSZ reg1,1 ; de donde fue llamado
    GOTO tres
    RETURN

;************************************************************************************

pau
    MOVLW 0xFF
    MOVWF reg4
    nop
    DECFSZ reg4,1
    GOTO $-2
    RETURN

;************************************************************************************

      END
 
Última edición por un moderador:
muchas gracias por responder despues de hacer de todo cambie el micro le ise toda clase de pruebas al parecer el modulo ccp esta dañado por que lo demas funciona bien... y tambien por que el micro nuevo esta con el mismo codigo y funciona muy bien (el primer codigo)
 
Atrás
Arriba