LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: rglove em 12 de Setembro de 2012, 17:02

Título: Ajuda em código C
Enviado por: rglove em 12 de Setembro de 2012, 17:02
Boas. Há uma semanita comecei a ler algumas coisas sobre programação de microcontroladores avr em C. Aprendi já o básico, então decidi criar uma biblioteca para poder comunicar via Serial com quaisquer pinos do microcontrolador.
Vi uns gráficos que me ajudaram bastante e finalmente consegui enviar informação para o computador.
Tentei hoje então criar o código para receber a informação do computador, mas estou a ter problemas nesta parte...

O código para receber a informação funciona, mas ao incluir uma interrupção deixou de funcionar. Quer dizer, o código funciona na mesma, mas a variável buf aparece vazia no loop, assim como a buflen, apesar de ter sido alteradas na interrupção.
Quando tento fazer PrintSerial de dentro da interrupção obtenho no Serial Monitor a informação correcta, mas de fora da interrupção os valores dessas variáveis estão inalterados...
Estou a fazer alguma coisa mal?

Está aqui o código:
Código: [Seleccione]
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "Serial.h"
#include <avr/interrupt.h>

char buf[20];
int buflen = 0;

int main(void)
{
DDRB |= (1<<PB5);
TCCR1B = (1<<WGM12)|(1<<CS10);
OCR1A =  1;
TIMSK1 = (1<<OCIE1A);
DDRD &= ~(1<<PD0);
InitSerial();
sei();

    while(1)
    {
cli();
PrintSerial(buf); //Aqui a variável está vazia, pelo menos não consigo receber nada no Serial Monitor...
_delay_ms(1000);
sei();
    }
return 0;
}


ISR(TIMER1_COMPA_vect){
if ((PIND & (1<<PD0)) == 0) {
_delay_us(52);
char bits[7];
for (int i=0;i<=7;i++) {
_delay_us(104);
bits[i] = (PIND & (1<<PD0));
}
char byte = 128*bits[7] + 64*bits[6] + 32*bits[5] + 16*bits[4] + 8*bits[3] + 4*bits[2] + 2*bits[1] + 1*bits[0];
buf[buflen] = byte;
buflen++;
}
}

Título: Re: Ajuda em código C
Enviado por: senso em 12 de Setembro de 2012, 17:17
Não sei se sabes, mas existem bibliotecas que fazem isso, serial bitBanged não é tão trivial como parece.
Mas se a ideia é aprender, para começar, todas as variaveis usadas numa interrupção que sejam partilhadas por outro código têm de ser declaradas como volatile, assim:
volatile int foo;

Outra coisa, nunca se fazem delays numa interrupção, uma interrupção é para ser uma resposta rápida a um pedido externo, portanto ter delays vai contra a lógica de uma interrupção.
Título: Re: Ajuda em código C
Enviado por: rglove em 12 de Setembro de 2012, 17:33
Não sabia, vou ver isso então.
A ideia era também aprender um bocado ao fazer isto.

Já alterei as variáveis, vou ver se consigo fazer isto de outra forma, obrigado.