TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: mrgse en 06 de Mayo de 2009, 08:14:56
-
Hola soy nuevo en el foro y necesito un poco de ayuda para programar mi PIC 16F877. Lo que pretendo es que el PIC vaya ejecutando su programa, en el que hay delays, y se interrumpa cuando reciba una interrupcion desde el PC. Mi duda es, si la interrupcion llega durante un delay, el delay se interrumpe, o espera a que termine??
Si espera a que termine, como podria hacer para tener un delay de 5 minutos y si surgiera una interrupcion durante esos 5 minutos, el programa la tratase, y luego siguiera con el delay donde lo havia dejado?
Otra pregunta, cual es el delay_ms maximo que se puede hacer??
Muchas gracias!!
-
Hola mi consejo es q dado el tipo de programa q quieres hacer utilices solo la interrupcion, q te cuente con otra variable los cinco minutos dentro de la interrupcion.
Ademas creo q los delay no son tan precisos y la verdad q no creo q sea ortodoxo usar un delay de 5 minutos dado q se pararia todo el programa durante 5 minutos .
Pon aqui el codigo aver si te puedo aconsejar mejor.
-
hola mrgse
como su nombre lo indica Interrupcion, cuando se produce una INT. el programa se detiene donde este y atiende la interrupcion, a menos que este atendiendo otra enterrupcion de mayor prioridad.
ahora como dijo juansi los delays no son precisos y para 5 minutos tenedras una gran variacion de tiempo. seria mejor utilizar la interrupcion del TMR0 para que te cuente los 5 min. y asi no tendras que esperar a que termine el delay.
salu_2 a to_2
-
No se si hablo con motivo, pero por mi experiencia es igual de ineficiente un delay que un timer...
Cuando hice el temporizador de mi insoladora el pic no era capaz de contar eficientemente 2 minutos... se retrasaba como 4 segundos...
Internamente, creo que un delay es lo mismo que el timer... al fin y al cabo, lo que hace el delay es generar un bucle que durara X instrucciones... que seran X ciclos de reloj, y eso es lo mismo que cuenta un timer... por lo que la impresicion sera la misma... el problema esta en que nuestro oscilador realmente este trabajando a los mhz que creemos... el oscilador interno del pic creo que tiene un margen de error de 1%... los cristales externos creo que son mas precisos... pero no me fio... :?
-
Gracias por las respuestas. Cuando tenga el programa más avanzado lo pondré. Podriais decirme como programar el tmr0 para que cuente 5 minutos? Cuando se reciba la interrupcion, necesito que se trate, pero el contador debe seguir contando esos 5 minutos. para poder continuar el programa cuando el contador termine.
-
Hola.
Pues todo depende del cristal que estes usando -y tambien del compilador- Si se quiere conteos muy presisos de tiempo, lo mejor es usar el timer1 como contador externo y conectarle un cristal de esos de 32k768. Otra opcion, un reloj de tiempo real.
-
mrgse. lo primero es calcular el tiempo para el timer0, (1 segundo por ejemplo) ¿saes hacerlo?,bueno cuando lo calcules haces la variale de modo que te cuente el tiempo q necesitas (300 seg) y al llegar al tiempo por ejemplo puedes incrementar otra variale para cuando esta ultima sea i=1 te haga la funcion , comando etc... q quieras.
Espero que esto te ayude un poco.
-
para que entiendas un poquito mas como hacer el contador, primero piensa que el timer0 cuenta de 0 a 255, y en el paso de 255 a 0 se genera la interrupcion.
dependiendo de la frecuencia de tu cristal el timer ira mas rapido o mas despacio, pero siempre sumara uno cada una instruccion. una instruccion es igual a cuatro ciclos de reloj. si tienes un cristal de 4mhz, tendras que se ejecutan 1.000.000 de instrucciones por segundo, es decir, una instruccion cada 1uS. Eso quiere decir que el timer durara 256uS antes de la interrupcion, si no usas un prescaler.
deberas esperar unas 3906 interrupciones de este timer para contar un segundo. Y 1.171.875 interrupciones para contar 5 minutos... usando prescaler no tendras que contar numeros tan altos.
investiga un poco sobre el timer0 y su prescaler. hay ejemplitos por el foro. no te sera dificil contar ese tiempo, aunque repito, dudo que sea muy preciso.
Salu2
-
Muchas gracias. Investigare y en caso de duda volvere a postear
-
No estaria demas que digas que compilador usas y la frecuencia con la que corres al PIC si quieres que te demos codigos, total no es tan dificil.
Suerte.
-
No se si hablo con motivo, pero por mi experiencia es igual de ineficiente un delay que un timer...
Cuando hice el temporizador de mi insoladora el pic no era capaz de contar eficientemente 2 minutos... se retrasaba como 4 segundos...
Internamente, creo que un delay es lo mismo que el timer... al fin y al cabo, lo que hace el delay es generar un bucle que durara X instrucciones... que seran X ciclos de reloj, y eso es lo mismo que cuenta un timer... por lo que la impresicion sera la misma... el problema esta en que nuestro oscilador realmente este trabajando a los mhz que creemos... el oscilador interno del pic creo que tiene un margen de error de 1%... los cristales externos creo que son mas precisos... pero no me fio... :?
Esto no es exactamente así, Marttyn. Con un Timer se puede conseguir exactitud en la medición del tiempo, si el cristal es bueno y el software de la interrupción también lo es.
Con delays es imposible porque mientras se ejecuta la interrupción el delay está parado, así que su precisión dependerá de las interrupciones que lleguen y eso no se controla.
La diferencia entre ambos es que el delay usa el core del micro para contar ciclos, mientras que el Timer los cuenta él solito.
-
Tienes razon, estaba asumiendo que es programa solo estaria pendiente del delay. Si hubiese alguna interrupcion se desbarajusta todo :mrgreen:
Lo de la presicion del timer no se que decir... Estaba usando el oscilador interno del pic, y la rutina para contar era EXACTA para que de un segundo, ni una instruccion mas, medido con mplab. Y tuve q modifucarla, porque me contaba unos 5 segundos de desfase (no recuerdo si de mas o de menos) cada 2 minutos y medio aprox... :(
-
El oscilador interno del pic es igual de práctico que de impreciso. Para aplicaciones donde la medición del tiempo sea crítica hay que usar cristales u osciladores de cuarzo.
-
Sabias palabras manolo! Mirando el data del 16F648A dice que el oscilador interno funciona "tipicamente" a 4mhz, con un min y un max de 3.92 y 4.08 respectivamente...
Hace MUUUUUCHO que no uso un cristal, pero supongo que tendre que implementarlos cuando tenga que hacer algo con un poquito de precision :mrgreen:
-
y los errores de los cristales son en partes por millón, los comunes que venden en las tiendas supongo serán algo imprecisos, si puedes saber las ppm también ayuda a escoger un cristal
-
una pregunta para los heroes del foro ¿si tengo en un programa muchos delays pueden afectar de alguna manera al tiempo de mi timer0?
gracias
-
No
-
Hola de nuevo, finalmente lo que he hecho es un bucle de 300 repeticiones de un delay de 1 segundo junto a una comprovacion de si se ha recibido un caracter en el buffer de recepcion (de un ST485). De esta manera, si entra en la comprovacion, puedo saber cuantos segundos han pasado, por tanto, cuantos kedan, y realizar los calculos pertinentes conociendo el tiempo de la ejecucion de la funcion que se realiza si he recibido un caracter. Esquematicamente:
Interrupcion: Cuando llega un caracter al buffer, una variable "recibido" cambia . Nada mas.
En el programa principal, un bucle de 300 repeticiones realiza:
- Un delay de 1 segundo
- Comprobacion de si la variable "recibido" ha cambiado
Si la variable no ha cambiado, no pasa nada.
Si ha cambiado, hace una serie de cosas, que tardan X tiempo que puedo calcular, pasarlo a su equivalente en repeticiones, y asi no desfasarme de los 5 minutos.
Lo pongo asi porque el programa en si no esta escrito completamente ni probado.
-
mrrse yo de todas formas intentaria usar el timer0, si el caracter llega durante el delay no se si lo leera bien la verda y ademas pienso q con el timer0 no tendrias q calcular ese tiempo X del q hablas.
de todas formas cuelga el codigo cuando lo tengas pa echarle un ojo (por curiosidad).
-
juansi, si el caracter llega durante un delay no habra problema porque la interrupcion se activara igual (si tiene USART por hard, si lo hace por soft no hay interrupcion, y no se como seria).
Realmente hacer la temporizacion con un timer de 8bits es algo engorroso, y la opcion de los delays es mas elegante dentro de lo que cabe...
-
usar timer para hacer delay es lo mejor que hay, porque allí tu defines la base de tiempo que quieras, una interrupción ocurrirá en cualquier proceso donde te encuentres (salvo en la propia interrupción).
El truco de usar timer es precisamente administrar el tiempo para que se ejecuten otros procesos, si por ejemplo defines una base de tiempo de 20 ms, bueno lo que te queda es dividir el delay que necesitas entre 20ms y ese número corresponde a las iteraciones de interrupción del timer.
En caso de necesitar precisión, deberás por el medio que sea (simulación, osciloscopio, etc) ir midiendo los ciclos que consumen las instrucciones que existan de por medio para ir ajustando el número de iteracciones, es decir, terminas tu código completo y después ajustas los valores del delay requerido.