TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: fr4n en 12 de Octubre de 2011, 05:29:03
-
Hola a todos, estoy usando un PIC 18F4550. Programo en C usando CCS.
Uso un cristal externo de 20Mhz, pero mi sistema funciona a 48Mhz (mediante trasformaciones PLL)
He estado buscando información el foro sobre el tema de los timers, pero no me queda claro.
Necesito una interrupción cada 10ms (milisegundos) y he visto que se usa esta fórmula:
(256-TMR0) = Temporización / (ciclo de instrucción * Divisor de frecuencia)
Necesito usar el timer0, solo necesito que se interrumpa cada 10ms, pero no entiendo que valores debo meter para cargar ese tiempo.
No se que valor de prescaler poner ni de ciclo de instrucción (¿20 Mhz o 4Mhz?), no se si servirá de algo, pero tengo usando estos fuses, no se si alguno indica el prescaler que se está usando:
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL5 //Divide By 5(20MHz oscillator input)
#FUSES CPUDIV1 //No System Clock Postscaler
#FUSES USBDIV //USB clock source comes from PLL divide by 2
¿Que valor le tengo que cargar? o como lo calculo realmente?
Segun el datasheet el prescaler (¿divisor de frecuencia?) máximo de mi PIC es 256 y usando ese valor, si hago las cosas bien, me sale un número negativo ¿alguien puede ayudarme?
Muchas gracias!
-
Si tu sistema funciona a 48MHz el ciclo de instrucción es 4/48M --> 83.333ns. Siempre el ciclo de instrucción es de 4/clock de CPU
Fijate en el datasheet tanto en el esquema de la configuración del oscilador como en la del timer0. En la del timer0 figura que la entrada puede ser T0CKI (que sería RA4) o sino Fosc/4 (es la frecuencia de CPU).
Usando ese clcok y suponiendo un prescaler de 256 y el Timer0 en 16 bits, generaría la interrupción cada
83.333n(ciclo de instrucción) * 256(prescaler) * 65536(timer0 en 16 bits) --> 1.398s
si en cambio utilizas el prescaler en 64 sería 83.333n * 64 * 65536 --> 349.511ms
con prescaler en 2 sería 83.333n * 2 * 65536 --> 10.922ms
-
Pensaba que el Timer0 era de 8 bits :shock:
Muchisimas gracias! salvo ese detalle, creo que me ha quedado todo claro :)
Gracias!
-
Hola, te puede servir tambien el PIC Timer Calculator By Redraven (http://picmania.garcia-cuervo.net/recursos/rrpictimercalculator.zip).
Saludos
-
Pensaba que el Timer0 era de 8 bits :shock:
Hay que tener el datasheet a mano ;-)
-
Muchas gracias a todos!
En CCS, como quedaría la rutina de configuración entonces, asi?
setup_timer_0(T0_INTERNAL | T0_DIV_2 | T0_16_BIT); ???
Y la rutina de interrupción en ccs, si no me equivoco, será asi, no?
#int_TIMER0
void TIMER0_isr(void) {
Código
}
Falla algo?
Gracias!
-
No uso CCS pero aparentemente parecería estar bien.
También, si queres tener mas aproximado una interrupción cada 10ms podes poner el prescaler en 4 y precargar el timer0 con x valor para que el tiempo sea mas cercano a los 10ms.
10ms = 83.333ns * 4 * x (siendo x el valor que tiene que contar el timer0) --> 10ms = 333.332n * x -->
x =(aproximadamente) 30000
Luego, para que el timer cuente 30000 tendrías que hacer valor_precarga = 65536 - 30000 --> timer0 = 35536.
La precarga la tendrías que hacer al comienzo y cada vez que se ejecuta la interrupción, así siempre la cuenta será de 30000 ciclos.
-
La instrucción para cargarle ese tiempo es así?
TIMER0(35536); ???
Muchas gracias, eres un crack! :)
Saludos!
-
La instrucción para cargarle ese tiempo es así?
TIMER0(35536); ???
Muchas gracias, eres un crack! :)
Saludos!
Hola fr4n, utiliza la ayuda de CCS alli encontraras la sintaxis usada por el compilador. Tambien encontraras codigo de ejemplo, aca en el foro también hay información a montones.
saludos.
-
Si, muchas gracias, ya habia mirado la ayuda (aunque no me entero bien con el inglés) y también habia mirado el foro (por eso he llegado a la conclusión de que se hace como expongo arriba), pero tenía dudas de saber si era correcto o no porque el compilador me da errores en esa línea.
Muchas gracias!
EDITO: Era un despiste, es y setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); set_TIMER0(35536); parece ser. Gracias.