TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: electronic182 en 26 de Octubre de 2011, 19:28:41

Título: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 19:28:41
ola k tal soy nuevo en el foro , y tenia algunas dudas con este proyecto! , en fin:

para hacer este proyecto solo m faltarian dos cosas que estan en la opcion del modulo CCP:
- variar la frecuencia
-variar el ancho d pulso
Lo de circuito d potencia lo tengo y se como funciona..
Eh estado viendo k hay aportes magnificos con respecto a estos, pero no lo entiendo muy bien!,  kisiera saber como puedo variar con un potenciometro la frecuencia y con otro el ancho de pulso, y luego visualizarlo en un LCD..ya que encontre estos datos:
mi limite de frecuencia esta entre aproximadament 4kHz a 20Khz
y mi ancho de pulso (PWM) esta entre aproximadament 1.5 a 8.5 ms , agradeceria cualquier ayuda posible ya que recien estoy empezando en este maravilloso arte!
gracias d antemano y que sigan mas exitos! nos vemos ...

psdt: es mas a k les doy el esquema para que se deen una idea..
http://www.megaupload.com/?d=6LUG0LPC
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 26 de Octubre de 2011, 19:50:43
a que te refieres con inyectorAs?? te refieres a inyectores?? de vehiculo??

Si es asi esas frecuencias son muy altas, un inyector de automovil 10000RPM = 166Hz

Para hacer una variacion por un potenciometro debes hacer lo siguiente, capturar el pot por el ADC y hacer una regla de 3. Osea:

5000----100%
ADC-----X

x=ADC*100/5000, con eso obtendras un % desde el 0% al 100% para ponerlo al DUTY por ejemplo.

Para variar la frecuencia ya es mas complicado, aunque con una libreria es facil, pero he visto muchas librerias que no permiten modificar la frecuencia unicamente el duty. Pero ya tienes el calculo para obtener una cifra con el ADC, por lo cual lo otro es similar.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 20:09:10
si. a inyectoras de autos..

y con respecto a las frecuencias no son muy altas!
es mas tengo estos datos:
Los datos que tengo sobre los inyectores son:

1. Resistencia de la bobina del inyector: 15 a 17 ohms (en la gran mayoría de los vehículos modernos)
2. Alimentación de exitación: 12 volts
3. Pulsaciones de los inyectores:
- En relantí es de: 2,2ms
- De 2000 a 3000 RPM es de: 1,5 a2,2ms
- Con mariposa a plena carga es de: 8.2 a 8.4ms


Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: NANO1985 en 26 de Octubre de 2011, 20:10:58
INTERESANTE PROYECTO, voy a seguirte de cerca, y a ver en que puedo ser util.
saludos
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 26 de Octubre de 2011, 20:18:34
si. a inyectoras de autos..

y con respecto a las frecuencias no son muy altas!
es mas tengo estos datos:
Los datos que tengo sobre los inyectores son:

1. Resistencia de la bobina del inyector: 15 a 17 ohms (en la gran mayoría de los vehículos modernos)
2. Alimentación de exitación: 12 volts
3. Pulsaciones de los inyectores:
- En relantí es de: 2,2ms
- De 2000 a 3000 RPM es de: 1,5 a2,2ms
- Con mariposa a plena carga es de: 8.2 a 8.4ms




lo que pones de las pulsaciones es la duracion del pulso no?? es logico tal y como pones esa duracion, pero la frecuencia no tiene nada que ver con el duty.

Estamos hablando de que 4khz = 240000 inyecciones por minuto, o lo que equivale a 240000rpm una barbaridad... Ni un monopunto tiene tantas inyecciones. Ademas a 4khz cada inyeccion duraria 250us, un inyector tiene un dead time (excitacion), este tiempo suele ser de 1ms dependiendo de la marca (para estos de alta impedancia como los tuyos sera mas o menos eso). Si cada inyeccion son en 250us y tienes 1ms de dead time el inyector no se llegaria a abrir.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 20:29:37
Que  posea un tiempo fijo de duración de la prueba de 90 segundos a 15 min.
Que las R.P.M. : Sean variables de 500 a 7000 R.P.M. en pasos de 500 R.P.M. por demdio de un potenciómetro.
El Tiempo de abertura: que sea tambien variable de 1,5 a 8 ms (mili segundos) en pasos de 0,5 ms. ajuste por potenciómetro.

