LusoRobótica - Robótica em Português

Sistemas específicos => Arduino / AVR => Tópico iniciado por: SJD22 em 14 de Setembro de 2011, 01:32

Título: AVR - UART Receive
Enviado por: SJD22 em 14 de Setembro de 2011, 01:32
Boas.

Estou de volta da programação do meu atmega1280 mas saltando por cima do Arduino. Estou a trabalhar directamente no AVR Studio, embora com um editor externo... Adiante...

Estou a tentar fazer um método para receber dados pela UART. Estou a usar um módulo GM862 e consigo enviar os dados na boa, mas receber as coisas sao mais complicadas. So consigo receber 3 caracteres e depois não recebo mais nada. A ideia é fazer um metodo amigável tipo o Serial.Read() que existe na plataforma do Arduino.

O código para receber que estou a usar é este:

Código: [Seleccione]
uint8_t USART_vReceiveByte() {
while((UCSR1A&(1<<RXC1)) == 0) {
};
return UDR1;
}

Ajudas?

Obg.
Título: Re: AVR - UART Receive
Enviado por: CBX em 14 de Setembro de 2011, 01:53
esse excerto de código só está a retornar 1 caracter, precisas de um buffer para armazenar temporariamente o que estás a receber
Título: Re: AVR - UART Receive
Enviado por: xiserre em 14 de Setembro de 2011, 01:54
ja experimentaste utilizar a interrupção que e gerada quando a usart recebe um byte?? lol
Tipo, quando a interrupçao acontece, les o byte e ta feito.. Nao te bloqueia o codigo..
Título: Re: AVR - UART Receive
Enviado por: SJD22 em 14 de Setembro de 2011, 02:02
CBX: isso mesmo. O que eu faço é executar esse codigo infinitamente ate encontrar o terminador de linha.... mas ele so recebe 3 caracters :( Como faço isso do buffer?
xiserre: como faço isso? :) Mas por acaso eu quero que bloqueie o codigo ate encontrar o caracter termiandor de linha...

Estas programações de baixo nivel trocam-me todo... :)

Obg.
Título: Re: AVR - UART Receive
Enviado por: xiserre em 14 de Setembro de 2011, 02:13
nao precisas de bloquear enquanto nao recebes o carry... Quando recebes tudo, activas uma flag... Configuras a usart para activar a  interrupçao de rx complete, e trabalhas dentro dessa rotina..
Título: Re: AVR - UART Receive
Enviado por: SJD22 em 14 de Setembro de 2011, 23:52
Isto está a tornar-se doloroso... sem código de exemplo não chego lá.
 :(
Ninguém tem exemplos concretos?

Obg
Título: Re: AVR - UART Receive
Enviado por: CBX em 15 de Setembro de 2011, 00:37
1º precisas de criar um array para armazenar a palavra que recebes:

Código: [Seleccione]
char buffer[10];
depois precisas de uma variável que receba o caracter do registo UDR:

Código: [Seleccione]
X = UDR1;
e de outra que diga qual a posição no array, Y

depois basta mandar os caracteres 1 a 1 para o array:

Código: [Seleccione]
buffer[Y] = X; //copia o valor do UDR1 para a posição Y do array
Y++;
}

não sei se me fiz entender, alguma duvida diz...
Título: Re: AVR - UART Receive
Enviado por: SJD22 em 15 de Setembro de 2011, 01:23
Percebi tudo CBX, obrigado,  mas eu se calhar não me expliquei bem logo ao inicio.

É assim:

1) envio um comando AT na boa para o módulo
2) estou a usar esta função:
Código: [Seleccione]
uint8_t USART_vReceiveByte() {
while((UCSR1A&(1<<RXC1)) == 0) {};
return UDR1;
}

3) Essa função de cima é chamada dentro de um ciclo while. Dentro desse ciclo while eu mostro no ecran (neste caso envio para a porta de serie que está ligada ao computador) o que recebi atraves dessa função.

