USART to RS485 atmega328

Тема в разделе "Микроконтроллеры AVR", создана пользователем Yerabdi, 28 дек 2017.

  1. Yerabdi

    Yerabdi Гик

    Здравствуйте всем как можно отправлять и принимать данные через usart с выходом на max485
     
  2. DIYMan

    DIYMan Guest

    Обычным образом, управляя выходами DE и RE MAX485 - соответственно, переключаетесь между режимами приём/передача. Эти выходы запараллеливают и пускают на пин ардуины, когда нужно принимать с шины - выставляется низкий уровень на этом пине, когда передавать - высокий. Вот и всё, собственно.
     
    Igor68 и ostrov нравится это.
  3. Yerabdi

    Yerabdi Гик

    по схеме всю понятно а в програмном коде как реализовать?
     
  4. DIYMan

    DIYMan Guest

    У вас беда выставить с помощью digitalWrite на ОДНОМ пине или низкий, или высокий уровень? Не получается, да? Беда.

    Я же всё описал. Как писать в UART - знаете: Serial.write сотоварищи. Как читать оттуда - тоже известно: Serial.read. Проблема-то в чём, мсье? Кусок готового кода надо?
     
    Igor68 нравится это.
  5. parovoZZ

    parovoZZ Гуру

    Сперва надо с протоколом передачи определится. Либо свой придумать, либо стырить готовый у кого. Если устройства два, то достаточно проверки на четность. Если устройств несколько - то и адресацию придется вводить.
     
  6. ostrov

    ostrov Гуру

  7. Yerabdi

    Yerabdi Гик

    По usart уже пробовал отправит и принимать значение с терминала, не могу понять как отправить по rs485 буду принимать значение с лектуса
     
  8. Igor68

    Igor68 Гуру

    ...но DIYMan Вам уже сказал, что MAX485 надо переключать на приём/передачу - линия то симплексная! Ну или переходите на RS422 там дуплексная схема... вот только надо сначала найти такие устройства. Сам о них только слышал, но не встречал.
     
  9. Igor68

    Igor68 Гуру

    Каким-нибудь пином переключайте MAX485 на передачу... и после передачи переключайте на приём. Ну и так далее.
     
  10. parovoZZ

    parovoZZ Гуру

    Работал с 422. Ничего сложного. Реализуется на двухканальном операционнике: четыре провода - RX+, RX-, TX+, TX-. Для однонаправленной задачи избыточна, поэтому и не популярна.
     
  11. Igor68

    Igor68 Гуру

    Я не про сложность, а про количество распространённых промышленных устройств:D
     
  12. Yerabdi

    Yerabdi Гик

    У меня имеется MAX485
    Вот код который написал в атмел студио по прерыванию отправляет данные с интервалом 1 секунды по usart:
    Код (C++):
    #include <avr/io.h>
    #include <avr/interrupt.h>
    unsigned char ubrr=103;//usart частота микроконтроллера 16МГц

    volatile unsigned int zn_adc, zn_acp=5, zn_temp=2;
    volatile unsigned int usart_zn;
    ISR (TIMER0_COMPA_vect)
    {
        T++;//shet zadershki impulsa  
    }
    //***********************
    ISR (USART_UDRE_vect)
    {   UDR0 = zn_adc;
        UCSR0B &=~(1<<UDRIE0);
    }
    //**********************
    int main(void)
    {
    //********Timer0***********
       TCCR0A |= (1<<WGM01);  // Режим CTC (сброс по совпадению)
      TIMSK0 |=(1<<OCIE0A);  // Разрешить прерывание по совпадению
      OCR0A=63; //63 по достижении уходить в вектор прерывании, 63 равняется к 1 millisec  
        TCNT0=0;
      TCCR0B |=(1<<CS00)|(1<<CS01);
    //********usart*************
        UBRR0H = (unsigned char)(ubrr>>8);
        UBRR0L = (unsigned char)ubrr;
        UCSR0B =(1<< RXEN0) //разрешаем прием
        |(1<< TXEN0 );//разрешаем передачу
        UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);
        UCSR0B |=(1<<UDRIE0);
        //*********************
        asm("sei");
        while(1)
        {
       
           usart_zn = usart_1();
     
        }
    }

    //**************
    int usart_1 ()
    {
       
    static char danie1;    
        if ((T == 1000)&&(danie1 == 0))
        { zn_adc=zn_acp;
       UCSR0B |=(1<<UDRIE0);//регистр данных чист
        danie1=1;
        T=0;
        }
       if ((T == 1000)&&(danie1 == 1))
        { zn_adc=zn_temp;
       UCSR0B |=(1<<UDRIE0);//регистр данных чист
       danie1=0;
        T=0;
        }
       
    }
     
  13. Yerabdi

    Yerabdi Гик

    Протокол модбас рту изучил,как считать данные с ведущего понял но как отправить ответ с правильными значениями не понятно
     
  14. Igor68

    Igor68 Гуру

    Если в состоянии принять, проверить по контрольной сумме... то для посылки ответа надо сформировать ответ с контрольной суммой. Причём общего ответа на Ваш вопрос нет по причине того, что нет единого ответа для всех команд.
    например:
    команды(код операции): 3, 4 - чтение, при котором ведомый получает запрос и отсылает овет содержащий массив данных регистров.
    а команда 6 не требует указания количества регистров для записи... записывается только один регистр.
    Для каждой команды по разному. Из не много (стандартных команд).
     
  15. Yerabdi

    Yerabdi Гик

    В HEX виде: 3Ah 31h 32h 52h 53h 34h 38h 35h 0Dh
    В ASCII виде: ":" "1" "2" "R" "S" "4" "8" "5" /ПС/
    В начале управляющий символ начала посылки ":", следующие две цифры - адрес получателя (12), затем символы данных (RS485) и в конце - управляющий символ конца посылки 0Dh (перевод строки). Все устройства на линии, приняв символ ":", начинают записывать в память посылку до символа конца строки 0Dh. Затем сравнивают адрес из посылки со своим адресом. Устройство с совпавшим адресом обрабатывает данные посылки, остальные - игнорируют посылку. Данные могут содержать любые символы, кроме управляющих (":", 0Dh).
    Теперь после принятие такой команды, именно что нужно ответить ведущему устройству