El diseño de este probador de inyectores se basa en la generación de un tren de pulsos de 12 V, en los que se pueda variar la frecuencia y el ancho del tren de pulsos que es capaz de entregar la corriente que demanda la bobina del inyector.
De este modo, cuando el inyector se encuentra alimentado con 12 V, se activa y permite el paso de combustible, si estuviera conectado a la alimentación.
El inyector se encuentra activado durante el tiempo en el que el pulso está en el nivel bajo (0 V). Durante al ancho del pulso, el otro extremo de la bobina está alimentado en forma permanente a 12 V.
La forma de prueba es mediante la activación y desactivación del inyector, lo que se logra gracias a la generación de la señal anteriormente descrita.
Para esto se genera un tren de pulso mediante un oscilador de onda cuadrada.
La salida del oscilador activa una etapa que amplifica la corriente, lo suficiente como para accionar el inyector.
La etapa de salida está formada por un transistor MOSFET en configuración source común.
El circuito posee dos potenciómetros que permiten modificar el ancho de pulso y la frecuencia para, de este modo, simular las condiciones a las que el inyector está sometido en su funcionamiento real.

la verdad esos han sido los datos que encontre , no c much de esto, mas bien toda ayuda es bien recibida..

encontre esto de un usuario:
Pues vamos viendo......



Supongamos que se desea una frecuencia de 1KHz a un ciclo de trabajo de 50% con una frecuencia del oscilador de 4MHz.


Lo primero es revisar la hoja de datos (en mi caso el 16F887 o cualquiera que tenga CCP).

Establece una fórmula
PWM Period = [(PR2)+ 1]•4•TOSC •(TMR2 Prescale Value)

Pero es menos complicado si se contempla en función de la frecuencia (recordar que f=1/t):
Fpwm=  [(Fosc)/(PR2+1)*(TMR2 Prescale Value)*(4)]

Lo que interesa es el PR2 ya que es el registro del periodo para la frecuencia (revisar fórmula de hoja de datos):
PR2= [(Fosc)/(Fpwm)*(TMR2 Prescale Value)*(4)]-1

PR2 debemos recordar que es de 8 bits, por lo que el valor máximo no debe exceder 255 (muy importante).


Si se desea 1KHz tenemos básicamente dos opciones:

    * 1.- Se cambia de frecuencia de oscilación (no recomendable, ya que todo el programa se altera)
    * 2.- Se cambia de preescalador para el Timer2



Si tomamos la segunda entonces tenemos tres opciones: 1, 4 y 16.

Con 1:
PR2= [(4MHz)/(1KHz)*(1)*(4)]-1
PR2=1000-1  <---bien importante no olvidarse del -1

PR2=999

Con 1 no sirve, ya que se pasa de los 8 bits.



Con 4:
PR2= [(4MHz)/(1KHz)*(4)*(4)]-1

PR2=249

Con 4 sirve.



Con 16:
PR2= [(4MHz)/(1KHz)*(16)*(4)]-1

PR2=62.5

Con 16 podría servir pero..... el registro no almacena decimales, solo enteros; lo anterior nos proporciona dos posibles caminos:

    * PR2=62
    * PR2=63


Si PR2=62, entonces la Fpwm será:
Fpwm=  [(Fosc)/(PR2+1)*(TMR2 Prescale Value)*(4)]
Fpwm=  [(4MHz)/(62+1)*(16)*(4)]
Fpwm=  992.0634 Hz

Lo anterior entrega un error de 0.8% aproximadamente.



Si PR2=63, entonces la Fpwm será:
Fpwm=  [(Fosc)/(PR2+1)*(TMR2 Prescale Value)*(4)]
Fpwm=  [(4MHz)/(63+1)*(16)*(4)]
Fpwm=  976.5625 Hz

Lo anterior entrega un error de 2.4% aproximadamente.



La ideal es PR2=249 con preescalador a 4; cabe señalar que solo estamos en la frecuencia.



