ok, entonces no me preocupo por ponerle un retardo por cada inyector..
Con respecto a la frecuencia y al ancho de pulso a como unirlos:
Para la frecuencia por ejemplo seria asi:
; PULSACIÓN FRECUENCIA SEMIPERIODO
; --------- ---------- -----------------------
; (Inicial) 10 kHz 50 µs. = 1 x 50 µs
; Primera 5 kHz 100 µs. = 2 x 50 µs
; Segunda 2 kHz 250 µs. = 5 x 50 µs
; Tercera 1 kHz 500 µs. = 10 x 50 µs
; Cuarta 500 Hz 1000 µs. = 20 x 50 µs
; Quinta 200 Hz 2500 µs. = 50 x 50 µs
; Sexta 100 Hz 5000 µs. = 100 x 50 µs
; Septima 50 Hz 10000 µs. = 200 x 50 µs
;
; Al conectarlo por primera vez se genera una frecuencia de 10 kHz, al activar el
; pulsador cambia a 5 kHz, al actuar una segunda vez cambia a 2 kHz, y así sucesivamente.
;
; El módulo LCD visualizará la frecuencia generada. A la línea de salida se puede conectar
; un altavoz que producirá un pitido.
; ZONA DE DATOS **********************************************************************
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CBLOCK 0x0C
ApuntadorFrecuencia
Semiperiodo
ENDC
TMR0_Carga50us EQU d'256'-d'42'; El semiperiodo patrón va a ser de 50 µs.
NUM_FRECUENCIA EQU d'8' ; Ocho posibles frecuencias: 10 kHz, 5 kHz, 2 kHz,
; 1 kHz, 500 Hz, 200 Hz, 100 Hz y 50 Hz.
#DEFINE Salida PORTB,3
#DEFINE Pulsador PORTB,7
; ZONA DE CÓDIGOS ********************************************************************
ORG 0
goto Inicio
ORG 4
goto ServicioInterrupcion
; Subrutina "CargaContador" -------------------------------------------------------------
CargaContador
addwf PCL,F
retlw .1 ; Semiperiodo 1 x 50 = 50 µs, frecuencia = 10 kHz.
retlw .2 ; Semiperiodo 2 x 50 = 100 µs, frecuencia = 5 kHz.
retlw .5 ; Semiperiodo 5 x 50 = 250 µs, frecuencia = 2 kHz.
retlw .10 ; Semiperiodo 10 x 50 = 500 µs, frecuencia = 1 kHz.
retlw .20 ; Semiperiodo 20 x 50 = 1000 µs, frecuencia = 500 Hz.
retlw .50 ; Semiperiodo 50 x 50 = 2500 µs, frecuencia = 200 Hz.
retlw .100 ; Semiperiodo 100 x 50 = 5000 µs, frecuencia = 100 Hz.
retlw .200 ; Semiperiodo 200 x 50 = 10000 µs, frecuencia = 50 Hz.
; Subrutina "CargaMensaje" -------------------------------------------------------------
CargaMensaje
addwf PCL,F
retlw Mensaje10kHz
retlw Mensaje5kHz
retlw Mensaje2kHz
retlw Mensaje1kHz
retlw Mensaje500Hz
retlw Mensaje200Hz
retlw Mensaje100Hz
retlw Mensaje50Hz
; Subrutina "Mensajes" ------------------------------------------------------------------
;
Mensajes
addwf PCL,F
MensajeFrecuencia
DT "Frec.: ", 0x00
Mensaje10kHz
DT "10 kHz. ", 0x00
Mensaje5kHz
DT "5 kHz. ", 0x00
Mensaje2kHz
DT "2 kHz. ", 0x00
Mensaje1kHz
DT "1 kHz. ", 0x00
Mensaje500Hz
DT "500 Hz. ", 0x00
Mensaje200Hz
DT "200 Hz. ", 0x00
Mensaje100Hz
DT "100 Hz. ", 0x00
Mensaje50Hz
DT "50 Hz. ", 0x00
; Programa Principal ------------------------------------------------------------------
Inicio
call LCD_Inicializa
bsf STATUS,RP0
bcf Salida
bsf Pulsador
movlw b'00001000' ; TMR0 sin prescaler.
movwf OPTION_REG
bcf STATUS,RP0
call EstadoInicial ; Visualiza la frecuencia inicial.
movlw TMR0_Carga50us ; Carga el TMR0.
movwf TMR0
movlw b'10101000'
movwf INTCON ; Activa interrupciones del TMR0, RBI y general.
Principal
goto Principal
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Detecta qué ha producido la interrupción y ejecuta la subrutina correspondiente.
ServicioInterrupcion
btfsc INTCON,T0IF ; ¿Interrupción por desbordamiento del TMR0?.
call Timer0_Interrupcion
btfsc INTCON,RBIF ; ¿Interrupción por cambio en el Puerto B?.
call Pulsador_Interrupcion
bcf INTCON,T0IF ; Repone flag del TMR0.
bcf INTCON,RBIF ; Repone flag del RBI.
retfie
; Subrutina "Pulsador_Interrupcion" -----------------------------------------------------
;
; Subrutina de atención a la interrupción por cambio en la línea RB7 donde se ha
; conectado un pulsador.
; Incrementa el registro (ApuntadorFrecuencia) desde b'00000000' (que corresponde a una
; frecuencia de 10 kHz) hasta b'00000111' (que corresponde a una frecuencia de 50 Hz),
; según la tabla especificada en el enunciado del ejercicio.
;
Pulsador_Interrupcion
call Retardo_20ms
btfsc Pulsador
goto Fin_PulsadorInterrupcion
incf ApuntadorFrecuencia,F ; Apunta a la siguiente frecuencia.
movlw NUM_FRECUENCIA ; Va a comprobar si ha llegado al máximo.
subwf ApuntadorFrecuencia,W ; (W)=(ApuntadorFrecuencia)-NUM_FRECUENCIA
btfsc STATUS,C ; ¿Ha llegado a su máximo?
EstadoInicial
clrf ApuntadorFrecuencia ; Si llega al máximo lo inicializa.
movf ApuntadorFrecuencia,W ; Va a cargar el valor del factor de
call CargaContador ; multiplicación del semiperiodo según la
movwf Semiperiodo ; tabla.
movwf Timer0_ContadorA
call LCD_Linea1 ; Visualiza la frecuencia seleccionada.
movlw MensajeFrecuencia
call LCD_Mensaje
movf ApuntadorFrecuencia,W
call CargaMensaje
call LCD_Mensaje
EsperaDejePulsar
btfss Pulsador
goto EsperaDejePulsar
Fin_PulsadorInterrupcion
return
; Subrutina "Timer0_Interrupcion" -------------------------------------------------------
;
CBLOCK
Timer0_ContadorA
ENDC
Timer0_Interrupcion
movlw TMR0_Carga50us
movwf TMR0 ; Recarga el TMR0.
decfsz Timer0_ContadorA,F ; Decrementa el contador.
goto Fin_Timer0_Interrupcion
movf Semiperiodo,W ; Repone el contador nuevamente.
movwf Timer0_ContadorA
btfsc Salida ; Testea el último estado de la salida.
goto EstabaAlto
EstabaBajo
bsf Salida ; Estaba bajo y lo pasa a alto.
goto Fin_Timer0_Interrupcion
EstabaAlto
bcf Salida ; Estaba alto y lo pasa a bajo.
Fin_Timer0_Interrupcion
return
INCLUDE <LCD_MENS.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <RETARDOS.INC>
END
Y para el ancho de pulso la mejor manera es usando duty cicle por porcentaje:
Como este ejemplo:
; PULSACIÓN DC (%) SEMIPERIODO ALTO SEMIPERIODO BAJO
; --------- ------- ---------------------- -----------------------
; Inicial 0 % 0 µs = 0 x 100 µs 10000 µs = 100 x 100 µs
; Primera 10 % 1000 µs = 10 x 100 µs 9000 µs = 90 x 100 µs
; Segunda 20 % 2000 µs = 20 x 100 µs 8000 µs = 80 x 100 µs
; Tercera 30 % 3000 µs = 30 x 100 µs 7000 µs = 70 x 100 µs
; Cuarta 40 % 4000 µs = 40 x 100 µs 6000 µs = 60 x 100 µs
; Quinta 50 % 5000 µs = 50 x 100 µs 5000 µs = 50 x 100 µs
; Sexta 60 % 6000 µs = 60 x 100 µs 4000 µs = 40 x 100 µs
; Septima 70 % 7000 µs = 70 x 100 µs 3000 µs = 30 x 100 µs
; Octava 80 % 8000 µs = 80 x 100 µs 2000 µs = 20 x 100 µs
; Novena 90 % 9000 µs = 90 x 100 µs 1000 µs = 10 x 100 µs
; Décima 100 % 10000µs = 100 x 100 µs 0 µs = 0 x 100 µs
;
; Al conectarlo por primera vez se genera un ciclo de trabajo de 0%, al presionar el pulsador
; cambia al 10%, al actuar una segunda vez cambia al 20%, y así sucesivamente.
; El módulo LCD visualiza el ciclo de trabajo vigente en cada momento.
;
; ZONA DE DATOS **********************************************************************
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CBLOCK 0x0C
CicloTrabajo ; Ciclo de trabajo deseado.
Timer0_ContadorA ; Contador auxiliar.
ENDC
TMR0_CARGA EQU d'256'-d'89' ; El semiperiodo patrón va a ser de 100 µs.
INCREMENTO_DC EQU d'10' ; Incremento de cada paso del ciclo de trabajo.
#DEFINE Salida PORTB,3
#DEFINE Pulsador PORTB,7
; ZONA DE CÓDIGOS ********************************************************************
ORG 0
goto Inicio
ORG .4
goto ServicioInterrupcion
Mensajes
addwf PCL,F
Mensaje_DC
DT "Duty Cycle: ", 0x00
Mensaje_TantoPorCiento
DT "% ", 0x00
Inicio
bsf STATUS,RP0
bcf Salida
bsf Pulsador
movlw b'00001000' ; TMR0 sin prescaler.
movwf OPTION_REG
bcf STATUS,RP0
call LCD_Inicializa
call DC_CeroPorCiento ; Inicializa con un DC=0%, por tanto salida
movlw b'10001000' ; en bajo permanentemente.
movwf INTCON ; Habilita solo interrupción RBI.
Principal
goto Principal
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
ServicioInterrupcion
btfsc INTCON,RBIF ; ¿Interrupción por cambio en el Puerto B?
call Pulsador_Interrupcion
btfsc INTCON,T0IF ; ¿Interrupción por desbordamiento del TMR0?
call Timer0_Interrupcion
bcf INTCON,RBIF ; Limpia flags de reconocimiento.
bcf INTCON,T0IF
retfie
; Subrutina "Pulsador_Interrupcion" -----------------------------------------------------
;
; Subrutina de atención a la interrupción por cambio en la línea RB7 donde se ha
; conectado un pulsador.
; Incrementa el registro (CicloTrabajo), desde 0 (que corresponde a un DC = 0%
; hasta d'100' (que corresponde a un ciclo de trabajo del 100%).
;
Pulsador_Interrupcion
call Retardo_20ms
btfsc Pulsador ; Si no es la línea del pulsador sale.
goto Fin_PulsadorInterrupcion
bsf INTCON,T0IE ; En principio habilita interrupciones TMR0.
movlw INCREMENTO_DC ; Se le va a sumar al ciclo de trabajo
addwf CicloTrabajo,W ; (W) = (CicloTrabajo) + INCREMENTO_DC
movwf CicloTrabajo ; Guarda resultado.
sublw .100 ; Si DC ha llegado al 100% la salida pasa a
btfsc STATUS,Z ; alto permanentemente.
goto DC_100PorCiento
btfsc STATUS,C ; Si pasa de 100, lo inicializa.
goto Visualiza
DC_CeroPorCiento
bcf Salida ; Pone la salida siempre en bajo.
clrf CicloTrabajo ; Inicializa el ciclo de trabajo a 0%.
goto InhabilitaInterrupcionTMR0
DC_100PorCiento
bsf Salida ; Pone la salida siempre en alto.
movlw .100 ; Está al máximo, DC=100%.
movwf CicloTrabajo
InhabilitaInterrupcionTMR0
bcf INTCON,T0IE
Visualiza
call VisualizaCicloTrabajo ; Visualiza el ciclo de trabajo seleccionado.
EsperaDejePulsar
btfss Pulsador
goto EsperaDejePulsar
Fin_PulsadorInterrupcion
movf CicloTrabajo,W ; Carga todos los contadores.
movwf Timer0_ContadorA
movlw TMR0_CARGA
movwf TMR0
return
; Subrutina "Timer0_Interrupcion" -------------------------------------------------------
;
; Mantiene la salida en alto un tiempo igual a 100µs x (CicloTrabajo)
; y en bajo un tiempo igual a 100µs x (100-CicloTrabajo).
;
Timer0_Interrupcion
movlw TMR0_CARGA
movwf TMR0
decfsz Timer0_ContadorA,F ; Decrementa el contador.
goto Fin_Timer0_Interrupcion
btfsc Salida ; Testea el anterior estado de la salida.
goto EstabaAlto
EstabaBajo
nop
bsf Salida ; Estaba bajo y lo pasa a alto.
movf CicloTrabajo,W ; Repone el contador nuevamente con el tiempo en
movwf Timer0_ContadorA ; alto.
nop
goto Fin_Timer0_Interrupcion
EstabaAlto
bcf Salida ; Estaba alto y lo pasa a bajo.
movf CicloTrabajo,W ; Repone el contador nuevamente con el tiempo
sublw .100 ; en bajo.
movwf Timer0_ContadorA
Fin_Timer0_Interrupcion
return
; Subrutina "VisualizaCicloTrabajo" -----------------------------------------------------
;
; Visualiza el ciclo de trabajo en el visualizador LCD. Se hace de manera tal que cuando
; haya que visualizar un número mayor de 9, las decenas siempre se visualicen aunque sean
; cero. Y cuando sea menor de 99 las decenas no se visualicen si es cero.
;
VisualizaCicloTrabajo
call LCD_Linea1 ; Visualiza el ciclo de trabajo seleccionado.
movlw Mensaje_DC
call LCD_Mensaje
movf CicloTrabajo,W
call BIN_a_BCD ; Lo pasa a BCD.
movf BCD_Centenas,W ; Visualiza las centenas.
btfss STATUS,Z ; Si son cero no visualiza las centenas.
goto VisualizaCentenas
movf CicloTrabajo,W ; Vuelve a recuperar este valor.
call BIN_a_BCD ; Lo pasa a BCD.
call LCD_Byte ; Visualiza las decenas y unidades.
goto VisualizaTantoPorCiento
VisualizaCentenas
call LCD_Nibble ; Visualiza las centenas.
movf CicloTrabajo,W ; Vuelve a recuperar este valor.
call BIN_a_BCD ; Lo pasa a BCD.
call LCD_ByteCompleto ; Visualiza las decenas (aunque sea cero) y
VisualizaTantoPorCiento ; unidades.
movlw Mensaje_TantoPorCiento ; Y ahora el simbolo "%".
call LCD_Mensaje
return
INCLUDE <LCD_MENS.INC>
INCLUDE <LCD_4BIT.INC>
INCLUDE <RETARDOS.INC>
INCLUDE <BIN_BCD.INC>
END
Pero como lo uniria los dos ?
Osea quiero mi frecuencia regulable y a la vez mi duty cicle visualizados en mi LCD:
Frecuencia : 10KHz
Duty Cycle : 10%
ALgo asi que se puedan variar en cualkier momenro....
gracias por tu tiempo! , dime que deberia leer o hacer o buscar info t lo hago y digo mis reporte..
PSDT: al compilarlo en el MPLAB m sale una falla en OPTION_REG , dice que no esta en el bank 0 algo asi..
gracias d antemano!