Tenho uma rotina de PWM eficaz em ASM que se eu apenas testá-la num looping no programa,ela gera os sinais como o esperado,mas se eu colocá-la dentro de uma interrupção (INT0) na borda de subida de um detector zero cross (120HZ) a rotina fica totalmente fora do esperado.
Estou usando o Proteus para simular.
Seria assim,a cada transição de zero de uma tensão AC(110v)é disparado a rotina que gera as saidas no PORT A.
Se eu fizer apenas um teste,tipo,a interrupção é acionada,elevo RA0 a 1 e depois a 0, a cada interrupção,o sinal no osciloscopio corresponde corretamente,mas se usa a rotina dentro da interrupção,não funciona como o esperado.
Ja tentei usando C18 e ASM,pois achei que a interrupção em C não estava correta mas o resultado é o mesmo.
Segue exemplo no proteus.
A cor amarela é o sinal do detetor zero cross.
Vermelho é a rede AC 60 Hz.
Azul é o primeiro canal PWM.
Verde é o segundo canal PWM.
O exemplo em C é praticamente o mesmo,inclusive a rotina multipla de PWM está em ASM e é totalmente funcional se estiver em LOOPING no programa,eu ja usaei para 8 Leds com controle perfeito do brilho.
Se for descomentado as 4 primeiras linhas da rotina MULTI_PWM,voces poderão ver qual seria o resultado esperado.
- Código: Selecionar todos
;
;
#INCLUDE <P18F2550.INC>
CONFIG PLLDIV = 1
CONFIG CPUDIV = OSC1_PLL2
CONFIG USBDIV = 2
CONFIG FOSC = XTPLL_XT
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRT = OFF
;................................................................................................................
CBLOCK 0X000
PWM0
PWM1
PWM2
PWM3
PWM4
PWM5
PWM6
PWM7
PWM0_CNTR
PWM1_CNTR
PWM2_CNTR
PWM3_CNTR
PWM4_CNTR
PWM5_CNTR
PWM6_CNTR
PWM7_CNTR
ESTADO_PWM2
SOBE_BORDA
ENDC
#DEFINE POINTER1 .2
;........................................................
ORG 0
GOTO START
;-------------------------------
ORG 0X08 ;ALTA PRIORIDADE
BTFSS INTCON,1
RETFIE
BCF INTCON,1
GOTO MULTI_PWM ;SALTA PARA A FUNCAO DE INTERRUPCAO
GOTO $
ORG 0X18 ;BAIXA PRIORIDADE
GOTO $
;-------------------------------
START:
CLRF PORTB
MOVLW B'11000001'
MOVWF TRISB
MOVLW 0X00
MOVWF TRISA
MOVLW .1
MOVWF PWM0
MOVLW 0X01
MOVWF PWM1
MOVLW 0X01
MOVWF PWM2
MOVLW 0X01
MOVWF PWM3
MOVLW 0X01
MOVWF PWM4
MOVLW 0X01
MOVWF PWM5
MOVLW 0X01
MOVWF PWM6
MOVLW 0X01
MOVWF PWM6
MOVLW POINTER1
MOVWF SOBE_BORDA
MOVLW 0X0F
MOVWF ADCON1
MOVLW 0X06
MOVWF CMCON
BCF INTCON,INT0IF
BSF INTCON,INT0IE
BSF INTCON2,INTEDG0
BSF RCON,IPEN
BSF INTCON,GIE
; BCF INTCON,GIE
XP:
BTFSC PORTB,7
BRA XP
INCF PWM0,F
XP2:
BTFSS PORTB,7
BRA XP2
GOTO XP
;.................................................
MULTI_PWM:
; BSF PORTA,0
; NOP
; BCF PORTA,0
; RETFIE
;.................................................
DECFSZ SOBE_BORDA,1,BANKED
BRA PWM_ATUALIZA2
MOVLW POINTER1
MOVWF SOBE_BORDA,BANKED
MOVFF PWM0,PWM0_CNTR
MOVFF PWM1,PWM1_CNTR
MOVFF PWM2,PWM2_CNTR
MOVFF PWM3,PWM3_CNTR
MOVFF PWM4,PWM4_CNTR
MOVFF PWM5,PWM5_CNTR
MOVFF PWM6,PWM6_CNTR
MOVFF PWM7,PWM7_CNTR
MOVLW 0XFF
GOTO PWM_FIM2
PWM_ATUALIZA2:
MOVLW 0x00
DECFSZ PWM0_CNTR,1,BANKED
IORLW B'00000001'
DECFSZ PWM1_CNTR,1,BANKED
IORLW B'00000010'
DECFSZ PWM2_CNTR,1,BANKED
IORLW B'00000100'
DECFSZ PWM3_CNTR,1,BANKED
IORLW B'00001000'
DECFSZ PWM4_CNTR,1,BANKED
IORLW B'00010000'
DECFSZ PWM5_CNTR,1,BANKED
IORLW B'00100000'
DECFSZ PWM6_CNTR,1,BANKED
IORLW B'01000000'
DECFSZ PWM7_CNTR,1,BANKED
IORLW B'10000000'
ANDWF ESTADO_PWM2,0,BANKED
PWM_FIM2:
MOVWF PORTA, ACCESS
MOVWF ESTADO_PWM2,BANKED
RETFIE FAST
;...........................................
END
http://www.4shared.com/rar/pwWssG_s/PWM_8.html
Gostaria muito de entender onde estou errando...
PS:Quero ressaltar que o problema não é na rotina que gera o PWM,a mesno que exista uma rotina de multiplo PWM mais eficaz,oque eu acho pouco provável.