TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: migsantiago en 17 de Abril de 2010, 16:22:30
-
Hola
Cuando estamos compilando con CCS hay ocasiones en que dentro de una interrupción queremos colocar un delay_ms. Cuando CCS ve esto deshabilita la interrupción para no volver a entrar a ella por si el delay sigue trabajando.
Creo recordar que arroja un warning... "int tmr disabled to prevent re-entrancy".
Con la ayuda de las librerías C18 de Microchip, se pueden importar las funciones DelayMs() y Delay10us() a CCS. Una vez compiladas me doy cuenta de que CCS tiene una optimización en tiempo de ejecución superior a C18.
Con FCY = 12MIPS (Fosc = 48MHz) los tiempos son:
- DelayMs(1) se ejecuta en 300us
- Delay10us(1) se ejecuta en 3us
A raíz de estos desajustes se puede simplemente crear otra función que anide las anteriores pero con nuevos nombres:
void DelayMs(int16 n)
{
while(n--)
{
Delay300us(3);
Delay3us(34);
}
}
Una vez compilada, el analizador muestra que se ejecuta en 1ms exactamente :mrgreen:
Un ejemplo con código y tiempos...
/*
Programa para poner a prueba la librería de delays modificada
*/
#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOBROWNOUT,USBDIV,PLL2,CPUDIV1,VREGEN,PUT,MCLR
#use delay(clock=48000000)
#define GetSystemClock() 48000000 //esto es lo único que hay que configurar
#include "superdelay.c"
void main()
{
int m=10;
while(1)
{
DelayMs(m);
output_b(0xFF);
DelayMs(m);
output_b(0);
}
}
http://img217.imageshack.us/img217/508/superdelay.png
(http://img217.imageshack.us/img217/508/superdelay.th.png) (http://img217.imageshack.us/img217/508/superdelay.png)
Al tener una función DelayMs() y otra nativa delay_ms() se puede insertar la nueva en una interrupción sin que CCS se oponga.
Adjunto la librería modificada. La librería original es timedelay.c de la Microchip Applications Library.
http://www.4shared.com/file/uhCIONz2/SuperDelay.html
Funciones contenidas:
Delay3us()
Delay300us()
DelayMs()
Las pruebas sólo se han hecho a 48MHz y PIC18. Es probable que a velocidades inferiores cambien los tiempos, por favor si alguien obtiene resultados diferentes que nos avise. Gracias.
-
Me chirrían los dientes al ver un delay dentro de una interrupción.
De todas formas, es muy buena aportación para cuando haga falta. Gracias Santiago.
-
Me chirrían los dientes al ver un delay dentro de una interrupción.
De todas formas, es muy buena aportación para cuando haga falta. Gracias Santiago.
:D :D De nada.
Me gustaría que hicieran pruebas con otras velocidades y checar qué tanto cambia el tiempo. :mrgreen:
-
Si usas C18 estudiantil, seguramente no tedrá la mayor optimización :?
Saludos!
-
Si usas C18 estudiantil, seguramente no tedrá la mayor optimización :?
Saludos!
No te entiendo Suky :shock: :z)
-
Tengo entendido que esa versión te limita en eso. En configuraciones de proyecto se puede trabajar con las optimizaciones. :roll: Lei tu cometario de optimización y comenté, no lei el post completo :oops: :mrgreen:
Saludos!
-
santi, tengo una duda
Al compilar los delays de C18 en CCS se ejecutan más rápido
o sea que si tengo un delay de 10 segundos en c18, ¿en ccs correría en menos de 10 segundos?
tengo entendido que el código resultante en c18 sería mas largo que en ccs, pero los 10 segundos deberían ser los mismos.
-
Hola Pedro
Exacto, si se compila un delay con el mismo código fuente...
- en C18 corre en 10s
- en CCS corre en 3s
Quiero pensar que en CCS se corre más rápido el delay porque la aritmética compilada es mucho más eficiente que la aritmética de C18.
-
Hola, mi humilde opinion. Como comento Nocturno no es recomendable o buena idea colocar un delay dentro de handler de interrupción. Con respecto a los delays y timers yo pienso que depende de la necesidad de cada proyecto. En mi caso hago lo sgte:
- Timers, estan implementadas en base a un timer y con una resolucion determinada, del orden de los 10 ms, lo utilizo cuando tengo que esperar eventos asincronicos que no puedo determinar de ante mano cuanto tardaran. Mientras espero que el evento ocurra puedo realizar otras tareas.
- Delays, en este caso no utlizo timers sino directamente una función en assembler que va variando dependiendo de la frecuencia de cristal, normalmente utilizada para esperar tiempos cortos, del orden de los microsegundos hasta unos pocos milisegundos. Mientras se encuentra ejecutando esta función las interrupciones son habilitadas para que puedan ejecutarse.
Saludos !
-
Hola Richi, sé que ejecutar código largo dentro de una interrupción es programación sucia, pero para un programa que estamos haciendo necesitamos un delay breve dentro de la interrupción y pues esto lo soluciona.
-
Hola Mig, me parece bien. Igual mas que nada mi post hiba al uso del delay, no puedo entender que dependiendo de que compilador uses tarde mas o menos, en si entiendo, debe estar hecho en C ...
Saludos !