LusoRobótica - Robótica em Português

Robótica => Iniciantes => Tópico iniciado por: tiagosilva510 em 26 de Maio de 2011, 11:32

Título: atmega88 USART
Enviado por: tiagosilva510 em 26 de Maio de 2011, 11:32
Bom dia , sou novo no forum, gostaria de colocar uma questao que nao estou a conseguir resolver...

Estou actualmente a fazer um projecto no qual irei usar a comunicação rs232 com atmega88, interegindo com um terminal.

para testar fiz um codigo que enviaria uma string, no entanto nao estou a conseguir obter essa string no terminal, ja verifiquei que existe comunicação entre o meu atmega e o computador, fazendo apenas variar o tempo posso ver a demora no terminal. mas a string nao aparece, aparecendo somente caracteres estranhos...

aqui vai o codigo...



#define F_CPU 1000000
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#define BAUDRATE 9600
#define BAUD_PRESCALLER F_CPU/16/BAUDRATE-1

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

char String[]="OLA"; /*String[] que dizer que é um
array, mas ao colocar-mos o texto entre "" indicamos ao
compilador que é uma string e ele coloca automáticamente o
terminador null e temos assim uma string de texto usavel*/
int main(void){
            USART_init(); //Inicializar a usart
            while(1){ //Loop infinito
                  USART_putstring(String); //Passamos a nossa string á função que a escreve via serial
                  _delay_ms(50); //E a cada 5s re-enviamos o texto
                  }
            return 0;
            }

void USART_init(void){
                  UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
                  UBRR0L = (uint8_t)(BAUD_PRESCALLER);
                  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
                  UCSR0C = ((1<<USBS0)|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++;
                                               }
                             }

Será que me podem ajudar?

Cumprimentos
Título: Re: atmega88 USART
Enviado por: Njay em 26 de Maio de 2011, 12:36
Deve ser um erro no baudrate. Se vires a datasheet do mega, vais ver que para 1MHz de clock, 9600bps com o bit U2xn = 0 tens um erro de baudrate de 7%, o que é muito para funcionar bem. Lê essa parte da datasheet para os detalhes.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 26 de Maio de 2011, 12:47
muito obrigado por teres respondido, realmente depois de ter aberto o topico li isso algures no google.

acho que vou tentar meter-lhe um cristal de 16 e ver se fica resolvido.. achas uma boa medida? ou aumento o baud?

Cumprimentos
Título: Re: atmega88 USART
Enviado por: Njay em 26 de Maio de 2011, 14:03
Não é preciso "tentar" nada, tudo isto é deterministico e calcula-se com contas simples, está tudo explicadinho na datasheet.

Vê a tabela 20-9 da datasheet. Por aí vês que, com um clock de 1MHz, só tens um erro abaixo de 1% para baudrates de 4800 ou 2400, com o bit U2Xn = 0 (este bit, quando está a 1, duplica a frequência de funcionamento da UART). Este "erro" é o erro na frequência gerada pelo mega face à frequência desejada. Devido à forma como o hardware funciona, não conseguimos obter exactamente o baudrate que queremos,  mas conseguimos na maior parte das vezes obter um baudrate "muito próximo"; como não é exactamente igual, diz-se que temos um "erro", que na datasheet aparece como uma percentagem. Este erro não faz mal desde que seja pequeno (menos de 1%).

Mas se colocares este bit U2Xn a 1 ("n" é o número da UART, no teu caso será U2X0 pois tás a usar a UART0) e recalculares o novo valor para o BAUD_PRESCALLER (agora a /8 em vez de /16) já consegues um erro suficientemente pequeno para que funcione. Tens que procurar nos registos da UART na datasheet qual é o registo onde está este bit.

Investe algum tempo a ler calmamente a secção de UART da datasheet que vale mesmo a pena; coloca aqui dúvidas sobre o que não entenderes.
Título: Re: atmega88 USART
Enviado por: senso em 26 de Maio de 2011, 14:59
Esse código é meu lol, de resto o Njay já respondeu.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 26 de Maio de 2011, 17:19

#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000
#define BAUDRATE 9600
#define BAUD_PRESCALLER F_CPU/8/BAUDRATE-1

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

