Necessito arrumar uma saída PWM que quando esta em 100% ocorre um erro, segue imagem com o erro:
http://i60.tinypic.com/2zjmkn6.jpg
Sendo que o sinal deveria ficar constantemente em alto.
O código em assembly é:
- Código: Selecionar todos
;------------------------------------------------------------------------------
; PWM ASSEMBLY
;------------------------------------------------------------------------------
; AUTOR:
; DATA:
; CONTROLE DE REVISÕES:
;------------------------------------------------------------------------------
#INCLUDE <P16F877A.INC>
;------------------------------------------------------------------------------
; BITS DE CONFIGURAÇÃO
;------------------------------------------------------------------------------
; CONFIG
; __config 0xFF79
__CONFIG _FOSC_XT & _WDTE_ON & _PWRTE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
; FOSC - Seleção tipo oscilador.
; WDTE - Watchdog timer.
; PWRTE - Power on timer (72ms após energização).
; BOREN - Brown-out enable, proteção contra baixa tensão.
; LVP - Low voltage programming.
; CPD - Code protect da EEPROM.
; WRT - Write protection da memória flash.
; CP - Code protect memória de programa.
;------------------------------------------------------------------------------
; PAGINAÇÃO DE MEMÓRIA (MACROS)
;------------------------------------------------------------------------------
BANK0 MACRO
BCF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK1 MACRO
BSF STATUS,RP0
BCF STATUS,RP1
ENDM
BANK2 MACRO
BCF STATUS,RP0
BSF STATUS,RP1
ENDM
BANK3 MACRO
BSF STATUS,RP0
BSF STATUS,RP1
ENDM
;------------------------------------------------------------------------------
; VARIÁVEIS
;------------------------------------------------------------------------------
CBLOCK 0X20
FILTRO_BOTOES
TEMPO1
TEMPO0
ENDC
;------------------------------------------------------------------------------
; CONSTANTES
;------------------------------------------------------------------------------
; CONSTANTES UTILIZADAS PELO SISTEMA
FILTRO_TECLA EQU .200
;------------------------------------------------------------------------------
; ENTRADAS
;------------------------------------------------------------------------------
; PINOS QUE SERÃO UTILIZADOS COMO ENTRADA
#DEFINE BOTAO_0 PORTB,0 ;ESTADO BOTÃO 0
;1 -> LIBERADO
;0 -> PRESSIONADO
#DEFINE BOTAO_1 PORTB,1 ;ESTADO BOTÃO 1
;1 -> LIBERADO
;0 -> PRESSIONADO
#DEFINE BOTAO_2 PORTB,2 ;ESTADO BOTÃO 2
;1 -> LIBERADO
;0 -> PRESSIONADO
#DEFINE BOTAO_3 PORTB,3 ;ESTADO BOTÃO 3
;1 -> LIBERADO
;0 -> PRESSIONADO
;------------------------------------------------------------------------------
; SAÍDAS
;------------------------------------------------------------------------------
; PINOS QUE SERÃO UTILIZADOS COMO SAÍDA
#DEFINE DISPLAY PORTD ;BARRAMENTO DE DADOS DO DISPLAY
#DEFINE RS PORTE,0 ;INDICA P/ O DISPLAY UM DADO OU COMANDO
;1 -> DADO
;0 -> COMANDO
#DEFINE ENABLE PORTE,1 ;SINAL DE ENABLE P/ DISPLAY
;ATIVO NA BORDA DE DESCIDA
#DEFINE VENTILADOR PORTC,1 ;SAÍDA P/ O VENTILADOR
;1 -> VENTILADOR LIGADO
;0 -> VENTILADOR DESLIGADO
;------------------------------------------------------------------------------
; VETOR DE RESET DO MICROCONTROLADOR
;------------------------------------------------------------------------------
ORG 0X0000 ;ENDEREÇO DO VETOR DE RESET
GOTO INICIO ;PULA PARA CONFIG DEVIDO A REGIÃO
;DESTINADA AS ROTINAS SEGUINTES
;------------------------------------------------------------------------------
; ROTINA DE DELAY (DE 1mS ATÉ 256mS)
;------------------------------------------------------------------------------
;ESTÁ É UMA ROTINA DE DELAY VARIÁVEL, COM DURAÇÃO DE 1mS X O VALOR PASSADO EM
;WORK
DELAY_MS
MOVWF TEMPO1 ;CARREGA TEMPO1(UNIDADE DE mS)
MOVLW .250
MOVWF TEMPO0 ;CARREGA TEMPO0 (P/CONTAR 1mS)
CLRWDT ;LIMPA WDT (PERDE TEMPO)
DECFSZ TEMPO0,F ;FIM DE TEMPO0?
GOTO $-2 ;NÃO - VOLTA 2 INSTRUÇÕES
;SIM - PASSOU-SE 1mS
DECFSZ TEMPO1,F ;FIM DE TEMPO1?
GOTO $-6 ;NÃO - VOLTA 6 INSTRUÇÕES
;SIM
RETURN ;RETORNA
;------------------------------------------------------------------------------
; ROTINA DE ESCRITA DE UM CARACTER NO DISPLAY
;------------------------------------------------------------------------------
;ESTA ROTINA ENVIA UM CARACTER PARA O MÓDULO DE LCD. O CARACTER A SER ESCRITO
;DEVE SER COLOCADO EM WORK (W) ANTES DE CHAMAR A ROTINA.
ESCREVE
MOVWF DISPLAY ;ATUALIZA DISPLAY (PORTD)
NOP ;PERDE 1US PARA ESTABILIZAÇÃO
BSF ENABLE ;ENVIA UM PULSO DE ENABLE AO DISPLAY
GOTO $+1
BCF ENABLE
MOVLW .1
CALL DELAY_MS ;DELAY DE 1MS
RETURN ;RETORNA
;------------------------------------------------------------------------------
; CONFIGURAÇÕES INICIAIS DE HARDWARE E SOFTWARE
;------------------------------------------------------------------------------
;NESTA ROTINA SÃO INICIALIZADAS AS PORTAS DE I/O DO MICROCONTROLADOR E AS
;CONFIGURAÇÕES DOS REGISTRADORES ESPECIAIS (SFR). A ROTINA INICIALIZA A MÁQUINA
;E AGUARDA O ESTOURO DO WDT.
INICIO
CLRF PORTA ;GARANTE TODAS AS SAÍDAS EM ZERO
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
BANK1 ;SELECIONA BANCO 1 DA RAM
MOVLW B'11111111'
MOVWF TRISA ;CONFIGURA I/O DO PORTA
MOVLW B'11111111'
MOVWF TRISB ;CONGIGURA I/O DO PORTB
MOVLW B'11111101'
MOVWF TRISC ;CONFIGURA I/O DO PORTC
MOVLW B'00000000'
MOVWF TRISD ;CONFIGURA I/O DO PORTD
MOVLW B'00000100'
MOVWF TRISE ;CONFIGURA I/O DO PORTE
MOVLW B'11011111'
MOVWF OPTION_REG ;CONFIGURA OPTIONS
;PULL-UPS DESABILITADOS
;INTER. NA BORDA DE SUBIDA DO RB0
;TIMER0 INCREM. PELO CICLO DE MÁQUINA
;WDT - 1:128
;TIMER - 1:1
MOVLW B'00000000'
MOVWF INTCON ;CONFIGURA INTERRUPÇÕES
;DESABILITA TODAS AS INTERRUPÇÕES
MOVLW B'00000111'
MOVWF ADCON1 ;CONFIGURA CONVERSOR A/D
;CONFIGURA PORTA E PORTE COMO I/O DIGITAL
MOVLW .255
MOVWF PR2 ;CONFIGURA PERÍODO DO PWM
;T=((PR2)+1)*4*TOSC*TMR2PRESCALE
;T=((255)+1)*4*250ns*16
;T=4,096ms -> 244,14 Hz
BANK0 ;SELECIONA BANCO 0 DA RAM
MOVLW B'00000111'
MOVWF T2CON ;CONFIGURA TMR2
;TIMER 2 LIGADO
;PRESCALE 1:16
;POSTSCALE 1:1
MOVLW B'00001111'
MOVWF CCP2CON ;CONFIGURA CCP2CON PARA PWM
;(PINO RC1)
CLRF CCPR2L ;INICIA COM DUTY CYCLE EM ZERO
;------------------------------------------------------------------------------
; INICIALIZAÇÃO DA RAM
;------------------------------------------------------------------------------
; ESTA ROTINA IRÁ LIMPAR TODA A RAM DO BANCO 0, INDO DE 0X20 A 0X7F.
; EM SEGUIDA, AS VARIÁVEIS DE RAM DO PROGRAMA SÃO INICIALIZADAS.
MOVLW 0X20
MOVWF FSR ;APONTA O ENDEREÇAMENTO INDIRETO PARA
;A PRIMEIRA POSIÇÃO DA RAM
LIMPA_RAM
CLRF INDF ;LIMPA POSIÇÃO
INCF FSR,F ;INCREMENTA O PONTEIRO P/ A PRÓX. POS.
MOVF FSR,W
XORLW 0X80 ;COMPARA O PONTEIRO COM A ÚLTIMA POS. +1
BTFSS STATUS,Z ;JÁ LIMPOU TODAS AS POSIÇÕES?
GOTO LIMPA_RAM ;NÃO - LIMPA A PRÓXIMA POSIÇÃO
;SIM
;------------------------------------------------------------------------------
; CONFIGURAÇÕES INICIAIS DO DISPLAY
;------------------------------------------------------------------------------
; ESTA ROTINA INCIALIZA O DISPLAY P/ COMUNICAÇÃO DE 8 VIAS, DISPLAY PARA 2
; LINHAS, CURSOR APAGADO E DESLOCAMENTO DO CURSOR À DIREITA.
INICIALIZACAO_DISPLAY
BCF RS ;SELECIONA O DISPLAY P/ COMANDOS
MOVLW 0X30 ;ESCREVE COMANDO 0X30 PARA
CALL ESCREVE ;INICIALIZAÇÃO
MOVLW .3
CALL DELAY_MS ;DELAY DE 3MS (EXIGIDO PELO DISPLAY)
MOVLW 0X30 ;ESCREVE COMANDO 0X30 PARA
CALL ESCREVE ;INICIALIZAÇÃO
MOVLW 0X30 ;ESCREVE COMANDO 0X30
CALL ESCREVE ;INICIALIZAÇÃO
MOVLW B'00111000' ;ESCREVE COMANDO PARA
CALL ESCREVE ;INTERFACE DE 8 VIAS DE DADOS
MOVLW B'00000001' ;ESCREVE COMANDO PARA
CALL ESCREVE ;LIMPAR TODO DISPLAY
MOVLW .1
CALL DELAY_MS ;DELAY DE 1MS
MOVLW B'00001100' ;ESCREVE COMANDO PARA
CALL ESCREVE ;LIGAR O DISPLAY SEM CURSOR
MOVLW B'00000110' ;ESCREVE COMANDO PARA INCREM.
CALL ESCREVE ;AUTOMÁTICO À DIREITA
;------------------------------------------------------------------------------
; ROTINA DE ESCRITA DA TELA PRINCIPAL
;------------------------------------------------------------------------------
; ESTA ROTINA ESCREVE A TELA PRINCIPAL DO PROGRAMA, COM AS FRASES:
; LINHA 1 - "MICROCONTROLADORES"
; LINHA 2 - "PWM: XX% "
MOSTRA_TELA_PRINCIPAL
MOVLW 0X80 ;COMANDO PARA POSICIONAR O CURSOR
CALL ESCREVE ;LINHA 0/ COLUNA 1
BSF RS ;SELECIONA O DISPLAY P/ DADOS
;COMANDOS PARA ESCREVER AS
;LETRAS DE "TRABALHO-1"
MOVLW 'T'
CALL ESCREVE
MOVLW 'R'
CALL ESCREVE
MOVLW 'A'
CALL ESCREVE
MOVLW 'B'
CALL ESCREVE
MOVLW 'A'
CALL ESCREVE
MOVLW 'L'
CALL ESCREVE
MOVLW 'H'
CALL ESCREVE
MOVLW '0'
CALL ESCREVE
MOVLW '-'
CALL ESCREVE
MOVLW '1'
CALL ESCREVE
BCF RS ;SELECIONA O DISPLAY P/ COMANDOS
MOVLW 0XC3 ;COMANDO PARA POSICIONAR O CURSOR
CALL ESCREVE ;LINHA 1/COLUNA 3
BSF RS ;SELECIONA O DISPLAY P/DADOS
;COMANDOS PARA ESCREVER AS
; LETRAS DE "PWM: OFF"
MOVLW 'P'
CALL ESCREVE
MOVLW 'W'
CALL ESCREVE
MOVLW 'M'
CALL ESCREVE
MOVLW ':'
CALL ESCREVE
MOVLW ' '
CALL ESCREVE
MOVLW ' '
CALL ESCREVE
MOVLW 'O'
CALL ESCREVE
MOVWF 'F'
CALL ESCREVE
MOVWF 'F'
CALL ESCREVE
;------------------------------------------------------------------------------
; VARREDURA DOS BOTÕES
;------------------------------------------------------------------------------
; ESTA ROTINA VERIFICA SE ALGUM BOTÃO ESTÁ PRESSIONADO E CASO AFIRMATIVO
; DESVIA PARA O TRATAMENTO DO MESMO.
VARRE
CLRWDT ;LIMPA WATCHDOG TIMER
; VERIFICA ALGUM BOTÃO PRESSIONADO
VARRE_BOTOES
BTFSS BOTAO_0 ;O BOTÃO 0 ESTA PRESSIONADO?
GOTO TRATA_BOTAO_0 ;SIM - PULA P/ TRATA_BOTAO_O
;NÃO
BTFSS BOTAO_1 ;O BOTÃO 1 ESTA PRESSIONADO?
GOTO TRATA_BOTAO_1 ;SIM - PULA P/ TRATA_BOTAO_1
;NÃO
BTFSS BOTAO_2 ;O BOTÃO 2 ESTA PRESSIONADO?
GOTO TRATA_BOTAO_2 ;SIM - PULA P/ TRATA_BOTAO_2
;NÃO
BTFSS BOTAO_3 ;O BOTÃO 3 ESTA PRESSIONADO:
GOTO TRATA_BOTAO_3 ;SIM - PULA P/ TRATA_BOTAO_3
;NÃO
; FITRO P/ EVITAR RUIDOS
MOVLW FILTRO_TECLA ;CARREGA O VALOR DE FILTRO_TECLA
MOVWF FILTRO_BOTOES ;SALVA EM FILTRO_BOTOES
;RECARREGA FILTRO P/ EVITAR RUIDOS
; NOS BOTÕES
GOTO VARRE ;VOLTA PARA VARRER TECLADO
;------------------------------------------------------------------------------
; TRATAMENTO DOS BOTÕES
;------------------------------------------------------------------------------
; NESTE TRECHO DO PROGRAMA ESTÃO TODOS OS TRATAMENTOS DOS BOTÕES
; TRATAMENTO DO BOTÃO 0
TRATA_BOTAO_0
MOVF FILTRO_BOTOES,F
BTFSC STATUS,Z ;FILTRO JÁ IGUAL A ZERO?
;(FUNÇÃO JA FOI EXECUTADA?)
GOTO VARRE ;SIM - VOLTA P/ VARREDURA DO TECLADO
;NÃO
DECFSZ FILTRO_BOTOES,F ;FIM DO FILTRO?(RUIDO?)
GOTO VARRE ;NÃO - VOLTA P/ VARRE
;SIM - BOTÃO PRESSIONADO
CLRF CCPR2L ;ZERA CCPR2L
BCF CCP2CON,5 ;ZERA OS BITS 5 E 4
BCF CCP2CON,4 ; (LSB DO DUTY CYCLE)
;Tp=CCPR2L:CCP2CON<5,4>*TOSC*TMR2PRESCALE
;Tp=0*250ns*16
;Tp=0;
;PWM -> DUTY CYCLE = 0% -> OFF
BCF RS ;SELECIONA O DISPLAY P/ COMANDOS
MOVLW 0XC8 ;COMANDO PARA POSICIONAR O CURSOR
CALL ESCREVE ;LINHA 1 / COLUNA 8
BSF RS ;SELECIONA O DISPLAY P/DADOS
;COMANDOS PARA ESCREVER AS
;LETRAS DE "OFF"
MOVLW ' '
CALL ESCREVE
MOVLW 'O'
CALL ESCREVE
MOVLW 'F'
CALL ESCREVE
MOVLW 'F'
CALL ESCREVE
GOTO VARRE ;VOLTA P/ VARREDURA DOS BOTÕES
; TRATAMENTO DO BOTÃO 1
TRATA_BOTAO_1
MOVF FILTRO_BOTOES,F
BTFSC STATUS,Z ;FILTRO JÁ IGUAL A ZERO?
;(FUNÇÃO JA FOI EXECUTADA?
GOTO VARRE ; SIM - VOLTA P/ VARREDURA DO TECLADO
;NÃO
DECFSZ FILTRO_BOTOES,F ;FIM DO FILTRO? (RUIDO?)
GOTO VARRE ;NÃO - VOLTA P/ VARRE
;SIM - BOTÃO PRESSIONADO
MOVLW 0X80
MOVWF CCPR2L ;CARREGA CCPR2L COM 0X80
BCF CCP2CON,5 ;LIMPA OS BITS 5 E 4
BCF CCP2CON,4 ;LSB DO DUTY CYCLE
;Tp = CCPR2L:CCP2CON<5,4>*TOSC*TMR2PRESCALE
;Tp = 512 * 250ns * 16
;Tp = 2,048ms
;PWM -> DUTY CYCLE = 50%
BCF RS ;SELECIONA O DISPLAY P/ COMANDOS
MOVLW 0XC8 ;COMANDO PARA POSICIONAR O CURSOR
CALL ESCREVE ;LINHA1/COLUNA8
BSF RS ;SELECIONA O DISPLAY P/ DADOS
;COMANDOS PARA ESCREVER AS
;LETRAS DE "50%"
MOVLW ' '
CALL ESCREVE
MOVLW '5'
CALL ESCREVE
MOVLW '0'
CALL ESCREVE
MOVLW '%'
CALL ESCREVE
GOTO VARRE ;VOLTA P/ VARREDURA DOS BOTÕES
; TRATAMENTO DO BOTÃO 2
TRATA_BOTAO_2
MOVF FILTRO_BOTOES,F
BTFSC STATUS,Z ;FILTRO JÁ IGUAL A ZERO?
;(FUNÇÃO JA FOI EXECUTADA?
GOTO VARRE ; SIM - VOLTA P/ VARREDURA DO TECLADO
;NÃO
DECFSZ FILTRO_BOTOES,F ;FIM DO FILTRO? (RUIDO?)
GOTO VARRE ;NÃO - VOLTA P/ VARRE
;SIM - BOTÃO PRESSIONADO
MOVLW 0XC0
MOVWF CCPR2L ;CARREGA CCPR2L COM 0XC0
BCF CCP2CON,5 ;LIMPA OS BITS 5 E 4
BCF CCP2CON,4 ;LSB DO DUTY CYCLE
;Tp = CCPR2L:CCP2CON<5,4>*TOSC*TMR2PRESCALE
;Tp = 768 * 250ns * 16
;Tp = 3,072ms
;PWM -> DUTY CYCLE = 75%
BCF RS ;SELECIONA O DISPLAY P/ COMANDOS
MOVLW 0XC8 ;COMANDO PARA POSICIONAR O CURSOR
CALL ESCREVE ;LINHA1/COLUNA8
BSF RS ;SELECIONA O DISPLAY P/ DADOS
;COMANDOS PARA ESCREVER AS
;LETRAS DE "75%"
MOVLW ' '
CALL ESCREVE
MOVLW '7'
CALL ESCREVE
MOVLW '5'
CALL ESCREVE
MOVLW '%'
CALL ESCREVE
GOTO VARRE ;VOLTA P/ VARREDURA DOS BOTÕES
; TRATAMENTO DO BOTÃO 3
TRATA_BOTAO_3
MOVF FILTRO_BOTOES,F
BTFSC STATUS,Z ;FILTRO JÁ IGUAL A ZERO?
;(FUNÇÃO JA FOI EXECUTADA?
GOTO VARRE ; SIM - VOLTA P/ VARREDURA DO TECLADO
;NÃO
DECFSZ FILTRO_BOTOES,F ;FIM DO FILTRO? (RUIDO?)
GOTO VARRE ;NÃO - VOLTA P/ VARRE
;SIM - BOTÃO PRESSIONADO
MOVLW 0XFF
MOVWF CCPR2L ;CARREGA CCPR2L COM 0XFF
BCF CCP2CON,5 ;SETA OS BITS 5 E 4
BCF CCP2CON,4 ;LSB DO DUTY CYCLE
;Tp = CCPR2L:CCP2CON<5,4>*TOSC*TMR2PRESCALE
;Tp = 1023 * 250ns * 16
;Tp = 4,092ms
;PWM -> DUTY CYCLE = 99,9%
BCF RS ;SELECIONA O DISPLAY P/ COMANDOS
MOVLW 0XC8 ;COMANDO PARA POSICIONAR O CURSOR
CALL ESCREVE ;LINHA1/COLUNA8
BSF RS ;SELECIONA O DISPLAY P/ DADOS
;COMANDOS PARA ESCREVER AS
;LETRAS DE "100%"
MOVLW '1'
CALL ESCREVE
MOVLW '0'
CALL ESCREVE
MOVLW '0'
CALL ESCREVE
MOVLW '%'
CALL ESCREVE
GOTO VARRE ;VOLTA P/ VARREDURA DOS BOTÕES
;------------------------------------------------------------------------------
; FIM DO PROGRAMA
;------------------------------------------------------------------------------
END ;FIM DO PROGRAMA
O que devo fazer para consertar isso?