Ou seja, neste caso nao preciso de acumular nada num array porque envio para o ecran.

Acontece que so recebo meia duzia de caracteres e nao a totalidade do que deveria receber... :(

Título: Re: AVR - UART Receive
Enviado por: zordlyon em 15 de Setembro de 2011, 08:25
isso é simples, é devido ao Return...

O return é a mesma coisa que um "break" num case... ele acaba-te essa função assim que faz return..

Agora não percebo é como ele até manda 3 caracteres, porque com esta logica so mandaria 1 e acabava..

Isso de estar dentro de um while infinito não interessa, quando fazer return, ele sai da função, voltando para o proximo passo no main..

Cumprimentos,
André Carcalho.
Título: Re: AVR - UART Receive
Enviado por: SJD22 em 15 de Setembro de 2011, 09:47
Não percebeste o que eu disse. Essa função faz return e retorna-me o caracter. Mas a chamada a essa função está dentro de outro ciclo WHILE. Ou seja, a função está infinitamente a ser chamada.

Isto está assim:

Código: [Seleccione]
uint8_t u8Data;
while(true) {
    u8Data = USART_vReceiveByte();
    // Nesta linha mostra o caracter recebido no computador.
}

Ou seja, isso deveria mostrar-me tudo o que é recebido... certo?
Título: Re: AVR - UART Receive
Enviado por: zordlyon em 15 de Setembro de 2011, 11:40
Certo, mas quando ele não recebe nada fica ali em ciclo infinito, e não será por estar bastante tempo em ciclo infinito e como não tens grande poder de processamento, ele não crasha?

Eu sou da opinião de que, se usasses um array era muito mais simples..

Sempre que mandavas um caracter ou mensagem criavas um array dinamico com o tamanho do caracter e depois bastava ler o array..
Para teres o tamanho da mensagem, bastava ao escreveres a mensagem, chamavas uma função lenght() em que te percorria a mensagem e via o tamanho..depois fazias um concat() e adicionavas ao fim da mensagem o tamanho da mensagem.
Ao ler, percorrias o array até ao fim, e depois fazias um malloc() com o tamanho da mensagem..


Cumprimentos,
André Carvalho.
Título: Re: AVR - UART Receive
Enviado por: terran em 15 de Setembro de 2011, 17:20
Viva, porque não fazes uma trama quando envias? Tipo, fazes bloco de mensagem fixa e as que tiverem pouco, acrescenta com "bolas de ar".  Tipo SDH (não sei se sabes o que é)

Deste género |# | 1 | 2 | 3 |  em que sabes que sempre que recebes um #, é o início da informação, assim, sempre que vais recebendo fazes como já foi dito (a operação do array). Quando receberes um novo "#" sabes que tens de preencher um novo array. Pegas no que já recebeste e mandas processar, e por aí a fora ....

PS: Se encontrar esse código que fiz em tempos, eu depois mando-te (se até lá não conseguires resolver o problema).
Título: Re: AVR - UART Receive
Enviado por: zordlyon em 15 de Setembro de 2011, 17:25
Viva, porque não fazes uma trama quando envias? Tipo, fazes bloco de mensagem fixa e as que tiverem pouco, acrescenta com "bolas de ar".  Tipo SDH (não sei se sabes o que é)

Deste género |# | 1 | 2 | 3 |  em que sabes que sempre que recebes um #, é o início da informação, assim, sempre que vais recebendo fazes como já foi dito (a operação do array). Quando receberes um novo "#" sabes que tens de preencher um novo array. Pegas no que já recebeste e mandas processar, e por aí a fora ....

PS: Se encontrar esse código que fiz em tempos, eu depois mando-te (se até lá não conseguires resolver o problema).

Isso so tem o problema de ter memória desperdiçada, isso é um array fixo, com ou sem bolas de ar não interessa..ta lá o espaço ocupado..daí o malloc ter a sua vantagem, aloca aquilo que é necessário...mas não discordo da sua opinião, além de válida se for para uma coisa simples só para testes ou assim é mais que válida..  ;)

