TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: manex_1987 en 27 de Noviembre de 2006, 11:53:16
-
Hola
'Amos a ver.. que compilo mi programa, con sus ajustes, todo bien... lo mando a simular al proteus, y descubro que a partir de cierto segmento del programa, se "estanca" el programa. Miro en el debug del proteus, y pone que "no source line in adress 0x3C9". Voy al PICC, miro en el ASM_OUTPUT, y sorpresa! El compilador ha metido la instruccion SLEEP en la direccion 0x3C8!! Lo que es mas sorprendente... al principio de una subrutina!
VARIABLES.C
int16 time=0;
int LED[4]={0x01,0x02,0x04,0x08};
int16 TVALUE=0;
int16 TVALUEPREV=0;
int16 TMAX=0x0000;
int16 TMIN=0xFFFF;
int16 TMED=0;
int count=0;
int Pulse_Status=0;
int16 DIFF=0;
int16 RNDFACTOR=0; //factor aleatorio del tiempo
int DF;
int a,b;
int randval;
int16 randval2;
MAIN.C
#include <16f876.h>
#use delay(clock=20000000)
#fuses HS,NOWDT
#include <lcdPORTC.c>
#include <stdlib.h>
#include <variables.c>
#define SET_LED(x) (output_a(x || input(PIN_A5))
#define SET_BUZZER(x) (output_bit(PIN_A5,x))
#define READ_PULSE() (!input_b() && 0x0F)
int16 Difficulty();
void Game();
void main()
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
set_timer1(0);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RB);
lcd_init();
setup_adc_ports(NO_ANALOGS);
set_tris_a(0x00);
set_tris_b(0xF0);
port_b_pullups(TRUE);
printf(LCD_PUTC,"Medidor Reflejos");
printf(LCD_PUTC,"***Manex 2006***");
//delay_ms(1000);
DIFF=Difficulty();
DIFF=800-100*DIFF;//PROVISIONAL: tiempo que pasa desde pulsar un boton
//hasta encenderse otro led
Game();
while(1);
}
int16 Difficulty()
{
lcd_putc('\f');
lcd_gotoxy(1,1);
printf(LCD_PUTC,"Dificultad:1 2");
printf(LCD_PUTC,"PULSAR 3 4");
DF=0;
while(DF=0) //Rutina de lectura y evitacion de datos erroneos
{
do{
Pulse_Status=READ_PULSE();
}while(Pulse_Status==0);
switch (Pulse_Status){
case 0x01: DF=1;
break;
case 0x02: DF=2;
break;
case 0x04: DF=3;
break;
case 0x08: DF=4;
break;
default: break;
}
}
lcd_putc('\f');
return DF;
}
void Game()
{
printf(LCD_PUTC,"Preparado...");
for(a=5;a==0;a--)
{
lcd_gotoxy(2,1);
printf(LCD_PUTC,"%u",a);
}
lcd_putc('\f');
time=0;
set_timer1(0xEC77);
enable_interrupts(GLOBAL);
for(a=32;a==0;a--)
{
SET_BUZZER(1);
delay_ms(100);
SET_BUZZER(0);
b=get_timer0();
randval=(b/64)+1;
randval2=DIFF+b*3;
do
{
Pulse_Status=READ_PULSE(); //Esperamos a que no haya ninguna tecla pulsada
}while(Pulse_Status!=0x00);
delay_ms(randval2);
SET_LED(LED[randval])); //?????COMPILADOR EXIGE PARENTESIS ADICIONAL????????
TVALUEPREV=time;
do
{
}while(Pulse_Status=LED[randval]); //pulsador coincide con LED
TVALUE=time;
TVALUE=TVALUE-TVALUEPREV; // sacamos el lapso de tiempo entre luz...pulsador
if(TVALUE>TMAX) TMAX=TVALUE; //maximo
if(TVALUE<TMIN) TMIN=TVALUE; //minimo
TMED=TMED+TVALUE/32; //media en 32 intentos
}
}
#INT_TIMER1
void isr()
{
set_timer1(0xEC77); //1msec de timer
if(time++==0xFFFF) time=0; //capacidad:65,535 sec
}
#INT_RB
void isr2()
{
Pulse_Status=READ_PULSE();
}
Resumiendo, se trata de generar el encendido aleatorio de un LED, y de cronometrar el tiempo hasta pulsar el pulsador que le corresponde. Se observa, que despues de MAIN viene DIFFICULTY. Pues cuando miro el asm generado, descubro que la instruccion SLEEP viene... justo cuando empieza lo referente a la subrutina DIFFICULTY!
Es decir, es bien sabido que al final de MAIN siempre viene un sleep (para marcar el fin del programa), pero a mi me lo mete en la siguiente funcion!
Aver si podeis ayudarme... culpa del proteus no creo que sea, pues lo irracional viene desde el mismo ASM!
Bug del CCS? Mal programado (pero bien compilado)?
salu2!
-
Hola Manex, he revisado tu código por encima y he encontrado que te falta un parentesis de cierre en la siguiente línea:
#define SET_LED(x) (output_a(x || input(PIN_A5))
por lo tanto te sobra el de esta línea:
SET_LED(LED[randval])); //?????COMPILADOR EXIGE PARENTESIS ADICIONAL????????
saludos,
Mario
-
Gracias por la correcion! Realmente no comprendia porque me pedia un parentesis adicional.
Pero el problema sigue ahi, he vuelto a compilar (con la correcion) pero el SLEEP sigue ahi :S
-
Manex como bien dices, se coloca un SLEEP al final del MAIN, y si miras bien está colocado al final, ya que la posición de memoria que ocupa es la última utilizada. No tengo ni idea de porque el compilador ordena las líneas de esa forma.
Mirando el código he detectado un par de errores, puede ser por eso por lo que no te funcione:
while(DF=0) //Rutina de lectura y evitacion de datos erroneos
}while(Pulse_Status=LED[randval]); //pulsador coincide con LED
saludos,
Mario
-
Hola Manex....
con la info q pusiste no se puede ver todo, pero el ccs normalmente pone un sleep al final del main para q si el programa se va de viaje al final del codigo entre en ahorro de energia y pare.
ademas el compilador reordena tu codigo poniendo siempre la rutina main al final del mismo al momento de compilar, yo no habia notado el problema pq siempre pongo el main al final.
de cualquier manera te diria q no es un problema en si en el programa sino en la manera q lo muestra, hice una prueba y puse una rutina a continacion del main y esto es lo q aparecio...
0000 02131 .................... void prendoLuzPatio2()
0000 02132 .................... {
02CF 0063 02133 SLEEP
0000 02134 .................... pLuzPatio= 1;
0084 1405 02135 BSF 05.0
0000 02136 .................... }
0085 2AC4 02137 GOTO 2C4 (RETURN)
0000 02138 ....................
como podras ver el sleep aparecio dentro de la ruina nueva pero si uno mira con mas detalle vera q la direccion del SLEEP es 0x2CF q es el final del programa y la rutina en si la codifica a partir de la direccion 0x85 ( como se ve arriba)
En definitiva, el codigo y la ejecucion seran buenos y solo lo muestra de una manera confusa.
Suerte.
-
Hola y gracias por las respuestas.
Entonces, no entiendo... en el proteus, en el LCD se aprecia una ejecucion correcta hasta por lo menos las lineas
printf(LCD_PUTC,"Medidor Reflejos");
printf(LCD_PUTC,"***Manex 2006***");
pero luego llamo al procedimiento Difficulty(); y la ejecucion inmediata es esta:
lcd_putc('\f');
lcd_gotoxy(1,1);
printf(LCD_PUTC,"Dificultad:1 2");
printf(LCD_PUTC,"PULSAR 3 4");
Pues el LCD se borra, pero ni rastro de todo lo demas... y lo dicho, en la pantalla de debug (donde vemos la linea que se ejecuta) aparece "No source program in adress XXXX"
en fin...