Exactamente, la salida PORTC,2 que es la salida del PWM no varia cuando deberia variar....
A ver si puedo explicar un poco mejor porque talves por la tabla no me entiendas....
Utilizo una resolución en el PWM de 8 bits (256 niveles de tensión). Lo que intento hacer es que estos niveles (salida PWM) varíen en el tiempo para describir una señal seno.
Primero elijo que resolución en frecuencia deseo darle a la "salida seno", es decir cuantos niveles de tensión deseas tener en un ciclo de la senoide, esto lo hago cada 5,625 grados eléctricos (el ciclo completo es 2pi=360 grados) por lo cual tendre 64 niveles distintos.
Para realizar lo anterior debo tener una salida PWM (obvio) y un timer que es el que te actualizará el valor del duty cycle de la salida.
Entonces calculo el tiempo en el que el timer debe recalcular el duty cycle de la salida.
Lla frecuencia de la seno es 60Hz por lo tanto:
el período es ------>60 Hz = (1/60)seg = 16,67 ms
esto es lo que dura un período de la seno, como lo actualizamos cada 5,625 grados tendremos 64 niveles y cada uno durará:
Tiempo del timer ----> Tt = período / 64 = 16,67 / 64 = 260,468 Useg
Estos 260 Useg es cada cuanto debes recalcular el duty cycle del PWM.
Ahora bien, para calcular este duty cycle habría que calcular el seno de 5,625 grados, el de 11,25... hasta el de 360 grados y nuevamente el seno de 5,625.....y asi eternamente, esto es muy complejo de realizar con un microcontrolador de 8 bits. Lo que se hace es colocar los 64 resultados en una tabla, e irlos leyendo con la frecuencia que te da el timer que acabamos de calcular.
Luego los valores de la tabla serán:
para 0o = ((seno 0o)*127)+127 = 127
para 5,625o = ((seno 5,625o)*127)+127 = 139,44
para 11,25o = ((seno 11,25o)*127)+127 = 151,77
.
.
para 90o = ((seno 90o)*127)+127 = 254
.
.
para 180o = ((seno 270o)*127)+127 = 127
.
.
para 270o = ((seno 270o)*127)+127 = 0
.
.
para 360o = ((seno 360o)*127)+127 = 127
Estos valores son los que coloco en el PWM para ajustar el duty cycle, pero los transformo en hexadecimal
Entonces leo esta tabla e incremento el puntero de lectura (cont_val), al llegar al final debes comenzar nuevamente.
Aqui estoy algo confundido ya q no se si tengo q utilizar la bandera del Timer 2 o algo mas?? solamente ocupo la bandera del Timer 0.... la verdad que tambien estoy un poco oxidado en programacion y por eso queria ver si alguien me podia colaborar a ver en que me estoy equivocando o que me esta faltando.
Aqui el codigo en 16f871, a ver si ahi me pedes ayudar
list p=16F871
#include "p16f871.inc"
;Auxiliares
cont_val = 0x01
aux1 = 0X02
;====================
org 0x00
goto inicio
org 0x04
goto INT ;rutina de atencion a IT de baja prioridad
;==================================================================================================
;Configuarción de hardware y condiciones iniciales de variables
;--------------------------------------------------------------------------------------------------
inicio
;PORTC
movlw b'00100000' ;Pasa al Banco1
movwf STATUS
bcf TRISC,2 ;salida del PWM
;==================================================================================================
;Configuración del periodo de PWM y del registro CCP1CON
movlw 0x0F
movwf CCP1CON; Configura en modo PWM
movlw d'81'
movwf PR2 ;Frecuencia de PWM = ; PR2 = [(Fosc*Tpwm)/(Prescaler*4)]-1 = [(20E6*(260,468E-6))/(16*4)]-1= 81
;==================================================================================================
;Configuración del TIMER 0
;--------------------------------------------------------------------------------------------------
;TOverflow max apagado
movlw b'00000010' ;configura el prescaler 1:8, y la int por flanco de bajada (bit6)
movwf OPTION_REG
;==================================================================================================
;Configuración del TIMER 2
;--------------------------------------------------------------------------------------------------
;Timer 2: overflow max. apagado
movlw b'00000011' ; cargado con un pre-escaler de 16 y post-escaler de 1:1
movwf T2CON
bsf PIE1,TMR2IE
;==================================================================================================
;Interrupciones
bcf INTCON,GIE ;Deshabilitadas todas las interrupciones
bsf INTCON,PEIE ;Habilitadas de IT perifericas
bsf INTCON,INTE ;Habilita IT externa en PORTB0
;Int_timer 0
bsf INTCON,T0IE ;Habilita IT del TMR0
bsf INTCON,TMR0IE ;Interrupción de desbordamiento del Temporizador 0 habilitada
bcf OPTION_REG,INTEDG ;La interrupción externa en Rb0 se dispara por flanco de bajada.
;==================================================================================================
;Condiciones iniciales
movlw b'00000000' ;configura el prescaler 1:8, y la int por flanco de bajada (bit6)
movwf STATUS ;BSR=0 ubicación en el banco 0
;==========================================
;arranque
bsf T2CON,TMR2ON ;arranca timer 2
bsf INTCON,GIE ;arrancan ITs y TMR0
;==========================================
;Lazo principal
again goto again
;==========================================
;Interrupción
;-----------------------------------------------------------------------------
INT ;Pregunta por banderas de IT
btfss INTCON,INTF
goto a
goto int_ext
a btfss INTCON,T0IF ;¿int timer 0?
goto volver
call ini_tabla
movlw d'64'
movwf aux1
tab decfsz aux1,1
goto mover
clrf cont_val
goto volver
int_ext
bcf PORTC,2
bcf INTCON,INTF
retfie
mover incf cont_val,1
pageselw tabla
movf cont_val,w
call tabla
movwf CCPR1L
goto tab
volver bcf INTCON,T0IF
retfie
;========= Inicia la TAbla o ACCESA============
ini_tabla
movlw 0
clrf cont_val
return
;==============================================================
;Demoras
;--------------------------------------------------------------------------------------------------
;Tabla de valores de la onda!!!!
org 0x600
tabla
ADDWF PCL,1 ; W = offset
RETLW 0X7F ; Empieza la tabla
RETLW 0X8B ;
RETLW 0X97 ;
RETLW 0XA3 ;
RETLW 0XAF ;
RETLW 0XBA ;
RETLW 0XC5 ;
RETLW 0XCF ;
RETLW 0XD8 ;
RETLW 0XE1 ;
RETLW 0XE8 ;
RETLW 0XEF ;
RETLW 0XF4 ;
RETLW 0XF8 ;
RETLW 0XFB ;
RETLW 0XFD ;
RETLW 0XFE ;
RETLW 0XFD ;
RETLW 0XFB ;
RETLW 0XF8 ;
RETLW 0XF4 ;
RETLW 0XEF ;
RETLW 0XE8 ;
RETLW 0XE1 ;
RETLW 0XD8 ;
RETLW 0XCF ;
RETLW 0XC5 ;
RETLW 0XBA ;
RETLW 0XAF ;
RETLW 0XA3 ;
RETLW 0X97 ;
RETLW 0X8B ;
RETLW 0X7F ;
RETLW 0X72 ;
RETLW 0X66 ;
RETLW 0X5A ;
RETLW 0X4E ;
RETLW 0X43 ;
RETLW 0X38 ;
RETLW 0X2E ;
RETLW 0X25 ;
RETLW 0X1C ;
RETLW 0X15 ;
RETLW 0XE ;
RETLW 0X9 ;
RETLW 0X5 ;
RETLW 0X2 ;
RETLW 0X1 ;
RETLW 0X0 ;
RETLW 0X1 ;
RETLW 0X2 ;
RETLW 0X5 ;
RETLW 0X9 ;
RETLW 0XE ;
RETLW 0X15 ;
RETLW 0X1C ;
RETLW 0X25 ;
RETLW 0X2E ;
RETLW 0X38 ;
RETLW 0X43 ;
RETLW 0X4E ;
RETLW 0X5A ;
RETLW 0X66 ;
RETLW 0X72 ;
RETLW 0X7E ;
;--------------------------------------------------------------------------------------------------
end
Saludos, Pedro.
No entiendo lo que estas haciendo, pero bueno es que la serie 18f no la controlo mucho, lo que si veo es que efectivamente la salida PORTC,2 salida del PWM no varia.
Pon el que tienes para el 16f871, a ver si con ese me entero algo mas. Nunca hice esto para monofasica, pero te explico como creo que es:
Para generar el PWM de 6KHz cada 167uS tienes que poner a 1 el PORTC,2 y ponerlo a 0 cuando acaba su DUTTY correspondiente que sera diferente en cada PWM primero sera de 0 (este sera el paso por 0 de la onda alterna) no hay que detectarlo porque eres tu quien lo hace, el segundo PWM tendra un DUTTY del 10% es decir 16 o 17us (asi seria una onda de 10 niveles, que deben ser multiplos de 3, pero bueno...) el tercero del 20% y asi sucesivamente hasta llegar al 100%, entonces empezara a bajar, primero al 90%, despues al 80% ..........del 10% y de 0, que sera el cruce por 0 nuevamente y e haras lo mismo pero con sentido inverso de corriente para hacer la semionda negativa. Tendras que hacer los calculos para que con todas estas te salga una frecuencia de 60Hz de alterna. Bueno esta es la manera de hacerlo que yo se, no se si tu lo haces asi o de otra manera, que habra otras maneras de hacerlo, supongo.
No se que hard esta usando, supongo que un puente H, tendras que poner bobinas para que conviertan los PWMs en niveles de tension, si es para alimentar un motor las bobinas del motor ya te hacen esta funcion, pero si es para alimentar una vivienda...