char String[]="OLA"; /*String[] que dizer que é um
array, mas ao colocar-mos o texto entre "" indicamos ao
compilador que é uma string e ele coloca automáticamente o
terminador null e temos assim uma string de texto usavel*/
int main(void){
            USART_init(BAUD_PRESCALLER); //Inicializar a usart
            while(1){ //Loop infinito
                  USART_putstring(String); //Passamos a nossa string á função que a escreve via serial
                  _delay_ms(50); //E a cada 5s re-enviamos o texto
                  }
            return 0;
            }

void USART_init(unsigned int ubrr){
                  UBRR1H = (unsigned char)(BAUD_PRESCALLER>>8);
                  UBRR1L = (unsigned char)(BAUD_PRESCALLER);
                  UCSR1B = (1<<RXEN1)|(1<<TXEN1);
                  UCSR1C = (1<<USBS1)|(3<<UCSZ10);
                }

USART_receive(void){
                        while(!(UCSR1A & (1<<RXC1)));
                        return UDR1;
                         }

void USART_send( unsigned char data){
                           while(!(UCSR1A & (1<<UDRE1)));
                           UDR1 = data;
                           }

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


seria isto entao!?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 26 de Maio de 2011, 17:36
sim, é teu :) mas n o tou a conseguir por a funcionar =/
Título: Re: atmega88 USART
Enviado por: senso em 26 de Maio de 2011, 21:52
Esse código compila?

Na declaração das funções está:
Código: [Seleccione]
void USART_init(void);

