serial.available() вор!!!

Тема в разделе "Arduino & Shields", создана пользователем lazerrain, 16 ноя 2016.

  1. ostrov

    ostrov Гуру

    Как это относится к среде IDE? Если я напишу это в AVRS то напишу и в AIDE, точнее скопирую.
     
  2. ostrov

    ostrov Гуру

    Кстати, попробую вечером поиграть с ISR(USART0_RX_vect). Как то так:
    Код (C++):
    ISR(USART0_RX_vect)
    {  
        *receivedDataPtr = UDR0;
        receivedDataPtr++;  
        numOfDataReceived++;
        if (numOfDataReceived == numOfDataToReceive)
        {
            UCSR0B &= ~((1 << RXCIE0) | (1 << RXEN0));
            readyToExchange = 1;
        }
    }
     
    ИгорьК нравится это.
  3. Onkel

    Onkel Гуру

    поиграть можно, только вам придется выковырять ардуиновскую функцию обработки прерывания по поступлению байта в буфер usart. Суп из топора получается - берем Ide Для домохозяек и потом влезаем в этот ide чтобы отключить костыли, как раз для домохозяек и сделанные. В studio или CV сразу не проще написать?
    Впрочем, очень интересен результат ваших экспериментов. Будем ждать.
     
    Последнее редактирование: 17 ноя 2016
  4. Onkel

    Onkel Гуру

    ну да, а зачем тогда писать в aide, если Вы можете написать в avrs? Aide как раз и сделана для людей, которые не собираются осваивать avrs и работе с регистрами (таймеры, spi etc) предпочитают готовые функции.
     
    Последнее редактирование: 17 ноя 2016
  5. ostrov

    ostrov Гуру

    Зачем костыли отключать? Достаточно их не использовать и в коде их не будет.
     
  6. Onkel

    Onkel Гуру

    ну так что, заработала ваша функция? Думаю, нет.
     
  7. ostrov

    ostrov Гуру

    Не пробовал я, пока занят другими делами. Отпишусь.
     
  8. Alex19

    Alex19 Гуру

    Вернемся к самой реализации Serial.

    Получение данных в библиотеке Serial, на примере Arduino Uno, происходит по прерывание по завершению приема UART ISR(USART_RX_vect), которое вызывает Serial._rx_complete_irq();, данный вызов Вы можете увидеть тут - https://github.com/arduino/Arduino/...arduino/avr/cores/arduino/HardwareSerial0.cpp. Поэтому не зависимо от того, какое время выполнения loop, все данные будут приняты. В функции _rx_complete_irq, эти данные помещаются в буфер, это можно увидеть тут - https://github.com/arduino/Arduino/...no/avr/cores/arduino/HardwareSerial_private.h.

    Если во время loop, мы получаем 10 байт, они сохранятся в буфер и на следующем loop мы читаем их из буфера, так как наш буфер имеет размер в 63 байта, мы имеем существенный запас. Но если во время loop приходит более 63 (между чтениями), то мы теряем данные. Тут просто не зачем прерывания, при всей моей любви к ним:).

    Как происходит передача, мы вызываем Serial.print, который вызывает write (HardwareSerial наследник класса Stream, а он в свою очередь класса Print именно в нем описаны все методы print и println), который мы переопределён тут - https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp. Тут мы записываем 1 байт из буфера отправки в буфер UART и включаем прерывание по опустошению буфера.

    Отправка происходит через прерывание по опустошению буфера UART ISR(UART0_UDRE_vect), которое вызывает Serial._tx_udr_empty_irq();, данный вызов Вы можете увидеть тут - https://github.com/arduino/Arduino/...arduino/avr/cores/arduino/HardwareSerial0.cpp.

    После того, как буфер очищен, мы отключаем прерывание.

    Не думаю, что у кого-то тут возникают проблемы, просто тут собрались перфекционисты (сам иногда болею:)). И в конце простая реализация UART, как пример для Ардуин на AVR, с аналогичными буферами. Там нужно определить контролер
    Код (C++):

    #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega2560__)

      // Частота процессора.
      #ifndef F_CPU
        #define F_CPU 16000000UL
      #endif                          

      #if defined(__AVR_ATmega2560__)
        // Если ArduinoMega.
        #define ARDUINO_MEGA_2560
      #endif
    #else
      #error This board not support!
    #endif
     
    И по мелочи.
    Код (C++):
    // Используем UART AVR.
    #define USE_AVR_UART
    Если кто-то захочет использовать и будут проблемы, пишите, вытянул из текущего проекта, может забыл о чем-то забыл. Для большинства прекрасно подойдет стандартный Serial, который сделан не плохо.
     

    Вложения:

    • UART.cpp
      Размер файла:
      14,5 КБ
      Просмотров:
      331
    • UART.h
      Размер файла:
      3,3 КБ
      Просмотров:
      280