• Welcome to LusoRobótica - Robótica em Português.
 

Introdução ao avr-gcc usando o AvrStudio [Mais timers/mood light]

Started by senso, 28 de September de 2010, 01:07

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

senso

E claro, se alguem reparar em algum erro digam para corrigir ;)
Obrigado.
Avr fanboy

Cynary

Excelente tutorial :)
A única coisa que penso que poderia completá-lo seria uma pequena explicação de como comunicação serial funciona.
Duas pequenas observações: a maior parte dos registers 16 bits do AVR (até agora todos têm funcionado, não sei se há algum que não esteja configurado :P), apesar de serem divididos em dois, um H e um L, podem ser acedidos directamente como um único register em C (muitas vezes é melhor isso do que separadamente, visto que por vezes existem regras sobre qual o register que se tem de aceder primeiro). Neste caso, acedes separadamente o UBRR0L e o UBRR0H, quando podias aceder unicamente ao UBRR0.
Outro pormenor, de formatação: Fechaste mal a code tag quando estavas a explicar a função USART_Init ...
Se não te importas, vou plagiar os teus tutoriais, e começar a usar funções nos meus xD, infelizmente nunca me lembrei disso :/.

senso

Obrigado pela chamada de atenção quanto ao erro.
Em alguns registos conheço isso, como é caso de ler a ADC usando só ADCW, mas para o caso deste não conhecia esse atalho por assim dizer.
Vai dar no mesmo e como é para iniciantes assim os registos que são usados no programa existem no datasheet.
Pois, eu estava para escrever uma pequena introdução sobre o que é em concreto a comunicação serial, mas primeiramente muita gente não iria entender grande coisa, e como só usamos serial até ao ftdi passa a usb e cada vez mais é assim, não vejo grandes vantagens em dizer como funciona, e no teu tutorial tu já escreves-te sobre isso.
Avr fanboy

Cynary

Quote from: senso on 01 de October de 2010, 01:10
Obrigado pela chamada de atenção quanto ao erro.
Em alguns registos conheço isso, como é caso de ler a ADC usando só ADCW, mas para o caso deste não conhecia esse atalho por assim dizer.
Vai dar no mesmo e como é para iniciantes assim os registos que são usados no programa existem no datasheet.
Pois, eu estava para escrever uma pequena introdução sobre o que é em concreto a comunicação serial, mas primeiramente muita gente não iria entender grande coisa, e como só usamos serial até ao ftdi passa a usb e cada vez mais é assim, não vejo grandes vantagens em dizer como funciona, e no teu tutorial tu já escreves-te sobre isso.

O que eu tenho no meu tutorial é mais a explicar o que cada register/bit faz.
Por curta descrição, estava a falar mais das especificações do standard.
Por exemplo, explicar como a paridade em serial funciona, a diferença entre modo síncrono e assíncrono, e qual a diferença entre 1 ou 2 stop bits (infelizmente ainda não percebi isto tudo bem xD era para ver este fim-de-semana :P).
Além disso, o USART tem outras funcionalidades que podem ser descritas, como os modos multi-processador/SPI (no entanto, sou da opinião que o SPI é suficiente para outra parte do tutorial, e o multi-processador é suficientemente semelhante ao I2C para ser descrito aí :P).
No entanto, também tens razão quando dizes que o que descreveste é suficiente para quase todas as aplicações, mas penso que uma curta descrição do serial seria positiva, mesmo que seja só para compreender mais facilmente como funcionam outras comunicações serial usadas como SPI/I2C.
Visto que já fizeste o tutorial de serial, em princípio irei trabalhar num de I2C para este fim-de-semana, e posso explicar isso aí ;)

senso

Quando vires o trabalho que dá meter o i2c a trabalhar certinho e direitinho, penso que no site do Fleury tem lá uma biblioteca de i2c e aquilo é massivo mesmo, tens montes de casos excepcionais, fazer o Start e o Stop.
Eu nunca usei a usart em modo spi nem nunca li a parte do multi processador, o modo síncrono segundo me parece é funcionar como uma porta spi, mas não tenho a certeza se é mesmo ou não.
1 stop bits ou dois é só mais um bit a comer tempo que em alta velocidade dá jeito, e mesmo em baixa, é menos um bit que a usart tem de gerar, eu dei comunicação serial em cadeiras e nunca ninguém disse o uso de 1 ou 2 stop bits, provavelmente teria uso nos antigos terminais mecânicos e os primeiros electrónicos, mas isto é especulação.
O bit de paridade é um mecanismo muito rudimentar de detecção de erros, mas só é capaz de os detectar, e não sei como é que o ftdi trata de uma falha de paridade, numa usart um erro de paridade das duas uma, ou mandava os dados do byte em questão fora ou ligava uma flag/excepção/interrupção consoante a importância dos dados.
Avr fanboy

