RS485 — BLOGS-IT.RU http://www.blogs-it.ru Компьютеры и электроника: о разработке программного обеспечения Mon, 06 May 2013 06:15:20 +0000 ru-RU hourly 1 https://wordpress.org/?v=4.7.3 AVR UART/USART на WinAVR C RS232/RS485 http://www.blogs-it.ru/mikrokontrollery-avr/avr-uart-usart-na-winavr-c/ http://www.blogs-it.ru/mikrokontrollery-avr/avr-uart-usart-na-winavr-c/#respond Thu, 30 Aug 2012 10:38:06 +0000 http://www.blogs-it.ru.mastertest.ru/?p=227 Данный пример основан на статье компании Atmel AVR306: Using the AVR® UART in C и описывает как настроить и задействовать UART на большинстве устройств ARV.
Примеры на языке C предоставляют примеры использования UART в следующий режимах:
  • Режим опроса (меньше кода);
  • Режим прерываний (программа свободна во время обмена данными).
Использование UART в режиме опроса позволяет создавать более простой и компактный код. Такой способ предпочтителен в таких случаях, когда использование прерываний не рекомендуется, а компактность кода является одним из наиважнейших требований к программе, например, при реализации собственного AVR-загрузчика (bootloader), применяющего для коммуникаций интерфейс RS232 или RS485 (для RS485 имеются определенные ограничения. Как учесть их описано ниже).
Режим прерываний же позволяет добиться наивысшей производительности, но требует больше усилий.
Скачать примеры можно по ссылкам указанным внизу документа (UART1.c, UART2.c, USART1.c, USART2.c). Примеры даны для микроконтроллеров ATmega128 и

Использование примера

Для этого понадобится:
  • Создать тестовый проект в AVR Studio;
  • Вставить в проект код из примера и адаптировать его под свой тип микроконтроллера и отладочной платы;
  • Запустить тестовую программу и произвести обмен данными.
Создайте проект WinAVR C в AVR Studio и выберите свой тип микроконтроллера (микроконтроллеры AVR8 с поддержкой USART). Выберите нужный вам режим задействования UART и вставьте соответствующий код из указанного в списке.
Адаптируйте вставленный код под ваш тип микроконтроллера. Это касается названий таких регистров как UBRR, UCR или UDR. Правильные названия необходимо брать из даташита на ваш микроконтроллер, т.к. названия регистров для вашего типа микроконтроллеров могут отличаться. К примеру, если в микроконтроллере имеется несколько UART эти переменные будут иметь в своем имени цифровые индексы.
К адаптации также относится процедура инициализации USART. Используя даташит на микроконтроллер необходимо вычислить правильные значения регистров UART на основе требуемых параметров скорости передачи данных и формата кадров.
К примеру, для Atmega32 необходимо присвоить UBRRL = 47, UCSRA |= _BV( U2X ) в случае с частотой 7372800Гц BAUDRATE = 19200 бод, а также присвоить UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1) для установки формата символа 8-N-1 (битов данных-четность-стоповых битов).
Далее потребуется программа для тестирования соединения с микроконтроллером. Если ваше отладочное устройство подключено к компьютеру через RS232, то можно для этого использовать стандартную программу HyperTerminal, входящую в состав операционной системы (Пуск->Все программы->Стандартные->Связь->HyperTerminal). Запустите программу и создайте подключение с теми же параметрами, что были выставлены для микроконтроллера. Подключите отлаживаемое устройство к компьютеру и запустите на нем программу.

Особенности применения UART на RS485

Как известно, главное отличие RS232 или RS485 заключается в том что RS232 предназначен для подключения двух устройств, а RS485 для подключения нескольких, в связи с чем применение RS485 немного сложнее применения RS232. Сложность возникает за счет того, что при использовании RS485 необходимо применять управляющий сигнал состояния канала, от которого зависит в что сейчас готово делать устройство — читать или записывать данные в линию.
Добавим в программу следующий макрос:
#ifdef  RTS_ENABLE

#define RTS_PIN         PA6
#define RTS_DDR         DDRA
#define RTS_PORT        PORTA

#define RTS_INIT        \
    do { \
        RTS_DDR |= _BV( RTS_PIN ); \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#define RTS_HIGH        \
    do { \
RTS_PORT |= _BV( RTS_PIN ); \
    } while( 0 );

#define RTS_LOW         \
    do { \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#endif

Макрос содержит три определения и три инструкции, необходимые для управления режимом передачи/чтения. Определения указывают к какой ноге микроконтроллера подключен управляющий сигнал RS485, а инструкции определяют процедуру инициализации порта две инструкции включения и выключения режима передачи.

Изменим исходный код UART1.c от Atmel, следующим образом:
Пример использования UART на RS485.
// AVR306: Using the AVR UART in C
// Routines for polled UART
// Last modified: 02-06-21
// Modified by: AR

/* Includes */
#include <io8515.h>

#ifdef  RTS_ENABLE

#define RTS_PIN         PA6
#define RTS_DDR         DDRA
#define RTS_PORT        PORTA

#define RTS_INIT        \
    do { \
        RTS_DDR |= _BV( RTS_PIN ); \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#define RTS_HIGH        \
    do { \
RTS_PORT |= _BV( RTS_PIN ); \
    } while( 0 );

#define RTS_LOW         \
    do { \
        RTS_PORT &= ~( _BV( RTS_PIN ) ); \
    } while( 0 );

#endif

/* Prototypes */
void InitUART( unsigned char baudrate );
unsigned char ReceiveByte( void );
void TransmitByte( unsigned char data );
uint8_t receiveMode = 1;

/* Main - a simple test program*/
void main( void )
{
InitUART( 11 ); /* Set the baudrate to 19,200 bps using a 3.6864MHz crystal */

for(;;)      /* Forever */
{
TransmitByte( ReceiveByte() ); /* Echo the received character */
}
}

/* Initialize UART */
void InitUART( unsigned char baudrate )
{
UBRR = baudrate;                  /* Set the baud rate */
UCR = ( (1<<RXEN) | (1<<TXEN) );  /* Enable UART receiver and transmitter */
}

uint8_t isReceivedByte( void ) 
{
if (!receiveMode)
{
RTS_LOW;
cbi(UCSRB, TXEN); 
sbi(UCSRB, RXEN); 
receiveMode = 1;
}
return UCSRA & (1<<RXC);
}

/* Read and write functions */
unsigned char ReceiveByte( void )
{
while ( !isReceivedByte() ) /* Wait for incomming data */
;                 /* Return the data */
return UDR;
}

void TransmitByte( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) )
;
if (receiveMode)
{
cbi(UCSRB, RXEN); 
sbi(UCSRB, TXEN); 
RTS_HIGH;
receiveMode = 0;
}

/* Put data into buffer, sends the data */ 
UDR = data; 
while ( !( UCSRA & (1<<TXC)) )
; 
_delay_ms(0.5);

    return;
}

 

]]>
http://www.blogs-it.ru/mikrokontrollery-avr/avr-uart-usart-na-winavr-c/feed/ 0