Cumprimentos,
André Carvalho.
Título: Re: AVR - UART Receive
Enviado por: CBX em 15 de Setembro de 2011, 18:21
não precisa de saber quando começa, apenas quando acaba, um simples if (UDR == 0x0D) {"contador" = 0} para reiniciar o contador quando tens uma break line serve (se não me engano o 0X0D é igual a /n)

@ SJD22 é mais fácil se mostrar o código inteiro...
Título: Re: AVR - UART Receive
Enviado por: terran em 15 de Setembro de 2011, 19:06

Isso so tem o problema de ter memória desperdiçada, isso é um array fixo, com ou sem bolas de ar não interessa..ta lá o espaço ocupado..daí o malloc ter a sua vantagem, aloca aquilo que é necessário...mas não discordo da sua opinião, além de válida se for para uma coisa simples só para testes ou assim é mais que válida..  ;)

Cumprimentos,
André Carvalho.

Yeap, tem toda a razão... quando usei tinha tamanho de tramas fixas, daí ter falado nas "bolas de ar" pois como tinha CRC, e essa fórmula era fixa nos n cálculos, tinha de usar dessa maneira... Mas claro que é muito mais vantajoso ter um array dinâmico, só a memória que se poupa..... (já nem me lembrava do mallcoc :S).

Um aparte, podes colocar aí um exemplo do malloc? :D





Título: Re: AVR - UART Receive
Enviado por: senso em 15 de Setembro de 2011, 19:28
Malloc em micro-controladores é perigoso, porque qualquer falha nos free e rebenta a stack bem depressa.

É claro que o micro não crasha se ficar num ciclo infinito, porque todos os micros têm de ficar em ciclo infinito, se não dão a volta ao program counter e recomeçam o programa do endereço 0, o que para o utilizador iria parecer um reset.

Isso de ele parecer que crasha é porque a tua função de recepção é bloqueante e se não tiver nada para ler fica ali á espera até receber alguma coisa.
Título: Re: AVR - UART Receive
Enviado por: Tyran em 15 de Setembro de 2011, 20:56
Depende do microcontrolador e da memória ram e do espaço para a heap.

Mas nestes não costuma ser boa prática, já para não falar de bugs que possam existir nas libs...

Tenta saber sempre qual o tamanho máximo que podes vir a precisar e trabalhas com base nisso. Não quer dizer que não possas fazer da outra maneira, mas tens de ter cuidado extra.
Título: Re: AVR - UART Receive
Enviado por: zordlyon em 15 de Setembro de 2011, 21:19
Malloc em micro-controladores é perigoso, porque qualquer falha nos free e rebenta a stack bem depressa.

É claro que o micro não crasha se ficar num ciclo infinito, porque todos os micros têm de ficar em ciclo infinito, se não dão a volta ao program counter e recomeçam o programa do endereço 0, o que para o utilizador iria parecer um reset.

Isso de ele parecer que crasha é porque a tua função de recepção é bloqueante e se não tiver nada para ler fica ali á espera até receber alguma coisa.

Hum disso desconhecia...é a desvantagem de andar a estudar informática e não electrotecnica, tudo o que passe da electronica basica uma pessoa fica a nora...  :-\

Pensei que so tinhamos que ter cuidado com a memória gasta, do resto era codigo para cima..

Cumprimentos,
André Carvalho.
Título: Re: AVR - UART Receive
Enviado por: senso em 15 de Setembro de 2011, 21:21
Mas tambem, ele bem que até pode usar um array com 1K para receber dados, tem 4K de ram para usar, chega e sobra bem.
O melhor nesse caso é usar uart com interrupções a ler para um buffer circular.
Título: Re: AVR - UART Receive
Enviado por: SJD22 em 21 de Setembro de 2011, 00:33
Feito! Uf...!  8)

Obrigado pelas dicas pessoal.