Cynary

O modo síncrono necessita do uso de um clock, e por isso a baud rate não interessa muito, a não ser que sejamos master. Basicamente funciona como nos modos SPI e I2C.
Como disse antes, esses pormenores são mais interessantes para perceber todo o potencial que o AVR nos dá do que propriamente para usá-los mesmo xD
Estive já a ver a biblioteca de I2C do fleury, e até não me pareceu muito complicado, apenas exige um bom conhecimento do protocolo.

senso

Pois, e tendo em conta que está implementada em assembly melhor que aquilo eu sei que não faço, portanto se quero i2c pego nela e uso-a.
O modo sincrono é mesmo um segundo SPI.
Avr fanboy

GnGz

Este foi o codigo que fiz para o desafio do senso .. com uma pequena ajudazita do senso:

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

//declaração das nossas funções
void USART_init(void);
unsigned char USART_receive(void);
void USART_send( unsigned char data);
void USART_putstring(char* StringPtr);



int main(void){

USART_init();      //Inicializar a usart
DDRB |= (1<<PB5);

while(1){      //Loop infinito

if ( USART_receive() == "a" ) {   //faltava-te o () depois de USART_receive para o compilador saber que é um função, e o receive estava mal escrito
PORTB |= (1<<PB5);
}
else {
  PORTB &= ~(1<<PB5);   //falta-te um ponto e virgula aqui para indicar fim de linha
}
}

return 0;
}

void USART_init(void){

   UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
   UBRR0L = (uint8_t)(BAUD_PRESCALLER);
   UCSR0B = (1<<RXEN0)|(1<<TXEN0);
   UCSR0C = (3<<UCSZ00);
}

unsigned char USART_receive(void){

   while(!(UCSR0A & (1<<RXC0)));
   return UDR0;

}

void USART_send( unsigned char data){

   while(!(UCSR0A & (1<<UDRE0)));
   UDR0 = data;

}

void USART_putstring(char* StringPtr){

while(*StringPtr != 0x00){
   USART_send(*StringPtr);
   StringPtr++;}

}


Tou e com dificuldades e para fazer upload no meu arduino... :\

senso

Le a pm, deves estar a esquecer-te de fazer reset no botao do arduino, que o avrdude nao faz reset automatico.
Avr fanboy

GnGz

Ja consegui mas parece que o codigo ai em cima faz o que deve fazer :S  :-[

Cynary

Quote from: GnGz on 02 de October de 2010, 18:16
Ja consegui mas parece que o codigo ai em cima faz o que deve fazer :S  :-[

Tentei usar o teu código ...
Deu-me um erro, nem chegou a compilar :P (tinha o compilador configurado para mostrar todos os erros/avisos -- opção -Wall).
Deu erro na linha 24:

Code (c) Select
USART_receive() == "a"

Em C, "a" não é um carácter, logo não podes comparar com um carácter. Ao usares o símbolo ", estás a declarar uma string, que acabam em 0 (logo tens dois caracteres aí) -- apenas se usa esta declaração em C quando estás a atribuir o valor de uma string na sua declaração (fora da declaração, usas a função strcpy) ou quando passas como parâmetro para uma função (em C++ tens mais opções :P).
Para declarares como carácter, tens de usar o símbolo ':

Code (c) Select
USART_receive() == 'a'

Não vi o resto do código, nem testei, por isso não sei se pode ter algum problema de lógica, mas tens esse problema de programação :P

GnGz

Sim ... o senso ja tinha dito isso mas muito obrigado... mas nao correu bem o soft..

Cynary

Quote from: GnGz on 02 de October de 2010, 19:30
Sim ... o senso ja tinha dito isso mas muito obrigado... mas nao correu bem o soft..

Estive a testar com maior pormenor, e o problema parece estar mesmo nas funções do USART :S
Agora não tenho tempo de testar ao pormenor, mas o código parece ficar bloqueado na função USART_init, e por alguma razão estranha, quando incluo o código para a função USART_putstring, o código aparenta dar problemas :S
Quando tiver mais tempo, vejo o que se passa com maior pormenor :P.

GnGz

Mas se o USART tivesse a funcionar direito .. o codigo corria certo ?

P.S : tou sem acentos...

Njay

O código parece-me bem. GnGz, o que é que vês e o que é que estavas à espera de ver no teste que fazes (e que teste é que fazes?)?