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
-
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:
#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++;
}
}
-
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.
-
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.