Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

06/03/2012 #1


Atmel 128 Delay y sprintf
Hola, estoy haciendo un programa para que un robot avance 5cm se pare y me devuelva 100 valores de un sonar y un infrarrojo. El código es este:

int main(void)
{
ini_port();
while(1)
{
while(PORTC==1)
{
PORTB=0b1;
tim0=0;
while(tim0<253);
tim0=0;
while(tim0<200);
PORTB=0;
for(i=0;i<100;i++)
{
tim0=0;
ADCIR=medidaIR();
//while(tim0<3);
enviarIR(ADCIR);
//while(tim0<8);
ADCSO=medidaSO();
enviarSO(ADCSO);
}
}
}
}

ISR(TIMER0_COMP_vect)
{
tim0++;//Interrupción cada 1ms
}

unsigned int medidaIR()
{
ADMUX=(0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0) | (0<<REFS1) | (1<<REFS0);
ADCSRA|=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
return ADC;
}

unsigned int medidaSO()
{
ADMUX=(0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0) | (0<<REFS1) | (1<<REFS0);
ADCSRA|=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
return ADC;
}

void enviar_texto(char *texto)
{
while(*texto != 0)
{
UDR0=*texto;
while((UCSR0A & (1<<UDRE0)) == 0);
texto++;
}
}

void enviarIR(unsigned int ADCIR)
{
sprintf(texto,"I %d \n\r",ADCIR);
enviar_texto(texto);
}

void enviarSO(unsigned int ADCSO)
{
sprintf(texto,"S %d \n\r",ADCSO);
enviar_texto(texto);
}

Nse xk si pongo un while(tim0<8); que esta comentado en el codigo el programa no pasa de hay se realiza todo el rato la parte superior igual que si pongo otro printf arriba del todo luego como tengo el delay de 453ms el programa vuelve a petar.

Aer si alguien me puede ayudar a saber porque si envió texto al USART si pongo después o delante un delay me peta el programa. Gracias
07/03/2012 #2

Avatar de StrySG

No se si entiendo bien tu pregunta... perdon no entiendo la expresion "petar" pero, no se como esta declarada la variable (tim0) en tu codigo pero, recuerda que si es una interrupcion la variable debe ser declarada con * volatile * para que pueda interactuar con el programa principal, ademas quizá valga la pena ver el codigo de algunas funciones que no posteaste.
07/03/2012 #3


Petar me refiero que cuando lo pongo en el micro no hace nada se queda clavado. Tim0 esta declarado como valatile, mi problema es que quiero hacer un delay donde he puesto los while pero si los pongo el programa no funciona correctamente. Y ademas si pongo una variable dentro de while(PORTC==1) cuando va volviendo haber si se cumple la condición la variable se queda en 0, es decir yo pongo dentro de ese while var1=var1+5; y esa variable nunca llega a ser 10, siempre sera 0 o 5.
Las funciones que tengo son las siguientes:

ISR(USART0_RX_vect)
{
if(UDR0=='A')
{
PORTC=0b1;
}
}

ISR(TIMER0_COMP_vect)
{
tim0++;
}

unsigned int medidaIR()
{
ADMUX=(0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0) | (0<<REFS1) | (1<<REFS0);
ADCSRA|=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
return ADC;
}

unsigned int medidaSO()
{
ADMUX=(0<<ADLAR) | (0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0) | (0<<REFS1) | (1<<REFS0);
ADCSRA|=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
return ADC;
}

void enviar_texto(char *texto)
{
while(*texto != 0)
{
UDR0=*texto;
while((UCSR0A & (1<<UDRE0)) == 0);
texto++;
}
}

void enviarIR(unsigned int ADCIR)
{
sprintf(texto,"I %d \n\r",ADCIR);
enviar_texto(texto);
}

void enviarSO(unsigned int ADCSO)
{
sprintf(texto,"S %d \n\r",ADCSO);
enviar_texto(texto);
}

void ini_port()
{
DDRC=0b1;
DDRB=0xFF;
DDRE=0b11101110;
//Los 3 timers prescaler a 64
TCCR0=(1<<WGM01) | (1<<WGM00) | (1<<COM01) | (1<<COM00) | (1<<CS02) | (0<<CS01) | (0<<CS00);
TIMSK=(1<<OCIE0);
OCR0=0xFA;
TCCR1A=(1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1);
TCCR1B=(1<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10);
OCR1AH=0x13;
OCR1AL=0x88;
OCR1BH=0x01;
OCR1BL=0XF4;
TCCR3A=(1<<WGM31) | (1<<WGM30) | (1<<COM3A1) | (1<<COM3B1);
TCCR3B=(1<<WGM33) | (1<<WGM32) | (0<<CS32) | (1<<CS31) | (1<<CS30);
OCR3AH=0x13;
OCR3AL=0x88;
OCR3BH=0x01;
OCR3BL=0XF4;
//ADC
ADCSRA=(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) | (0<<ADIE);
//USART
UCSR0C=(0<<UMSEL0) | (1<<UCSZ01) | (1<<UCSZ00);
UCSR0A=(1<<U2X0);
UBRR0H=0;
UBRR0L=51;
UCSR0B=(1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0) | (1<<TXCIE0);
//Iniciar Interrupción
sei();
}
07/03/2012 #4

Avatar de StrySG

Tal vez son posibles errores, digo si usas compilador AVR-GCC:

Código:
while(PORTC==1)
no he manejado hasta ahora ATMEGA128 (que creo que usas tu), pero Para comprobar el estado de un puerto se usa PINC, porque PORTC se usa para sacar datos no?...

Además

Código:
for(i=0;i<100;i++)
 {
 tim0=0;      -- tim0 = 0
 ADCIR=medidaIR();
 //while(tim0<3);
 enviarIR(ADCIR);
 //while(tim0<8);   --segun dices aqui se enclava tu programa
 ADCSO=medidaSO();
 enviarSO(ADCSO);
 }
No estoy seguro de donde actualizas la variable tim0, pero si se hace en la interrupcion tal vez te esta fallando la funcion sprintf(); una vez me paso que cuando llamaba la funcion printf(); para sacar datos via USART desde una funcion externa a la principal--, no funcionaba bien **no se por que** pero tuve que colocar el printf(); en la funcion principal o de otra menera no "sacaba" los datos via Usart...
08/03/2012 #5


Esta tarde lo revisare lo que mas dixo mil gracias

EDITO: El problema esta en que cuando activaba las interrupciones tmb activaba la de transmisión y como no la uso se perdía el programa por esa interrupción.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.