aqui te dejo un programita que trata sobre la PWM, lo que tienes que hacer a grandes rasgos es cargar un valor al CCPR1L. este programa lo qe hace es incrementar el PWM y decrementarlo , cambiar el sentiro de giro y volver a injcrementar y decrementar el PWM, con lo que se consigue que se varie la velocidad del motor
Definimos el tipo de procesador que vamos a utilizar e incluimos la librería del mismo ;donde se encuentras las definiciones de registros internos..
LIST P=16F873
INCLUDE "P16F873.INC"
;En el siguiente lo bloque, lo que hacemos es etiquetar los registros a utilizar.
AUX EQU 0X20 ;Registro que utilizamos para incrementar el valor
;posteriormente cargado en CCPR1L.
AUX2 EQU 0X21 ;Registro que utilizamos para compararlo con el
;Registro CCPR1L y averiguar si ha llegado al
;Nivel máximo que queremos alcanzar.
CONT1 EQU 0X23
CONT2 EQU 0X24
ORG 0X00 ;Vector de Reset.
;Programa Principal.
INICIO CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF AUX
BSF STATUS,RP0 ;Selecciona banco 1.
CLRF ADCON1 ;Puerta Analógica, Justificación Izda.
CLRF TRISB ;Pueta B, se configura como salida.
MOVLW B'00011111'
MOVWF TRISA ;RA4-RA0 Entradas
MOVLW B'11111011'
MOVWF TRISC ;RC2/CCP1 Salida
BCF STATUS,RP0 ;Selecciona banco 0
;Configuramos el Registro CCP1COM para que actúe en modo PWM con salida por ;RC2/CCP1. Esta configuración se hace cargando una serie de bits definidos por el ;fabricante en el registro..
MOVLW B'00001100'
MOVWF CCP1CON ;Módulo ccp1 en modo
;PWM con salida por RC2/CCP1
;El periodo del PWM para el módulo CCP1 es de 4 ms (pr2*tmr2 preescaler*4*tosc). ;Los 4ms los conseguimos cargando el valor decimal 250 en el PR2.
BSF STATUS,RP0 ;Selecciona página 1
MOVLW .250
MOVWF PR2
BCF STATUS,RP0 ;Selecciona página 0
;El TMR2 lo configuramos para que trabaje con un preescales de 1:16, es decir, ;evoluciona cada 16uS.
MOVLW B'00000110'
MOVWF T2CON ;TMR2 EN ON
;Con las siguientes dos instrucciones lo que hacemos es indicar el sentido de giro del ;motor, en este caso, el sentido que le indicamos es horario.
MOVLW B'00000010'
MOVWF PORTB
;En estas dos instrucciones, como he indicado anteriormente, lo que hacemos es cargar ;el valor 250 en decimal al registro que hemos llamado AUX2, para que pueda ser ;comparado con el CCPR1L.
MOVLW .250
MOVWF AUX2
;Mediante estas llamadas a subrutinas intentamos conseguir: Por un lado, que se valla ;incrementando la velocidad del motor hasta llegar a su máximo 250 (para 4ms), y que ;cuando llegue a su máximo empiece a disminuir su velocidad hasta llegar a pararse ;cuando CCPR1L alcance “0”. Y Por otro lado que cambie el sentido de giro e ;incremente y decremente y así sucesivamente.
CALL INCREMENTA
CALL DECREMENTA
CALL CAMBIO
CALL INCREMENTA
CALL DECREMENTA
GOTO INICIO
;Esta subrutina, es la encargada de conseguir que se incremente la velocidad del ;rotación del motor. En nuestro caso vamos incrementando un registro auxiliar y lo ;cargamos en CCPR1L. Para detectar cuando hemos llegado a 250, lo que hacemos es ;restar un registro auxiliar anteriormente creado (AUX2) el cual tiene cargado el valor ;de 250. Éste valor lo resto cada vez q se incrementa el registro AUX que es que vamos ;incrementando y vamos cargando en CCPR1L, y si el resultado de la resta de AUX – ;AUX2 es igual a “0” el BIT 2 (el BIT Z) del registro STATUS se pone a “1”. Por lo ;tanto cada vez que efectuamos la resta preguntamos por el BIT 2 del registro STATUS, ;si es igual a 1, la instrucción BTFSS salta una línea, sino, sigue a la línea siguiente.
INCREMENTA CALL TEMP
INCF AUX,1
MOVF AUX,0
MOVWF CCPR1L
MOVF AUX,0
SUBWF AUX2,0
BTFSS STATUS,2
GOTO INCREMENTA
RETURN
;La subrutina “Decrementa”, hace exactamente lo inverso a la subrutina “Incrementa” ;pero con algunas diferencias, es decir, decrementamos el registro AUX(el cual ;cargamos a CCPR1L) mediante la instrucción DECFSZ. Ésta instrucción decrementa ;en una unidad, y si el resultado es “0” salta una línea, sino, sigue a la siguiente línea, ;de modo que una vez aprendido como se maneja esta instrucción hacemos lo siguiente: ;vamos decrementado el registro AUX y si el resultado es “0” salta una línea, por lo ;tanto, la velocidad del motor será nula y por lo tanto pasaremos a la rutina cambio de ;giro y posteriormente a las rutinas de Incrementa y Decrementa. Si el resultado de la ;resta no es “0” seguimos decrementando.
DECREMENTA CALL TEMP
DECFSZ AUX,1
GOTO SITIO1
RETURN
SITIO1 MOVF AUX,0
MOVWF CCPR1L
GOTO DECREMENTA
;Con esta subrutina lo que conseguimos es cambiar el sentido de giro del motor. El ;sentido de giro del motor se controla mediante el Driver L293B modificando las ;entradas IN1 y IN2.
CAMBIO MOVLW B'00000001'
MOVWF PORTB ;Motor en on, giro anti-horario
RETURN
;Esta subrutina, es la subrutina de temporización. Cada vez que incrementemos o ;decrementemos debemos llamar a la temporización, para que pueda ser perceptible a ;través del ojo humano el aumento y la disminución de la velocidad del motor. Nostros ;hemos metido unos valores a los contadores auxiliares (CONT1 y CONT2) para una ;temporización de 5 ms (teóricamente), pero debido a que para temporizaciones ;pequeñas este tipo de aplicaciones son muy poco precisas pues conseguimos una ;temporización real de 15 ms aproximadamente debido al tiempo que se tarda en ;ejecutar las instrucciones. (Por ejemplo las instrucciones de salto tardan 2 ciclos de ;reloj).
TEMP MOVLW .200
MOVWF CONT1
IN1 MOVLW .50
MOVWF CONT2
IN DECFSZ CONT2
GOTO IN
DECFSZ CONT1
GOTO IN1
RETURN
END ;Fin del programa fuente