TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: douglas38 en 05 de Enero de 2020, 09:25:31
-
Hola a todos, estoy comenzando a programar micro controladores PIC. En este caso estoy tengo montado en el simulador proteus un pic 12f675 con un oscilador de 20 Mhz, un pulsador que tiene 3 funciones:
1. enciende a una frecuencia con un ciclo util de 50% oscilando a 250khz por un tiempo de 10 minutos
2. para la frecuencia anterior y comienza con otra frecuencia que varia desde 1khz hasta 250 khz por 7 minutos y luego 3 minutos a 250khz para
completar un total de 10 minutos, el ciclo de trabajo es de 50%.
3. apaga el sistema.
Como dije anteriormente soy nuevo en esto y agradecería cualquier ayuda que pudieran prestarme, a duras penas lo que he realizado es esto:
#include <12F675.h>
#FUSES HS
#FUSES NOWDT // No Watch Dog Timer
#FUSES NOPUT // Power Up Timer
#FUSES NOMCLR // Master Clear pin used for I/O
#FUSES NOPROTECT // Code not protected from reading
#use delay(CLOCK=20M)
#INT_TIMER1
void temporizador()
{
output_toggle(pin_a0);
set_timer1(65526); //set_timer1(65526);
}
void main()
{
set_tris_a(0b11110100);
setup_timer_1( T1_INTERNAL | t1_div_by_1 ); //| T1_EXTERNAL_SYNC
set_timer1(65526);
enable_interrupts(int_timer1);
enable_interrupts(GLOBAL); //habilita todas las interrupciones globales.
while(1)
{
}
}
-
Por ahora lo mas simple es hacer el codigo para cada uno y luego lo tratas de unir.
Si en el camino tenes dudas, las preguntas.
Actualmente tu "pregunta"/"duda", no es una pregunta o duda, es casi una declaracion para que te den el codigo. Correctamente deberias mostrar que intentaste, y asi podemos ayudarte en el "porque no funciona"
-
Lo que mencione es para que tengan una idea de lo que quiero hacer. pero en realidad estoy enfocado desde hace un tiempo en generar solo la frecuencia cuadrada de 250 khz pero no lo he logrado, allí muestro el código, lo he intentado pero nada.
Solo he podido llegar hasta un máximo de 30 khz y de paso el tiempo en alto que me da la señal en alto es menor que el tiempo en bajo.
-
Lo que mencione es para que tengan una idea de lo que quiero hacer. pero en realidad estoy enfocado desde hace un tiempo en generar solo la frecuencia cuadrada de 250 khz pero no lo he logrado, allí muestro el código, lo he intentado pero nada.
Solo he podido llegar hasta un máximo de 30 khz y de paso el tiempo en alto que me da la señal en alto es menor que el tiempo en bajo.
Estás haciendo una programación millenial, donde los procesadores tienen velocidades infinitas. Te estás olvidando que para atender una interrupción el micro necesita unos cuantos ciclos de máquina y otros mas para volver al programa.
Cuando ejecutás set_timer1(65526) dentro de la interrupción no tenés en cuenta que el contador ya tuvo incrementos --> estás alargando el período.
Además, como en 10 ciclos de máquina probablemente no haya vuelto al programa principal, se disparará otra interrupción o la perderás según donde te agarre.
En el cálculo del período tenés que tener en cuenta estos retardos, podés hacerlo a mano (tarea ingrata) o medir la frecuencia real y estimar 2 constantes.
Copypasteando tu código y colgando un frecuencímetro en PIN_A0 mido que el retardo promedio para atender la interrupción.
Me sale:
#define Tint1 43 // Tics medio para atender la interrupción
#define Tint2 23 // Tics medio para salir de la interrupción
Por lo tanto debés escribir en la interrupción: set_timer1(65536+Tint1-N) ; // N: numero de tics
Y ojo que debe ser N > Tint1+Tint2
Lástima que con estas demoras ni por casualidad vas a llegar a 250kHz, como máximo a 75kHz (37.5kHz la onda cuadrada)
Va a mejorar, aunque poco, usando #use fast_io(all), pero el cambio drástico es usando #INT_GLOBAL porque te evitás toda la parte de identificación de la fuente de interrupción, pero como igual vas a tener que hacer vos el salvar/recuperar el estado --> dudo que llegues a 250kHz.
El problema está en que 250kHz es una frecuencia muy alta para el 12F675 y la unica manera práctica es con un micro cuyo hardware incluya PWM.
-
ok, Eduardo2, entiendo, lo raro es que un amigo lo tiene hecho este circuito con su placa y todo. usando pic12f675 y un oscilador de 20 mhz y en el osciloscopio me daba la señal de 250khz. pero perdí el contacto con ese amigo y lamentablemente no me puede ayudar con el código para estudiarlo y ver como lo hizo.. bueno en fin casi todos los días estoy probando e investigando pero ya no se como conseguir esa frecuencia.
-
ok, Eduardo2, entiendo, lo raro es que un amigo lo tiene hecho este circuito con su placa y todo. usando pic12f675 y un oscilador de 20 mhz y en el osciloscopio me daba la señal de 250khz. pero perdí el contacto con ese amigo y lamentablemente no me puede ayudar con el código para estudiarlo y ver como lo hizo.. bueno en fin casi todos los días estoy probando e investigando pero ya no se como conseguir esa frecuencia.
No tiene muchas vueltas, para generar con ese micro una cuadrada de 250kHz (1 cambio cada 2us) tenés MUY pocos ciclos de máquina disponibles --> Por interrupción olvidate.
La única forma es NO usar interrupción, para no tener que salvar/recuperar el estado , sino hacer un simple bucle con un número determinado de instrucciones.
Haciendo:
void main()
{
set_tris_a(0b11110100);
#asm
bcf 3.5
movlw 1
LOOP1:
xorwf 0x05
nop
nop
nop
nop
nop
nop
nop
goto LOOP1
#endasm
}
Te sale:
- Tienes que ingresar para ver archivos adjuntos -
Lo que ha hecho tu amigo es en lugar de los NOPs, leer una entrada para salir del bucle.
-
perfecto Eduardo2, mil gracias por tomarte tu tiempo y responder. sabes, ya monte el circuito en el protoboard y si efectivamente en el osciloscopio veo los 250 khz. observo en tu código que utilizaste código C junto con asembler, hay alguna razón de usar las 2 al mismo tiempo? otra pregunta, los NOP tengo entendido que lo que están haciendo es consumir un poco mas de tiempo. si pudieras explicarme lo que hiciste con el código para sacar esta frecuencia te lo agradecería, porque tengo que estar claro con eso, debido a que ahora tengo que hacer que esa frecuencia varié poco a poco desde 1khz hasta 250kz y regrese desde 250 kz hasta 1khz y se repita constantemente por un tiempo de 3 minutos.
-
perfecto Eduardo2, mil gracias por tomarte tu tiempo y responder. sabes, ya monte el circuito en el protoboard y si efectivamente en el osciloscopio veo los 250 khz. observo en tu código que utilizaste código C junto con asembler, hay alguna razón de usar las 2 al mismo tiempo?
Es para tener control sobre los ciclos de máquina (0.2us) que demora el bucle.
Podría haber escrito:
while(1){
output_toggle(pin_a0) ;
// relleno para 250kHz MAX
#asm
nop
nop
nop
nop
nop
nop
#endasm
}
Pero según uses fast_io(all) o el código que haya escrito antes del while el compilador te insertará una selección del banco de registros, haciendo que el bucle demore 1 , 2 o 3 ciclos mas.
Esto con frecuencias mas bajas no tiene importancia, pero acá no podés programar sonriente y despreocupado porque estás al límite.
otra pregunta, los NOP tengo entendido que lo que están haciendo es consumir un poco mas de tiempo. si pudieras explicarme lo que hiciste con el código para sacar esta frecuencia te lo agradecería, porque tengo que estar claro con eso,
El bucle base es:
while(1){
output_toggle(pin_a0) ;
}
Por lo que te dije antes, ese bucle en C va a tener duraciones diferentes, supongamos la mejor --> 4 ciclos de máquina, es viene a dar 625kHz.
Si yo quiero 250kHz --> son 10 ciclos --> tengo que insertar 6 ciclos. Lo mas simple son 6 NOPs, pero también puedo agregar una comparación que me saque del bucle o un retardo estilo: N=Nini ; while(--N) ; y que lo que me saque del bucle o me cambie Nini sea una interrupción.
debido a que ahora tengo que hacer que esa frecuencia varié poco a poco desde 1khz hasta 250kz y regrese desde 250 kz hasta 1khz y se repita constantemente por un tiempo de 3 minutos.
Eso sería sencillo si el micro tuviera PWM o si la frecuencia fuera inferior a 100kHz (usando una #INT_GLOBAL) pero para llegar a 250kHz no hay soluciones bonitas y menos para un rango de 1k a 250k.
Lo único que se me ocurre es hacer dos/tres módulos, uno común y corriente por interrupción hasta frecuencias de 30k y uno/dos chanchos de alta velocidad de 30k a 250k.
¿Por qué no uno solo chancho de 1k a 250k? --> Porque necesitarías un retardo de 16bits y eso demora mas de 6 ciclos de máquina.
Sumado otro detalle: Que la frecuencia varíe de 1k a 250k en 3 minutos... ¿Siguiendo qué ley?
¿Que la frecuencia varíe linealmente? ¿Que el período varíe linealmente? ¿Logaritmica? Además, variación continua no puede ser... ¿En cuantos saltos? ¿Una tabla?
En la borra del café no me sale nada...
-
Buena explicación, voy a ponerme a realizar pruebas a partir de mañana y practicar bastante basándome en lo que me has enseñado y si logro avanzar algo significativo lo publico.
Definitivamente voy a trabajar con la frecuencia variable que sea desde los 30 khz por ejemplo hasta los 250 khz. y que varié en 10 pasos :
30 khz, 52 khz, 74khz, 96 khz, 118 khz, 140 khz, 162 khz, 184 khz, 206 khz, 228 khz y 250 khz y luego desde la frecuencia mas alta hasta la mas baja repetidamente hasta completar el tiempo de 3 minutos.
Eduardo2, Agradecido por todo hermano, siempre he utilizado pic basic para mis pequeños proyecticos, pero quiero aprender lenguaje C.