collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: atmega88 USART  (Lida 22694 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
atmega88 USART
« 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

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: atmega88 USART
« Responder #1 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.

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #2 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

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: atmega88 USART
« Responder #3 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.
« Última modificação: 26 de Maio de 2011, 14:08 por Njay »

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: atmega88 USART
« Responder #4 em: 26 de Maio de 2011, 14:59 »
Esse código é meu lol, de resto o Njay já respondeu.
Avr fanboy

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #5 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!?

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #6 em: 26 de Maio de 2011, 17:36 »
sim, é teu :) mas n o tou a conseguir por a funcionar =/

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: atmega88 USART
« Responder #7 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;
Avr fanboy

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #8 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

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #9 em: 29 de Maio de 2011, 12:15 »
ajudem la pf

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: atmega88 USART
« Responder #10 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.
Avr fanboy

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #11 em: 29 de Maio de 2011, 17:11 »
mas supostamente foi o que me disseram pra fazer =/

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: atmega88 USART
« Responder #12 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.

Offline tiagosilva510

  • Mini Robot
  • *
  • Mensagens: 100
Re: atmega88 USART
« Responder #13 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

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: atmega88 USART
« Responder #14 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.