Para el PWM es algo similar pero, el CCS utiliza funciones donde el comportamiento no es tan transparente como se desearía.


Recordar que
Pulse Width =(CCPRxL:CCPxCON<5:4>) •TOSC • (TMR2 Prescale Value)



y que

Duty Cycle Ratio= (CCPRxL:CCPxCON<5:4>)
                           --------------------------------
                                       4(PR2 + 1)


El ciclo de trabajo ya se conoce (es el deseado), por lo que interesa es el valor de CCPRxL:CCPxCON<5:4>. En C o en BASIC es relativamente sencillo colocar ese valor, en ensamblador no tanto. Lo anterior debido a que los bits 5 y 4 de CCPxCON son los de menor peso y se debe realizar un corrimiento con todo CCPRxL.


Aquí es donde se torna algo confuso (para la mayoría):

suponiendo un ciclo de trabajo de 50%, significa que el valor donde se repite el periodo (PR2+1) es 250, el valor medio sería 125, por lo que CCPRxL deberá tomar ese valor.
CCPRxL toma el valor ya que es el registro de mayor peso para el ciclo de trabajo, los otros dos bits no afectan.

Lo anterior es si deseas utilizar el PWM en "modo de 8 bits"  (no existe tal modo, pero trabaja asi). Si deseas utilizar los 10 bits de resolución, deberás utilizar esos dos bits de menor peso.

Esos dos bits de menor peso siempre producirán 4 combinaciones adicionales (00,01,10,11) a las 256 del CCPRxL y, como sabemos 10bits=1024. El máximo valor que tendrás será 1023.

Si PR2 es 249, y PR2+1 =250, entonces el valor para el ciclo de trabajo crece de 250 a 1000, dando 4 veces el original (debido a esos dos bits).

Aqui está la situación:
para utilizar los 10 bits de resolución el CCS debe saber que el parámetro de set_pwm_duty() es un entero de 16 bits (INT16 o LONG), de otra manera lo tomará como 8 bits (solo tomará el CCPRxL).

Coloca esto:
setup_ccp1(ccp_PWM);
setup_timer_2(t2_div_By_4,249,1);
set_pwm_duty(125);

Coloca esto:
setup_ccp1(ccp_PWM);
setup_timer_2(t2_div_By_4,249,1);
set_pwm_duty(500L);

Verás que no hay cambio.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 26 de Octubre de 2011, 20:36:58
pues ya tienes como calcular la frecuencia para el PWM, 500rpm = 8Hz; 7000rpm=117Hz

ahora tienes que calcular una escala y frecuencia para obtener esos Hz el minimo y maximo. El duty no te preocupes por ahora, lo que mas te va a costar es hacer el calculo para sacar la frecuencia deseada.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 20:47:12
alguien mas tiene una idea , gracias x su tiempo

Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 26 de Octubre de 2011, 21:50:48
me parece que para esas frecuencias bajas te conviene usar un timer.

EDITO: para usarlo tendrias que cargar en el timer el tiempo TOTAL del ciclo desde el primer potenciometro y luego, sacar el equivalente al tiempo ON del inyector desde el segundo potenciometro, una vez cumplido el tiempo ON, restas desde el tiempo TOTAL el tiempo ON para generar el tiempo en el que el inyector esta apagado.

______1--------2___3--------+___

1 - entra en la INT. por timer, acciona el inyector y carga el tiempo ON
2 - entra en la INT. por timer, libera el inyector, resta a TIEMPO_TOTAL la variable TIEMPO_ON y la carga en el timer
3 - entra en la INT. por timer, cumplido el ciclo, vuelve al punto 1
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 22:00:22
lo c , es mas tengo su esquema con timer o con un 556 , y tambien con opanes... pero mi objetivo es hacerlo con pic...
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 26 de Octubre de 2011, 22:04:54
timer del pic...
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 26 de Octubre de 2011, 22:12:13
para un PWM tan bajo necesitarias una velocidad baja del pic.

empieza por aqui:

ahi por lo menos veras como funciona, de que se trata, etc...
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 22:12:55
disculpame , m deje llevar por tu primera frase..