e depois na função em si está:
Código: [Seleccione]
void USART_init(unsigned int ubrr){

E eu defino o UBRR com um define, e não como parametro da função, se queres mudar o baud é só mudar no #define BAUD.
Como o Njay disse é agarrar na datasheet e ligar o tal bit e meter isso dentro da função USART_init;
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 27 de Maio de 2011, 16:10
nao, nao esta a compilar, e alterando a usart 0 para a usart 1 ele da montes de erros...

#define F_CPU 1000000
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#define BAUDRATE 4800
#define BAUD_PRESCALLER F_CPU/8/BAUDRATE-1

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

char String[]="OLA"; /*String[] que dizer que é um
array, mas ao colocar-mos o texto entre "" indicamos ao
compilador que é uma string e ele coloca automáticamente o
terminador null e temos assim uma string de texto usavel*/
int main(void){
            USART_init(); //Inicializar a usart
            while(1){ //Loop infinito
                  USART_putstring(String); //Passamos a nossa string á função que a escreve via serial
                  _delay_ms(50); //E a cada 5s re-enviamos o texto
                  }
            return 0;
            }

void USART_init(void){
                  UBRR0H = (uint8_t)(BAUD_PRESCALLER>>;
                  UBRR0L = (uint8_t)(BAUD_PRESCALLER);
                  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
                  UCSR0C = ((1<<USBS0)|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++;
                                               }
                             }


daqui apenas tenho q acionar o Bit 1 – U2Xn: Double the USART Transmission Speed no registo UCSRnA é isso? tenho que meter dentro do void USART_init, UCSR1A=(1<<U2X1)

É isso?

Obrigado e desculpem n perceber muito disto,

Abraço
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 29 de Maio de 2011, 12:15
ajudem la pf
Título: Re: atmega88 USART
Enviado por: senso em 29 de Maio de 2011, 13:53
USART 1 ? Então mas o Atmega 88 não tem só uma usart?

Isso com meia duzia de pesquisas ja tinhas encontrado código.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 29 de Maio de 2011, 17:11
mas supostamente foi o que me disseram pra fazer =/
Título: Re: atmega88 USART
Enviado por: Njay em 29 de Maio de 2011, 17:28
Mudas sabe-se lá o quê no meio de uma página de código e nem dizes o que alteraste exactamente; estás à espera que a gente vá andar a comparar as 3 massas uniformes de código que aí deixaste para ver o que mudou? Se só mudaste um bocadinho do código, não voltes a colocar o código todo!!! Basta a função que sofreu alterações; melhor ainda, mostras o bocadinho original e o bocadinho alterado. E deves envolver o código com as tags "code" (selecciona o código e clica no botãozinho que tem o cardinal) para ficar com uma fonte monoespaçada e ser (muito) mais fácil de ler. Quem quer ser ajudado deve facilitar ao máximo a vida dos outros; aqui tudo funciona na base da boa vontade e portanto quanto mais fácil for ler a mensagem, mais probabilidade de respostas.

Não encontro onde viste que te foi sugerido que mudasses de UART... a única coisa que te sugeri foi que colocasses o bit U2X0 a 1. E que desses uma leitura na secção da datasheet relativa à UART e colocasses aqui as dúvidas sobre o que não entendesses.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 29 de Maio de 2011, 20:07
teria entao que alterar para isto(referencio-me ao primeiro codigo que mostrei):

Código: [Seleccione]
#define BAUDRATE 4800
#define BAUD_PRESCALLER F_CPU/8/BAUDRATE-1

e alem disso

Código: [Seleccione]
void USART_init(void){
                  UBRR0H = (uint8_t)(BAUD_PRESCALLER>>;
                  UBRR0L = (uint8_t)(BAUD_PRESCALLER);
                  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
                  UCSR0C = ((1<<USBS0)|3<<UCSZ00);
                  UCSR0A =(1<<U2X1)
                }

Cumprimentos
Título: Re: atmega88 USART
Enviado por: Njay em 29 de Maio de 2011, 20:37
Esse código compila?...

Baixaste o baudrate para 4800, logo não precisavas de fazer mais nada. As outras alterações eram apenas para poderes manter os 9600 bps.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 30 de Maio de 2011, 14:39
fiz tal como disseste, alterei o baud rate e no entanto continua sem dar.. o que me aparece no terminal é : þÿÿüÿÿÿÿüÿüÿÿÿÿðüÿþÿÿþÿüÿÿüÿüüüðÿÿÿÿüÿþÿÿÿÿÿÿÿþÿøÿÿðÿÿÿüÿÿðÿÿÿÿþÿÿÿüÿÿÿÿÿÿüÿÿþüÿÿþüÿÿÿÿÿüüðüÿÿÿüÿÿÿÿüüþÿÿÿþÿðÿÿÿüüÿÿÿÿÿÿÿÿÿþüþÿãÿÿÿðÿÿÿþÿÿüüÿÿðÿÿÿÿ

cumprimentos
Título: Re: atmega88 USART
Enviado por: CBX em 30 de Maio de 2011, 14:55
o baudrate tem de ser igual nos dois lados
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 30 de Maio de 2011, 14:56
e no terminal selecionei o mesmo
Título: Re: atmega88 USART
Enviado por: Njay em 30 de Maio de 2011, 20:26
Continuas com o baudrate mal. Neste último teste pegaste no código original e só alteraste o baudrate para 4800 (e no terminal), certo?
Para clock tens que usar um cristal, não sei se é o que tás a fazer (um ressonador nem sempre funciona).
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 30 de Maio de 2011, 21:29
boas...

"Esse código compila?...

Baixaste o baudrate para 4800, logo não precisavas de fazer mais nada. As outras alterações eram apenas para poderes manter os 9600 bps."

segundo o q tinhas dito apenas teria de baixar o baudrate, e sim foi o q fiz, meti o terminal e o baud a 4800, nao estou a usar cristar.. tou a usar 1000000Hz do atmega88
Código: [Seleccione]
#define F_CPU 1000000
Título: Re: atmega88 USART
Enviado por: Njay em 30 de Maio de 2011, 22:13
A UART só funciona bem com cristal, não podes usar o clock interno do mega.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 30 de Maio de 2011, 22:20
ah, não sabia disso.. vou por-lhe um cristal de 16 Mhz. e alem disso n tenho q fazer mais nd ao codigo? n tenho que alterar a formula
Código: [Seleccione]
#define BAUD_PRESCALLER F_CPU/16/BAUDRATE-1
Título: Re: atmega88 USART
Enviado por: Njay em 30 de Maio de 2011, 22:32
O clock interno do mega tem um erro muito grande e ainda varia muito com a temperatura, por isso não serve para usar com a UART.

(...) e alem disso n tenho q fazer mais nd ao codigo? n tenho que alterar a formula
Código: [Seleccione]
#define BAUD_PRESCALLER F_CPU/16/BAUDRATE-1

Só precisas de alterar o F_CPU. O BAUD_PRESCALER depende automaticamente do F_CPU.
A propósito, convém envolver o cálculo entre parentesis, assim:

#define BAUD_PRESCALLER  (F_CPU/16/BAUDRATE-1)

Habituem-se a fazer isto em todas as macros para evitar serem apanhados de surpresa por problemas "estranhos", como por exemplo nesta utilização:

a = BAUD_PRESCALLER * 2;

E os argumentos das macros também devem ser envolvidos em parentesis no corpo da macro.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 30 de Maio de 2011, 23:50
ja fiz isso, mudei a frequencia no programa, meti um cristal de 16 Mhz e desta vez no terminal deu:

<0><0><0><0><0><0><0><0><0><0><0><0><0><0>
Título: Re: atmega88 USART
Enviado por: xiserre em 31 de Maio de 2011, 00:03
tas a complicar muito.. se compilares o programa original o que faz? tens os fuses certos?
Título: Re: atmega88 USART
Enviado por: Njay em 31 de Maio de 2011, 01:19
Já agora, tás a usar um conversor RS232<->UART-TTL, certo?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 08:50
compila sem erros, fuses? como assim?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 08:51
sim, tou a usar um max 232
Título: Re: atmega88 USART
Enviado por: xiserre em 31 de Maio de 2011, 09:54
alem de configurares a velocidade do atmega no programa, precisas de por os fuses certos para usares o cristal de 16mhz
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 11:56
o que sao os fuses?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 20:03
...
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 20:07
O google ai não funciona?
Nem a datasheet?
Primeiro, estás a programar o teu atmega com que?
Uma das coisas que um programador isp faz é ler os fuses, vais á datasheet e ves o que são e quais valores deves meter para usar um cristal.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 21:10
eu disse que nao percebia muito disto ,

Estou a programar com o avrisp v2.0

o que tenho que acrescentar entao?
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 21:15
Mas se nunca pesquisares nada por ti nem abrires o manual do teu chip, queres que sejam as outras pessoas que o vão sacar, abrir, ler e dar-te a ler o que está lá e que podias ter lido?
É que assim estás sempre á espera dos outros.
Nunca usei esse chip, portanto não sei os valores que são precisos, mas até no Avr Studio tens uma janela para configurar os fuses antes de programares o chip.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 21:27
sim isso eu sei..  penso que seja isto :
Device : atmega88
Frequency : 16000000
Optimization: -O0

quanto ao manual o que vi foi a partir da pagina 285 (27.2 Fuse Bits) mas n percebi muito bem como se funciona com isso
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 21:34
ja vi que nao era isso.. tive a procurar e ja vi onde esta isso... e qndo vou enviar o programa pro micro
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 21:41
Mas não configures nada, porque podes desligar o ISP, mostra primeiro aqui.

Espero que não estejas a perceber o meu "tom" de escrita de um modo errado, não te estou a repreender nem a dizer que fazes mal em perguntar.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 21:47
na boa, e normal.. mas sabes que estamos a falar duma coisa que provavelmente percebes bem.. eu nem tanto :P vou-t mostrar o que tenho 
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimageshack.us%2Fphoto%2Fmy-images%2F51%2Fsemttuloemn.jpg%2F&hash=e674eaf302b56f2b2b3d2b397c7cfe08aad0ac73)
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 21:49
<script src='http://imageshack.us/shareable/?i=semttuloemn.jpg&s=51' (http://imageshack.us/shareable/?i=semttuloemn.jpg&s=51') type='text/javascript'></script><noscript>(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg51.imageshack.us%2Fimg51%2F3964%2Fsemttuloemn.jpg&hash=77dbf13af99628e58416c6997e4930ccc416c523) (http://imageshack.us/photo/my-images/51/semttuloemn.jpg/)</noscript>
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 21:58
Carrega no read e apenas no read e mostra o resultado sff.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 22:18
com o circuito ligado ao pc ou basta ler o q esta no micro?
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 22:36
Com o micro-controlador ligado ao programador.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 23:11
aqui esta o q apareceu :

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg17.imageshack.us%2Fimg17%2F8805%2Fsemttulowy.png&hash=f3562f5cb2bbe1b3696a8e3604b87b49edf77e1a) (http://imageshack.us/photo/my-images/17/semttulowy.png/)
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 23:44
No SUT_CKSEL, carrega na seta e escolhe a opção mais parecida com isto:
Full swing crystal, startup time 65ms ou qualquer coisa assim do género.

Outra coisa, um Atmega88 só corre a 8Mhz no maximo..
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 23:46
nao posso por cristal de 16 Mhz entao?
Título: Re: atmega88 USART
Enviado por: senso em 31 de Maio de 2011, 23:47
Penso que os A/PA já suportam 16Mhz, mas para isso só vendo na datasheet, mas se é um atmega88 sem mais nada no nome o máximo é 8Mhz.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 31 de Maio de 2011, 23:48
atmega88-20pu
Título: Re: atmega88 USART
Enviado por: Njay em 31 de Maio de 2011, 23:53
Esse mega88 corre até 20MHz, podes usar o cristal de 16MHz. Tá lá escarrapachado na 1ª página da datasheet :)
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 10:47
No SUT_CKSEL, carrega na seta e escolhe a opção mais parecida com isto:
Full swing crystal, startup time 65ms ou qualquer coisa assim do género.


Meto na mesma isto? com cristal de 16?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 12:30
ja testei mas n da.. o que aparece na consola agora é

<0>€€€<0>€<0><0>€<0><0><0><0>€€<0>€€€€À€€<0><0><0>€€<0>€€€€À€€€€€<0><0><0>€€€<0><0><0><0>€€<0><0><0>€€<0><0><0>€<0>€
Título: Re: atmega88 USART
Enviado por: xiserre em 01 de Junho de 2011, 13:12
o problema esta na divisao do clock. tira o visto do fuse ckdiv8..
O que acontece e que tens o cristal de 16mhz, mas a pll do micro divide o clock por 8, ficando a 2mhz.. retira esse fuse e tudo deve funcionar
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 13:50
ja fiz isso e testei, mas mais uma vez o que apareceu no terminal foi :

ÿüÿÿÿüÿüÿÿÿÿÿüüÿÿÿÿÿÿÿÿÿÿÿüÿÿþÿÿÿÿüüÿÿÿÿÿÿÿÿþüÿÿÿþÿÿÿþÿÿÿÿþÿÿÿÿüÿÿþÿÿÿûãÿÿÿÿüÿÿüüÿüÿüüÿüÿÿÿÿÿþüÿþüÿÿþÿüÿÿüÿÿÿÏðÿÿÿÿüÿÿÿÿþÿþüþÿþþüÿüÿüðÿÿÿÿÿÿÿÿüþÿþÿÿÿÿþüÿÿÿÿÿüüÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿüÿþÿÿÿþþüÿÿÿÿÿÿÿÿþðÿÿÿÿþÿÿþðÿÿÿÿüÿüÿÿÿÿÿüüÿÿÿÿÿÿðÿÿÿÿÿÿÿÿüþÿþÿ
Título: Re: atmega88 USART
Enviado por: xiserre em 01 de Junho de 2011, 14:59
tou sem ideias. se tas a compilar o codigo original, nao tenho mais ideias
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 16:01
sim. tou a compilar o 1º código, e fiz td direito como disseram
Título: Re: atmega88 USART
Enviado por: senso em 01 de Junho de 2011, 16:33
Mostra os fuses que tens agora, só para o caso de estar ainda algo errado.

E estás a meter o terminal com 8 bits de dados, sem paridade e 1 stop bit?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 17:15
fica aqui tudo direito o que estou a fazer, codigo, fuses e terminal:
Código: [Seleccione]
#define F_CPU 16000000
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#define BAUDRATE 4800
#define BAUD_PRESCALLER (F_CPU/16/BAUDRATE - 1)

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

char String[]="OLA"; /*String[] que dizer que é um
array, mas ao colocar-mos o texto entre "" indicamos ao
compilador que é uma string e ele coloca automáticamente o
terminador null e temos assim uma string de texto usavel*/
int main(void){
            USART_init(); //Inicializar a usart
            while(1){ //Loop infinito
                  USART_putstring(String); //Passamos a nossa string á função que a escreve via serial
                  _delay_ms(50); //E a cada 5s re-enviamos o texto
                  }
            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++;
                                               }
                             }


(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg709.imageshack.us%2Fimg709%2F8982%2Fsemttulo1ggu.png&hash=e627afbe0c5599610ef0be9094b1921e90a10be9) (http://imageshack.us/photo/my-images/709/semttulo1ggu.png/)



(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg809.imageshack.us%2Fimg809%2F2408%2Fsemttulodbm.png&hash=941057f41fbddc7deccefa471e5bb44b8d729b45) (http://imageshack.us/photo/my-images/809/semttulodbm.png/)
Título: Re: atmega88 USART
Enviado por: xiserre em 01 de Junho de 2011, 17:24
baudrate????
Título: Re: atmega88 USART
Enviado por: senso em 01 de Junho de 2011, 17:25
Isso parece ser baud-rate errada, porque estás a receber, não está é a chegar em condições.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 17:27
ha qqr coisa que nao me deixa receber a string, pois eu altero o delay e demoro a receber no terminal, n estou é mesmo a receber a string.

=/
Título: Re: atmega88 USART
Enviado por: xiserre em 01 de Junho de 2011, 17:52
a baudrate ta mal.. tens a 4800..
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 01 de Junho de 2011, 17:54
e nao é a 4800?
Título: Re: atmega88 USART
Enviado por: xiserre em 01 de Junho de 2011, 18:24
pelo codigo que tens no primeiro post e a 9600
Título: Re: atmega88 USART
Enviado por: senso em 01 de Junho de 2011, 18:30
Mas o que ele postou agora e 4800.

Mas experimenta mudar para 9600..
Título: Re: atmega88 USART
Enviado por: Njay em 02 de Junho de 2011, 04:15
Experimenta esta USART_init em vez da que tens agora:

Código: [Seleccione]
void USART_init(void)
{
    /* F_CPU is larger than a 16 bit int so be carefull here. */
    uint16_t  ubrr_value = (F_CPU/(16L*BAUDRATE)) - 1;

    UBRR0H = (uint8_t)(ubrr_value >> 8);
    UBRR0L = (uint8_t) ubrr_value;

    /* Set frame format: 8 data bits, no parity, 1 stop bit. */
    UCSR0C = (3 << UCSZ00);

    /* Enable receiver and transmitter */
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    /* Activate internal pull up on PD0, used for serial data input (active low signal). */
    PORTD |= _BV(PD0);
}

Também podes fazer um teste simples para ver se tá tudo a funcionar bem entre o PC e o mega.

  1) desligas do mega o fio que vai dar ao pino3 (é o TX do mega)
  2) verifica que não há eco do que teclas no terminal série no PC (carregas numa letra e ela não aparece no terminal)
  3) pega nesse fio que desligaste do pino 3 do mega e liga-o ao pino 2 (ficas com os 2 fios ligados ao pino 2)
  4) verifica que agora já há eco no terminal, aquilo que escreves aparece no terminal

