TODOPIC
Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado 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
-
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.
-
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
-
INTERESANTE PROYECTO, voy a seguirte de cerca, y a ver en que puedo ser util.
saludos
-
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.
-
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.
-
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.
-
alguien mas tiene una idea , gracias x su tiempo
-
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
-
lo c , es mas tengo su esquema con timer o con un 556 , y tambien con opanes... pero mi objetivo es hacerlo con pic...
-
timer del pic...
-
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...
-
disculpame , m deje llevar por tu primera frase..
m podrias explicar un poco mas detallado por favor (lo mas detallado posible .gracias)
-
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.
-
wowwwwwwwwwww, excelent amigo gracias! y una vez k comprenda eso m orientas mas , por favor!
-
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.
-
ok , voy a atratar de asemejarlo!
-
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 ....
-
yoshua tengo una pregunta , con respecto al ciclo en cuantas divisiones lo puedo dividir?
-
te lo limita la velocidad a la que trabaja el pic porque el timer funciona con ese reloj, a mayor frecuencia, mayor resolucion.
-
osea no tiene nada k ver.??
-
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 .
-
yoshua t podrias conectar al msn pa hablar mejor?
-
el mio es
ray_yoshua@hotmail.com
-
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
-
dificil encontrar tal cosa, la mayoria de maquinas que venden son industriales, y encontrar manuales de esto es dificil.
-
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!!
-
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
-
gracias merlinz , de gran ayuda como simpre!!
ya estoy terminando.. mi proyecto ..
-
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
-
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%
-
aver merlinz , voy a poner manos a la obra .. y estoy comunicando mis resultados
-
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
-
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--
-
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..
-
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??
-
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!
-
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.
-
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.