TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: MINDFIELD en 17 de Mayo de 2015, 09:10:14
-
Buen dia tengo un par de lineas de codigo dentro del void main()
void main()
{
enable_interrupts(global);
enable_interrupts(int_ext | l_to_h);
setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);
while...
quien me puede explicar como funcionan estas dos lineas
enable_interrupts(int_ext | l_to_h);
setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);
-
Para eso deberias de tener a mano el manual de CCS ( busca en google "CCS manual"), de todas formas un poco de ingles lo soluciona.
enable_interrupts(int_ext | l_to_h);
This function enables the interrupt at the given level. An interrupt procedure should have been defined for the indicated interrupt.
Enabling interrupts does not clear the interrupt flag if there was a pending interrupt prior to the call. Use the clear_interrupt( ) function to clear pending interrupts before the call to enable_interrupts( ) to discard the prior interrupts.
TL;DR; = hanilita las interrupciones, en ese caso imagino que habilita la interrupcion externa (ext ) que es el RB0 y setea la pendiente para cuando ocurra la interrupcion en un flanco ascendente (l_to_h = low to high = bajo a alto)
setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);
Como el nombre de la funcion lo dice, es para configurar el timer 0. A veces llamado tambien RTCC.
Estaria seteandolo para que la entrada de clock sea del mismo oscilador y no de un pulso externo, con un preescaler de 128 y parece ser que tiene la opcion de ser de 16bits, pero lo configura como 8 bits.
-
Esta interrupcion crearia un ciclo de un segundo?, como saco la cuenta?
-
Utiliza el oscilador.. Asi que seria
4 / Fosc
Con un oscilador interno de 8Mhz
4 / 8Mhz = 500ns = 0.5us
Ahora tenemos el preescale de 128
0.5us * 128 = 64us
Cada 64 us cuenta 1. Suponiendo que se ponga a 0 el timer, es decir que tiene que contar 255 hasta el overflow:
64us * 255 = 0.0163s
Asi que deberias tener unas 61.35 interrupciones para llegar al segundo..
Asi que serian 61 interrupciones FULL y otra que tiene que durar:
0.35 * 0.0163s = 5.7ms
Deberia contar:
5.7ms / 64us = 89
Como el timer es un contador ascendente, deberia rellenar con el complemento a 2.
Es decir deberias cargarlo con : (256-89) = 167
A la interrupcion numero 62
Todo esto suponiendo que son 8Mhz
-
Y te puedes ayudar tambien con esta (http://www.picbasic.co.uk/forum/showthread.php?t=4994) buena herramienta :mrgreen:
Saludos
-
Gracias por responder, estoy jugando con este codigo ahora
#include <16F877A.h>
//#FUSES NOWDT, HS, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#FUSES NOWDT, HS, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#use delay(clock=16000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STREAM=PORT1)
#use standard_io(d)
int flanco=0;
int dly0=0;
int8 dly1=0;
char valor_B;
char COM0;
char COM1
#int_EXT
void EXT_isr(void)
{
output_d(0b00000000); //configuro todo el puerto b como salida
if (flanco==1)
{set_timer0(255-dly0);
while(get_timer0()>0); //espera hasta que timer0 se desborde
{
ext_int_edge(h_to_l);
flanco=0;
output_high(pin_d0);
}
}
else
{set_timer0(255-dly0);
while(get_timer0()>0); //espera hasta que timer0 se desborde
{
ext_int_edge(l_to_h);
flanco=1;
output_high(pin_d0);
}
}
if (flanco==1)
{
set_timer0(255-dly1);
while(get_timer0()>0); //espera hasta que timer0 se desborde
{ext_int_edge(h_to_l);
flanco=0;
output_high(pin_d1);
}
}
else
{
set_timer0(255-dly1);
while(get_timer0()>0); //espera hasta que timer0 se desborde
{ext_int_edge(l_to_h);
flanco=1;
output_high(pin_d1);
}
}
}
void main()
{
set_tris_b(0xff);
enable_interrupts(global);
enable_interrupts(int_ext | l_to_h);
setup_timer_0(rtcc_internal | rtcc_div_128 | rtcc_8_bit);
while (TRUE)
{
valor_B = getc();
COM = valor_B;
COM1 = valor_B;
if (COM == '0')
{
//dly0=1;
}
if (COM == '1')
{
dly0=25;
}
if (COM == '2')
{
dly0=50;
}
if (COM == '3')
{
dly0=75;
}
if (COM == '4')
{
dly0=100;
}
if (COM == '5')
{
dly0=125;
}
if (COM == '6')
{
dly0=150;
}
if (COM == '7')
{
dly0=200;
}
if (COM == '8')
{
dly0=225;
}
if (COM == '9')
{
dly0=254;
}
//****************************************************************
if (COM1 == '0')
{
}
if (COM1 == '1')
{
}
if (COM1 == '2')
{
}
if (COM1 == '3')
{
}
if (COM1 == '4')
{
}
if (COM1 == '5')
{
}
if (dly0==255) dly0=254; //no pasa de 255
if (dly1==255) dly1=254; //no pasa de 255
if (dly0==0) dly0=1; //no baja de 1
if (dly1==0) dly1=1; //no baja de 1
}
}
El problema que tengo es que cuando COM1 llegan hasta dly0=75 o dly0=100 se "bloquea" el programa en el
while(get_timer0()>0); //espera hasta que timer0 se desborde
no entiendo el porque... tambien puedo varear el valor de COM1 rapidamente en pocos segundos pero despues hace lo mismo, siempre se queda en ese while :(
-
Una posible solucion seria, preguntar por la bandera del timer0 y no tomar el valor que tiene el timer0.
Para ello borras la bandera y luego preguntas por el estado de esta.
Prueba y nos comentas. :mrgreen:
-
Como me gustaria entender todo lo que me decis :lol: voy a estudiarlo y en la proxima respuesta aviso que tal me fue...
-
Como me gustaria entender todo lo que me decis :lol: voy a estudiarlo y en la proxima respuesta aviso que tal me fue...
:shock:
ASi:
#bit Flag_TMR0= getenv("BIT:TMR0IF")
void main()
{
if(FLAG_TMR0) // Si el flag_tmr0 es igual a 1, hago algo ...
...
}
-
Gracias por tú interes, antes de hacer lo que tú dices me di cuenta que en esta linea
while(get_timer0()>0); //espera hasta que timer0 se desborde
{
está el punto y coma, de esa manera funciona pero despues queda en el bucle y si saco el punto y coma no hace nada...
-
y de la manera que me digiste RALF2 no me funciona
-
Creo que no vendría mal un poco de reorganización del código..... talves sacar algo de lo que haces en la interrupcion.
Agrega ERRORS a la directiva del RS232
-
Hola! no entiendo lo de que agrega errores a la directiva del rs232, ami no me genera ningun error ni avisos de peligro o warning, lo de organizacion si es verdad voy a tratar de hacerlo lo mejor posible! pasa que no entiendo mucho donde va cada cosa, cada directiva, sentencia o lo que sea; Estuve metiendo mano en el codigo y si al pre-escaler lo bajo a 4 obviamente no funciona igual pero no se queda en el bucle while(get_timer0()>0); porque no se queda en el bucle?
-
Me referia a lo siguiente:
Tu tienes
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STREAM=PORT1)
Yo digo que lo completes asi:
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STREAM=PORT1,ERRORS)
Al agregar el parametro ERRORS, si llegase a existir un error en la comunicacion se borrara y reseteara el modulo RS232 del PIC, continuando con la operacion normal, como dije en otros post, tambien es bueno revisar las banderas de error en el registro de estatus del modulo RS232, y de paso la ayuda de CCS
-
SOS UN MAESTRO!!!! ((:-)) ((:-)) ((:-)) ahora si fubciona!!! cuando crezca quiero ser como ustedes :mrgreen: espero poder avanzar con el codigo sin problemas!
Gracias a todos!!