Se o passo 2) falhar, deves ter o "auto echo" ligado no terminal - desliga-o e repete.
Se o passo 4) falhar então deves ter um problema algures entre o conversor USB-série e o MAX232 (inclusivé).
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 02 de Junho de 2011, 11:04
boas, n tive echo em nenhum dos casos
Título: Re: atmega88 USART
Enviado por: xiserre em 02 de Junho de 2011, 11:18
tens condensadores no cristal?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 02 de Junho de 2011, 11:19
sim tenho claro ambos ligados a massa
Título: Re: atmega88 USART
Enviado por: xiserre em 02 de Junho de 2011, 12:30
nao tens outro atmega para testar?
Título: Re: atmega88 USART
Enviado por: Njay em 02 de Junho de 2011, 14:44
Se não tens eco em nenhum dos casos então o teu problema não está no mega, está no conversor série e/ou MAX232.
Desliga do MAX a ficha do conversor, e une os pinos 2 e 3 da ficha (cuidado para não fazer curto circuito com outros pinos); isto liga o TX ao RX, e aqui tens que ter eco no terminal. Se não tiveres eco é o teu conversor USB-COM que não está bem. Se tiveres echo, é a parte do MAX que não está bem.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 02 de Junho de 2011, 15:50
n percebi muito bem o q tenho k fazer
Título: Re: atmega88 USART
Enviado por: senso em 02 de Junho de 2011, 16:46
Como é que estas a ligar o Atmega ao PC?
Porta serial nativa?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 02 de Junho de 2011, 19:32
nao, estou a usar um conversor usb-rs232

