quarta-feira, 4 de abril de 2012

Usando RS485 no AVR STUDIO - ATmega328:

 /*

 *                                                 usando a rs485
 *   Version    : 1.0
 *   microcontrolador : AVR ATMega328
 *   descrição  : exemplo usando a comunicação rs 485 em modo mestre-escravo
 *   criado: 3/4/2012 10:10:07
 *   autor: aguivone moretti fogia
 */


#define F_CPU 16000000  // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include <string.h>

  #define alterna_pino(x,y) x ^= _BV(y)   
  #define liga_pino(x,y) x |= _BV(y)
  #define desliga_pino(x,y) x &= ~(_BV(y))
  char caracter;

///////////////////////////////////////////////funçoes usadas pela usart////////////////////////////////////////////////

void RS485_inicializa(unsigned int BAUD)
{

   unsigned int velocidade = F_CPU/16/BAUD-1;
   //veja que na simulação do proteus dá erros nas velocidade diferentes de 9600 mas na pratica funciona.
   UCSR0A = 0X20;
/* habilita receiver and transmitter buffers */
  UBRR0H = (unsigned char)(velocidade>>8);
  UBRR0L = (unsigned char)velocidade;
  UCSR0B = 0X98;//deve se habilitar somente a interrupção de recepção para não travar o microcontrolador
  /* 8 bits , 1 stop bit, assincrono , sem paridade,modo nornal */
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
  desliga_pino(PORTD,PD2);
}

void escreve_caracter(unsigned char carac)
{  

            liga_pino(PORTD,PD2);//pino de controle da RS-485 
            _delay_loop_1(1);//tempo para estabilizar tensão            
            while ( !( UCSR0A & (1<<UDRE0)) ); //espera transmitir para enviar um novo
            UDR0 = carac;    
            while ( !( UCSR0A & (1<<UDRE0)) ); //espera transmitir desabilita a transmissão
            _delay_loop_1(1);//tempo para garantir o envio
            desliga_pino(PORTD,PD2);//pino de controle da RS-485   
}
void impri_serial(const char frase[80])
{
      unsigned int indice=0;
      unsigned int tamanho = strlen(frase);    
       while(indice<=tamanho)///veja que o programa pode travar se aqui não tiver as duas aspas
       {
            escreve_caracter(frase[indice]);
            indice++;
       }

}

//////////////////////////interrupções requerida para usar a recepção serial///////////////////////////////////
ISR(USART_RX_vect)
{
 caracter = (char)UDR0;
 escreve_caracter(caracter);
}
 

  
//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{
           DDRD = 0XFE;  //inicializa portD,4 a 7 entrada
           RS485_inicializa(9600);
           sei();
           impri_serial("Inicializado ... \n\r");
           impri_serial("pronto !\n\r");    

          //////////////////////////
          int long teste;
          for(;;)
            { 
                if(teste > 100000)
                {
                    alterna_pino(PORTB,PB1);
                    teste=0;                                        
                }                                    
              teste++;
            }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////

É preciso estar atento na hora de simular pois em testes feito no proteus gerou alguns erros :se colocar um baud rate diferente de 9600 ,os caracteres saem as vezes errados mas em teste práticos isso não acontece(vale lembrar que quando é usado só a serial 232 isso não acontece) acredito que seria uma limitação do software de simulação, veja abaixo imagem da simulação e o esquemático:



       veja que na simulação aparece alguns avisos.Neste exemplo tudo que você digitar no terminal rs485 é repetido no 232,pois no programa é solicitado que repita o que chegar no microcontrolador,assim termino aqui mais um exemplo de uso dos microcontroladores AVR.


configuração do proteus (o clock é de 16MHZ - se usar o cristal interno deve se reconfigurar todos os fuses do microcontrolador):

3 comentários :

  1. I need to work on RS485 modbus protocol pls help..

    i tried this program for me it didnt worked simulation ......

    I need it in English

    ResponderExcluir
  2. Boa noite.
    Acabei de fazer essa experiência no Proteus, porém não apareceu nenhum caractere no terninal RS232 quando eu digitei no terminal RS485. Conferi os baud-rates no codigo-fonte e no properties do MAX487 e estão como 9600 de baud rate. Poderia me ajudar e resolver o problema? Grato

    ResponderExcluir
    Respostas
    1. ok, postei a configuração do proteus que era onde ocorria o erro.

      Excluir

olá,digite aqui seu comentário!