m podrias explicar un poco mas detallado por favor (lo mas detallado posible .gracias)
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 26 de Octubre de 2011, 22:23:31
en ese video lo detalla perfectamente, si se te hace demasiado complicado, te recomiendo que en ese mismo canal mires otros tutoriales de lo que quieras saber, te lo comento porque explicarte todo desde 0 se me hace complicado, ademas de ser largo, y de que hay miles de tutoriales por ahi que lo explican mejor que lo haria yo.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 22:32:24
wowwwwwwwwwww, excelent amigo gracias! y una vez k comprenda eso m orientas mas , por favor!
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 26 de Octubre de 2011, 22:40:46
primero medis el potenciometro 1 para sacar el ciclo de trabajo que vas a tener ( usando un canal del ADC), luego calculas el tiempo COMPLETO al que equivale; por ejemplo, el ADC del pot.1 te da 500 (en decimal), despues sacas la cuenta a cuanto tiempo equivale, por ejemplo 250mS (este numero es de ejemplo). Luego medis con otro canal del ADC el pot. 2 y sacas el porcentaje del tiempo amterior, ej. si el pot.2 te da 512 significa que esta al medio de su recorrido, lo que daria un tiempo ON de 125mS. Entonces, ahora tener que cargar los tiempos en las variables y configurar el timer para que te de la cantidad de pasos que estas buscando.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 26 de Octubre de 2011, 23:48:57
ok , voy a atratar  de asemejarlo!
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 27 de Octubre de 2011, 00:03:51
la parte mas dificil es ajustar el timer para que te de bien el tiempo, despues, como te va a sobrar tiempo (porque se maneja por interrupciones) podrias incluso mostrar en la pantalla el consumo del inyector a distintas frecuencias, poner un menu para otras opciones ....
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 27 de Octubre de 2011, 00:08:35
yoshua tengo una pregunta , con respecto al ciclo en cuantas divisiones lo puedo dividir?
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 27 de Octubre de 2011, 00:12:46
te lo limita la velocidad a la que trabaja el pic porque el timer funciona con ese reloj, a mayor frecuencia, mayor resolucion.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 27 de Octubre de 2011, 00:15:04
osea no tiene nada k ver.??
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 27 de Octubre de 2011, 00:20:03
si queres, podes consegir divisiones de hasta 1uS con reloj de 4Mhz. Si preparas el timer para un desborde de 250uS tendrias 4 divisiones en 1mS .
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 27 de Octubre de 2011, 00:31:37
yoshua t podrias conectar al msn pa hablar mejor?
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: Yoshua en 27 de Octubre de 2011, 00:43:18
el mio es
ray_yoshua@hotmail.com
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 27 de Octubre de 2011, 16:17:06
hola k tal , quisieraa preguntarles si alguien me podríaa brindar un manual sobre una maquina generadora de pulso sobre cualquier modelo , no importa en español o ingles.. con tal d q sea generador de pulsos para inyectora de autos...

muchas gracias
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 27 de Octubre de 2011, 18:53:18
dificil encontrar tal cosa, la mayoria de maquinas que venden son industriales, y encontrar manuales de esto es dificil.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 31 de Octubre de 2011, 13:52:01
m podrian decir cual es el ancho d pulso que se reqiere para ralenti , ya que el que tengo m tiene en duda , y si tuvieran todos los tipos de arranque con sus rpm muchisiomo mejor , gracias d antmano!!
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 31 de Octubre de 2011, 14:50:05
el ancho de pulso de ralenti depende de la cantidad de gasolina que se quiera inyectar, varia para cada coche/modelo, para cada tamaño de inyectores, segun temperatura... para el mio varia entre 2.5ms y 3ms + 550us de lag time
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 31 de Octubre de 2011, 19:41:42
gracias merlinz , de gran ayuda como simpre!!

ya estoy terminando.. mi proyecto ..
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 31 de Octubre de 2011, 20:12:05
merlinz ak d nuevo fastidiandot, mm me puedes explicar como manejar el ancho de  pulso en cuestion de porcentaje xq segun esuche asi es mucho mas facil..