mas hoje de tarde emprestaram-m um, vou comparar os resultados com o meu.. :)
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 04 de Junho de 2011, 19:58
parece-m que era mesmo o conversor, mas ainda n consegui ver, pois ao testar o conversor, tive que instalar uns drivers, e depois disso, agora o terminal nao me deixa seleccionar as portas com desejada...

cumprimentos
Título: Re: atmega88 USART
Enviado por: senso em 04 de Junho de 2011, 22:50
Normalmente cada conversor vai aparecer numa porta COM com nome diferente.
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 06 de Junho de 2011, 14:49
com o novo conversor o que tive foi (em hex, uma vez q so consegui testar com o linux) ffff7fff7ffffefffefeff7ffffefeff, ou seja, ÿÿÿÿþÿþþÿÿþþÿ algo do genero do que me tinha dado anteriormente,

Cumprimentos Tiago Silva
Título: Re: atmega88 USART
Enviado por: Njay em 06 de Junho de 2011, 22:58
O teste de eco já funciona?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 16 de Junho de 2011, 11:08
dsclpem a demora, o problema estava mesmo no conversor :), era do ebay :P ja comprei um bom
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 16 de Julho de 2011, 21:13
boa noite, agora precisava de uma ajuda.. agora pra por o pc a enviar o bit 1 e o 0 para o atmega...

