Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Estoy liado con el código en CSS para lanzar una trama por RS232 hacia el PC(en este caso la lectura de varias LDR por las analógicas).El problema reside que cuando lanzo la trama con Printf al parecer entra la interrupcion de TMR0 (varias veces supongo)y me corta la trama, recibiendo caracteres sin sentido en el PC, otras veces cortadas, etc. Si desabilito el TMR0 no tengo ningún problema de recibir estas tramas. ¿alguna idea al respecto?. La interrupción de TMR la tengo rápida para no equivocarme mucho porque ataco a los servos trucados utilizando la parte de electrónica (asi me ahorro los puentes en H) . Y todo esto es para hacer un Mod de Tarribot. (gracias Furri por dar luz donde hay oscuridad y muy bueno tu trabajo).
Saludos
Yo empecé hace un mes con el CCS y PIC, pero creo que mi experiencia con otros compiladores y micros puede aplicarse a estos casos.
Yo uso TMR0, RS232, PWM y no se interfieren. Prueba a poner la interrupción TMR0 vacía para que entre pero no haga nada. Lo más probable es que el código de TMR0 cambie alguna variable o algún puerto (o el tris del puerto) y eso es lo que interfiere.
Sigo teniendo el problema. En cuanto pongo la interrupción activa de TMR0 el RS232 se vuelve "inestable". En la interrupción TMR0 he probado de dejarla vacia y sigue pasando lo mismo. He mirado varios ejemplos y no he visto ninguna diferencia en como tratar la interrupción TMR0 y la interrupción serie. También he probado diferentes preescalers y la unica diferencia es que corta más o menos la trama de la serie. Todo esto lo estoy cargando con bootloader pero creo que esto no deberia tener ningún conflicto. Tiene que ser una tonteria pero no consigo verlo.
¿Que versión de CCS usas? ¿Para que PIC?. ¿Usas RC o cristal?
Puedes enviar el trozo de código de main, TMR0 y RS232 a ver si se aprecia el problema. A mi me funciona bien incluso con bootloader, para un 16F876 y CCS 3,236.
Heli,
perdona por no dar más pistas. Utilizo un 16f877A con cristal a 20Mhz.
La versión del compilador de CCS es la 3.20. (no he probado otra ¿será eso?). Es un mini programa para llevar dos servos trucados hacia adelante y atras. Como verás tengo la interrupción de TMR0 activa pero el código de la interrupción está con simbolos de comentario asi que no ejecuta nada. Ya con esto tengo problemas con el printf que saco por la USART. No soy capaz de ver porque con el TMR0 activo la USART no envia la trama bien y si pongo a disable el TMR0 entonces el envio de la trama va perfectamente. Admito todo tipo de critica con el programa (ya de paso puedo aprender más)
Pego el programa (no lo he limpiado mucho). Lo quería poner en una caja pero no se hacerlo y no tengo tiempo ahora de ponerme a investigar. Sorry.
-----------------------------------------
/* Pruebas de motor en secuencia. Dos servos conectados a B0 y B1.
Los define de motor estan alterados para ir en lenta . Substituir si necesitamos mas velocidad.
*/
#include <16F877A>
#fuses HS,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#define ADELANTE 2
#define IZQUIERDAS 3
#define DERECHAS 4
#define MOTOR_DERECHO_ADELANTE_RAPIDO 0x7f //0x01
#define MOTOR_DERECHO_ADELANTE_LENTO1 0x7f
#define MOTOR_DERECHO_ADELANTE_LENTO2 0x7E
#define MOTOR_DERECHO_PARADO 0
#define MOTOR_DERECHO_ATRAS_RAPIDO 0x81 //0xFF
#define MOTOR_DERECHO_ATRAS_LENTO1 0x81
#define MOTOR_DERECHO_ATRAS_LENTO2 0x82
#define MOTOR_IZQUIERDO_ADELANTE_RAPIDO 0x81 //0xFF
#define MOTOR_IZQUIERDO_ADELANTE_LENTO1 0x81
#define MOTOR_IZQUIERDO_ADELANTE_LENTO2 0x82
#define MOTOR_IZQUIERDO_PARADO 0
#define MOTOR_IZQUIERDO_ATRAS_RAPIDO 0x7f // 0xff
#define MOTOR_IZQUIERDO_ATRAS_LENTO1 0x7f
#define MOTOR_IZQUIERDO_ATRAS_LENTO2 0x7E
#define MOTOR_CENTRADO 0x80
#define MOTOR_PARADO 0x00
#define MOTOR_DERECHO 0x01
#define MOTOR_IZQUIERDO 0x00
//#use standard_io(b)
#use fast_io(B)
int8 x,val,duty,timer0,dato,retardo,refe,ldr_izquierda_valor,ldr_derecha_valor,ldr_centro_valor,movimiento;
int1 led=FALSE,tick=FALSE,startPWM;
int8 duty_pwm[8],permiso_pwm[8];
void motorizacion(int8);
void secuenciador(void);
unsigned int contador;
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#ORG 0x1f00, 0x1FFF{}
#int_rda
void serial_isr(){
if (kbhit()){
refe=getc();
}
}
#int_TIMER0
void RTCC_isr(){
/*
x++;
if (x==3){
set_RTCC(100); // porque he tenido que redondear dar más tiempo (retardo) para que no vibre?
}
if (x>=4){
tick=TRUE;
x=0;
}
*/
}
void motorizacion(int8 valor){
switch(valor){
// motores parados
case 1: duty_pwm[MOTOR_DERECHO]=MOTOR_PARADO;
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_PARADO;
// printf ("Motores parados nr");
break;
// Hacia adelante a tope
case ADELANTE: duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ADELANTE_RAPIDO; // motor izquierdo adelante
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ADELANTE_RAPIDO; // motor derecho adelante
// printf ("Hacia adelante nr");
break;
// Hacia la izquierda ***
case IZQUIERDAS: duty_pwm[MOTOR_IZQUIERDO]=MOTOR_PARADO; // motor izquierdo parado
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ADELANTE_RAPIDO; // motor derecho hacia adelante
// printf ("A izquierdas nr");
break;
// Hacia la derecha ***
case DERECHAS: duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ADELANTE_RAPIDO; // motor izquierdo hacia adelante
duty_pwm[MOTOR_DERECHO]=MOTOR_PARADO; // motor derecho parado
// printf ("A derechas nr");
break;
// Hacia atras ***
case 5: duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ATRAS_RAPIDO; // motor izquierdo hacia atras
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ATRAS_RAPIDO; // motor derecho hacia atras
// printf ("Atras nr");
break;
case 6: // Giro izquierda
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ATRAS_RAPIDO; // motor izquierdo hacia atras
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ADELANTE_RAPIDO; // motor derecho hacia adelante
// printf ("Giro izquierdas nr");
break;
case 7: // Giro derechas
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ADELANTE_RAPIDO; // motor izquierdo hacia adelante
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ATRAS_RAPIDO; // motor derecho hacia atras
// printf ("Giro derechas nr");
break;
case 8: // marchas lentas centrada
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_CENTRADO; // motor izquierdo centrado
duty_pwm[MOTOR_DERECHO]=MOTOR_CENTRADO; // motor derecho centrado
// printf ("Marcha lenta centrado. Preparado para ajustesnr");
break;
case 9: // marchas lenta1 hacia adelante
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ADELANTE_LENTO1; // motor izquierdo lento hacia adelante
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ADELANTE_LENTO1; // motor derecho lento hacia adelante
// printf ("Marcha lenta 1 hacia adelantenr");
break;
case 10: // marchas lenta2 hacia adelante
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ADELANTE_LENTO2; // motor izquierdo lento 2 hacia adelante
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ADELANTE_LENTO2; // motor derecho lento 2 hacia adelante
// printf ("Marcha lenta 2 hacia adelantenr");
break;
case 11: // marchas lenta1 hacia atras***
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_IZQUIERDO_ATRAS_LENTO1; // motor izquierdo lento hacia atras
duty_pwm[MOTOR_DERECHO]=MOTOR_DERECHO_ATRAS_LENTO1; // motor derecho lento hacia atras
// printf ("Marcha lenta 1 hacia atrasnr");
break;
default : // printf("Comando no reconocido");
}
}
void secuenciador (void){
set_adc_channel(0);
delay_us(3);
ldr_izquierda_valor=read_adc();
set_adc_channel(1);
delay_us(3);
ldr_derecha_valor=read_adc();
set_adc_channel(2);
delay_us(3);
ldr_centro_valor=read_adc();
printf("-- Izquierda %3u ----- Derecha %3u ----- Centro %3u nr",ldr_izquierda_valor,ldr_derecha_valor,ldr_centro_valor);
movimiento=ADELANTE;
if ((ldr_centro_valor-ldr_izquierda_valor)>50) movimiento=IZQUIERDAS;
if ((ldr_centro_valor-ldr_derecha_valor)>50) movimiento=DERECHAS;
motorizacion(movimiento);
}
void main(){
setup_counters(RTCC_INTERNAL,RTCC_DIV_64| RTCC_8_BIT); // TIMER0: Clock Interno y Preescaler
// setup_timer_1(T1_DISABLED);
// setup_timer_2(T2_DISABLED,0,1);
// setup_comparator(NC_NC_NC_NC);
// setup_vref(FALSE);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports( ALL_ANALOG );
set_tris_b(0x00);
disable_interrupts(GLOBAL);
enable_interrupts(int_TIMER0);
enable_interrupts(int_rda);
enable_interrupts(GLOBAL); // Habilito Interrupciones
output_low(PIN_B0);
output_low(PIN_B1);
duty_pwm[MOTOR_IZQUIERDO]=MOTOR_PARADO;
duty_pwm[MOTOR_DERECHO]=MOTOR_PARADO;
retardo=0;
dato=0;
do{
if (tick==TRUE){
if (duty_pwm[0]){
output_high(PIN_B0);
permiso_pwm[0]=TRUE;
}
if (duty_pwm[1]){
output_high(PIN_B1);
permiso_pwm[1]=TRUE;
}
tick=FALSE;
}else secuenciador();
timer0=get_timer0();
if (permiso_pwm[0]==TRUE){
if (timer0>=duty_pwm[0]){
output_low(PIN_B0);
permiso_pwm[0]=FALSE;
}
}
if (permiso_pwm[1]==TRUE){
if (timer0>=duty_pwm[1]){
output_low(PIN_B1);
permiso_pwm[1]=FALSE;
}
}
}while(true);
}