ya tengo mis frecuencias variables ahora el problema esta en el ancho de pulso ,al variar la frecuencia siempre varia el ancho de pulso, no  c si seria mejor mediante tiempos o mediante porcentaje ... gracias
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 31 de Octubre de 2011, 20:26:59
por % cambiara tambien el ancho del pulso en tiempo.

Por ejemplo en 100Hz = 0.01s (periodo)
el 50% de ese periodo seria 0.005s

en 1000Hz  = 0.001s
el 50% seria 0.0005s

Siempre variara para obtener el 50% en determinada frecuencia, si varia el tiempo, tambien varia el tiempo del %

Lo que puedes hacer es ajustar que cuando cambies la frecuencia, tambien se cambie el duty al % adecuado para obtener el mismo ancho de pulso.

si por ejemplo tienes 100Hz y quieres 5ms seria

100-----10ms
X--------5ms

X=50%

Ahora si cambias a 200Hz

100------5ms
X--------5ms

X=100%
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 31 de Octubre de 2011, 20:47:00
aver merlinz , voy a poner manos a la obra .. y  estoy comunicando mis resultados
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 31 de Octubre de 2011, 21:04:18
melrinz m olvidadba pero si no deseo obtener un ancho de pulso fijo, y lo deseo variable ahi la cosa cambia, pero igual gracias tu idea es buena
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 07 de Noviembre de 2011, 18:10:59
alguien sabe el tiempo que se reqieere para cada inyectora, osea:

1ero le llega pulso a una inyectora , al finalizar empieza la otra pero kiero saber el tiempo que demora en que se accione la que sigue para asi evitar futuros problemas , como que se atasque u otros..

ah! y m olvidaba los tipos de secuencias mas utilizados:

1-2-3-4
1-3-2-4...

no c si abra otras para la utilizacion .. gracias--
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 10 de Noviembre de 2011, 17:19:56
ya esta solucionado las secuencias , en la mayoria de autos es : 1-3-4-2

ahora tengo duda--sobre otras cosas:

-Ya saque mi frecuencia visualizada en mi LCD
-Y mi PWM

Pero no tengo idea de como poder unirlos??
gracias..
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 10 de Noviembre de 2011, 18:22:47
el accionamiento de los inyectores lo elije la centralita, y dependiendo para cada coche varia, normalmente la inyeccion se produce en el tiempo de admision despues del cruce de valvulas (para evitar que salga la gasolina por el escape), sin embargo como el ancho de pulso varia, y tambien su frecuencia (al aumentar las RPM) llega un momento en que tiene que realizar antes la inyeccion para que le entre la cantidad adecuada. Ademas eso de que primero inyecta uno y luego otro no es cierto, a altas rpm y mucho tiempo de inyeccion puede llegar el momento en que cuando un inyector esta inyectando, el otro tambien se ponga a inyectar. Todo depende del coche, y de la tecnologia que tenga, por eso cada coche es un mundo.

A que te refieres con unirlos??
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 11 de Noviembre de 2011, 12:24:02
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!
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: electronic182 en 20 de Noviembre de 2011, 23:28:03
problema resuelto eh conseguido variar la frecuencia y el PWM  en el proteuss, ahora al armarlo en el protoboard no me sale nada en la pantalla LCD.

Ojo no estoy usando el 16f628.., lo cambie por el 16F877A(estoy usando 2 pic)  por sus entradas analogicas (use 2) para las RPM y PWM

Pero no c visualiza nada en el LCD , al poner una punta negativa de mi multimetro en un extremo de uno de los condensadores(22pF) que van con el cristal de 20MHz recien me aparece lo que deberia salir...

No c si sera x los condensadores , que es de 22pF , creen que deberia cambiarlos por unos de 33pF..??

El primer 16F877A es para las RPM y PWM , para variarlo
El segundo 16f877A es para  visualizar con el LCD.
Título: Re: generador de pulsos para inyectoras con pic 16f628A
Publicado por: MerLiNz en 20 de Noviembre de 2011, 23:39:22
no entiendo porque usar 2 pics para algo tan simple, con 1 te sobra en una protoboard 2 pics te pueden dar problemas de ruidos.