ja implementei um programa em C capaz de ler a porta serie.. no entanto agora usando o comando write nao tou a conseguir

Código: [Seleccione]
write(fd,1,1) em que o parametro do meio e o q será enviado. mas coloquei um led para ver se existia algum impulso no cabo rs232 mas n obtive nada.. alguem tem o codigo para receção de um bit no atmega?

Título: Re: atmega88 USART
Enviado por: xiserre em 17 de Julho de 2011, 02:14
boa noite, agora precisava de uma ajuda.. agora pra por o pc a enviar o bit 1 e o 0 para o atmega...

ja implementei um programa em C capaz de ler a porta serie.. no entanto agora usando o comando write nao tou a conseguir

Código: [Seleccione]
write(fd,1,1) em que o parametro do meio e o q será enviado. mas coloquei um led para ver se existia algum impulso no cabo rs232 mas n obtive nada.. alguem tem o codigo para receção de um bit no atmega?

tu nao podes enviar um bit.. tens de enviar 8.. e assim que tens configurada a USART.. Fazes uma mascara, e escreves no UDR.. Tao simples quanto isso..
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 17 de Julho de 2011, 11:36
sim eu sei.. mas tipo.. no programa em C?

eu qero enviar pelo programa em C e receber no atmega.. tens algum site que explique isso?
Título: Re: atmega88 USART
Enviado por: xiserre em 18 de Julho de 2011, 00:16
sim eu sei.. mas tipo.. no programa em C?

eu qero enviar pelo programa em C e receber no atmega.. tens algum site que explique isso?
queres enviar do pc para o atmega?
Tens experiencia de programaçao?
Título: Re: atmega88 USART
Enviado por: tiagosilva510 em 18 de Julho de 2011, 00:28
nao tenho muita.. eu tou a usar ,linux, como fiz no codigo para ler a porta serie do pc com um read, penso que enviar pela porta serie seja algo do genero dum write mas n estou a conseguir...

pretendo enviar do pc pro atmega
Título: Re: atmega88 USART
Enviado por: GnGz em 18 de Julho de 2011, 10:08
http://electrosofts.com/serial/ (http://electrosofts.com/serial/)
Título: Re: atmega88 USART
Enviado por: Njay em 18 de Julho de 2011, 14:13
Se tás a usar Linux é muito fácil fazer uma aplicação em TCL. Lanças a TCL shell (tclsh) e podes experimentar os comandos. Também podes enfiar tudo num ficheiro e executá-lo dado o nome do ficheiro como argumento à tclsh, tipo "tclsh script.tcl". Como o TCL é interpretado não é preciso compilar, e é uma linguagem de muito alto nível pelo que dá para fazer cenas bué complexas em meia dúzia de linhas. O man tem todo o help necessário sobre os comandos TCL.
Escrevi o código abaixo assim meio de cabeça por isso pode ter algum erro.

# Abrir porta série para leitura e escrita
set sd  [open "/dev/..." r+]  ;# (colocar o nome correcto da porta série)
# Configurar a porta série para (9600bps, sem paridade, 8 bits de dados, 1 stop bit)
fconfigure $sd -translation cr -buffering none -mode 9600,none,8,1
# Enviar uma string (terminada com \n) para o ATmega (o comando "puts" acrescenta sempre um \n no final)
puts $sd "oi!"
# Espera e recebe 1 string do ATmega (o ATmega tem que terminar os dados com um \n)
set str  [gets $sd]
# Imprimir no ecran a linha recebida
puts "Recebi do ATmega: $str"
# Fechar a porta série
close $sd