Alla_student 0 13 августа, 2016 Опубликовано 13 августа, 2016 (изменено) · Жалоба Здравствуй All! Необходимо написать программную поддержку передачи данных между встроенными портами UART1 и UART2 STM32F051. Алгоритм такой: 1. Прием данных с порта UART1 микроконтроллера, он подключен к PC, который всегда является мастером и запрашивает данные с устройства, которое подключено к порту UART2 микроконтроллера. 2. Загрузка принятых данных с UART1 в буфер1 256 байт, принятый пакет всегда меньше. 3. Передача данных из буфера1 в UART2. 4. Ожидание ответа внешнего устройства подключенного к UART2, и после получение данных в другой буфер2, то же 256 байт, иначе выход по таймауту 10 сек. 5. Передача данных из буфера2 в UART1 в сторону PC. PS: Скорость передачи на портах UART1 и UART2 разная! Я понимаю, что надо использовать прерывания, но запуталась с флагами, и пока ничего рабочего не получается. С DMA просто боюсь связываться. В конференциях аналогичного ничего рабочего не нашла. Буду признательна, если кто нибудь объяснит и даст пример рабочего кода для этой задачи. С уважением. Вечный студент Алла. Изменено 14 августа, 2016 пользователем Alla_student Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 13 августа, 2016 Опубликовано 13 августа, 2016 · Жалоба По-моему, с таким алгоритмом и прерываний не требуется, достаточно опроса флагов состояния UART :) В документе RM0091 содержаться даже примеры по работе с UART, как настройка, так и передача/приём. www.st.com/resource/en/reference_manual/dm00031936.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 13 августа, 2016 Опубликовано 13 августа, 2016 · Жалоба В документе RM0091 содержаться даже примеры :bb-offtopic: ну едрён батон, сколько ж можно :( что делают? - содЕржатся что БУДУТ делать - будут содержАться А по теме - да, ничего и не нужно Ждем байт из одного UART, если нет ничего - смотрим приемный UART и тупо перекидываем принятое туда-сюда. В тупом цикле while(1) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость TSerg 13 августа, 2016 Опубликовано 13 августа, 2016 · Жалоба ну едрён батон, сколько ж можно :( :bb-offtopic: Инвалиды ЕГЭ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alla_student 0 14 августа, 2016 Опубликовано 14 августа, 2016 (изменено) · Жалоба По-моему, с таким алгоритмом и прерываний не требуется, достаточно опроса флагов состояния UART :) В документе RM0091 содержаться даже примеры по работе с UART, как настройка, так и передача/приём. www.st.com/resource/en/reference_manual/dm00031936.pdf Спасибо, читала этот документ, но мне сложно завести именно два UART-а, а в документе этого нет, надо расставить приоритеты - работа с флагами и буферами данных, здесь видимо для меня засада. Да, и я спрашивала про реализацию алгоритма именно с двумя буферами выделенными в ОЗУ, или возможно реализацию FIFO с DMA или без. Это уже для меня "темный лес". Для чего это надо - я не указала, что скорость передачи данных на UART-ах разная. Поэтому уважаемый ALL! - Прошу привести примеры реализации этого алгоритма, если конечно не сложно, без примера я не разберусь, уже вторую неделю пытаюсь. Думаю и другим новичкам будет интересно. PS: В интернете не одного рабочего примера моста между внутренними UART-ами с буферизацией не нашла, только тупо перекладыванием байта, что при кратковременной паузе в данных или при разных скоростях на портах, не будет работать. Заранее спасибо за помощь! Изменено 14 августа, 2016 пользователем Alla_student Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Я бы сделал реализацию кольцевого FIFO-буфера. Создал бы два экземпляра - на прием и на передачу. Далее все просто: 1. При приеме символов из UART1 помещал бы их в первый буфер. 2. При приеме символов из UART2 помещал бы их во второй буфер. 3. При наличии символов в первом буфере и готовности передатчика UART2 выбирал бы их оттуда и записывал в UART2. 4. При наличии символов во втором буфере и готовности передатчика UART1 выбирал бы их оттуда и записывал в UART1. Пример реализации кольцевого FIFO-буфера: //----------------------------------------------------------------------------- // void sp_tx_push(sSERIAL_PORT *port, const BYTE x) //----------------------------------------------------------------------------- void sp_tx_push(sSERIAL_PORT *port, const BYTE x) { int tmp_t; port->tx_buf[port->tx_t] = x; tmp_t = port->tx_t + 1; if(tmp_t >= port->tx_size) tmp_t -= port->tx_size; if(tmp_t != port->tx_b) port->tx_t = tmp_t; } //----------------------------------------------------------------------------- // BYTE sp_tx_pop(sSERIAL_PORT *port) //----------------------------------------------------------------------------- BYTE sp_tx_pop(sSERIAL_PORT *port) { BYTE x; if(port->tx_b == port->tx_t) return 0; x = port->tx_buf[port->tx_b]; port->tx_buf[port->tx_b++] = 0; if(port->tx_b >= port->tx_size) port->tx_b -= port->tx_size; return x; } Опрос флагов UART, запись и чтение регистра данных UART, инициализация UART - тривиально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 40 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Алгоритм работы раскрыт не полностью. 1. Что происходит если приходит байт из устройства, а а. буфер от PC не заполнен б. буфер от PC передан на устройство не полностью 2. Что проиодит, если данные передаются в PC, а а. Приходят данные от устройства б. приходят данные от PC Нарисуйте на бумажке диаграмму работы (из стрелок и квадратиков). Начальных точек входа у Вас 4 1. Приняты данные от PC 2. Отправлены данные в PC 3. Приняты данные от устройства 4. Отправлены данные в устройство. Коды наколбасить для STM или любого другого - два часа максимум. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alla_student 0 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Алгоритм работы раскрыт не полностью. 1. Что происходит если приходит байт из устройства, а а. буфер от PC не заполнен Я выше писала, что работа PC в режиме мастера, уточняю - работа PC запрос устройства посылкой пакета данных со стороны PC и через промежуток времени в течении 10сек ответ устройства. Работа в режиме только запрос - ответ. б. буфер от PC передан на устройство не полностью - нет и ответа от устройства. Пакетный режим - известно начало и конец пакета, но пока я не хотела его определять, а тупо принимать - передавать. 2. Что проиодит, если данные передаются в PC, а а. Приходят данные от устройства Не придут без запроса - см. выше. б. приходят данные от PC Пока PC не получит ответ полностью от устройства, ничего передавать не будет. Нарисуйте на бумажке диаграмму работы (из стрелок и квадратиков). Начальных точек входа у Вас 4 1. Приняты данные от PC 2. Отправлены данные в PC 3. Приняты данные от устройства 4. Отправлены данные в устройство. Коды наколбасить для STM или любого другого - два часа максимум. Вроде бы без диаграммы я ясно написала, но если надо - то нарисую. С уважением, Вечный студент Алла. Я бы сделал реализацию кольцевого FIFO-буфера. Создал бы два экземпляра - на прием и на передачу. Далее все просто: 1. При приеме символов из UART1 помещал бы их в первый буфер. 2. При приеме символов из UART2 помещал бы их во второй буфер. 3. При наличии символов в первом буфере и готовности передатчика UART2 выбирал бы их оттуда и записывал в UART2. 4. При наличии символов во втором буфере и готовности передатчика UART1 выбирал бы их оттуда и записывал в UART1. Пример реализации кольцевого FIFO-буфера: //----------------------------------------------------------------------------- // void sp_tx_push(sSERIAL_PORT *port, const BYTE x) //----------------------------------------------------------------------------- void sp_tx_push(sSERIAL_PORT *port, const BYTE x) { int tmp_t; port->tx_buf[port->tx_t] = x; tmp_t = port->tx_t + 1; if(tmp_t >= port->tx_size) tmp_t -= port->tx_size; if(tmp_t != port->tx_b) port->tx_t = tmp_t; } //----------------------------------------------------------------------------- // BYTE sp_tx_pop(sSERIAL_PORT *port) //----------------------------------------------------------------------------- BYTE sp_tx_pop(sSERIAL_PORT *port) { BYTE x; if(port->tx_b == port->tx_t) return 0; x = port->tx_buf[port->tx_b]; port->tx_buf[port->tx_b++] = 0; if(port->tx_b >= port->tx_size) port->tx_b -= port->tx_size; return x; } Опрос флагов UART, запись и чтение регистра данных UART, инициализация UART - тривиально. Спасибо за код кольцевого буфера FIFO, но как я выше писала, не могу с флагами и приоритетами разобраться, чтобы алгоритм приема передачи между портами работал. Вот полный код с инициализацией мне бы помог. Заранее спасибо! Вечный студент Алла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Вот полный код с инициализацией мне бы помог. Заранее спасибо! Вечный студент Алла. В упомянутом мной документе имеются также примеры инициализации. А с разной скоростью проблем нет - по Вашему алгоритму приём/передача по UART1 не пересекаются во времени с приёмом/передачей по UART2. 1. Принял по UART1 - выплюнул в UART2. 2. Принял по UART2 - выплюнул в UART1. 3. goto 1. :bb-offtopic: смотрим приемный UART Наверно, Вы хотели сказать "приемлимый"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба 1. Принял по UART1 - выплюнул в UART2. Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600. Что будет, если в UART1 придет 2 символа? Первый запишется в UART2 и начнется передача по UART2. А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать. Спасибо за код кольцевого буфера FIFO, но как я выше писала, не могу с флагами и приоритетами разобраться, чтобы алгоритм приема передачи между портами работал. Вот полный код с инициализацией мне бы помог. Заранее спасибо! Вечный студент Алла. С такими запросами в раздел "предлагаю работу". Что именно не понятно с флагами и приоритетами? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600. Что будет, если в UART1 придет 2 символа? Первый запишется в UART2 и начнется передача по UART2. А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать. Ну если прочитать первое сообщение топика, то всё должно быть понятно :) Немного подправлю: 1. Принял пакет по UART1 - выплюнул пакет в UART2. 2. Принял пакет по UART2 - выплюнул пакет в UART1. 3. goto 1. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Ну если прочитать первое сообщение топика, то всё должно быть понятно :) И что же такое "пакет"? Как узнать конец пакета? По таймуату или разбирать протокол? Можно просто сделать два FIFO-потока, чтоб не привязываться к таймаутам и протоколам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alla_student 0 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600. Что будет, если в UART1 придет 2 символа? Первый запишется в UART2 и начнется передача по UART2. А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать. Не внимательно читали выше мою писанину. - Не будет такой ситуации. С такими запросами в раздел "предлагаю работу". Что именно не понятно с флагами и приоритетами? Спасибо за совет о разделе "предлагаю работу", а мне только остается подавать объявление "ищу работу" :( C флагами все понятно..., почти, но только мой код не работает, поэтому я пишу привести пример работы с двумя портами UART, которого я не нашла в интернете. Я не прошу привести весь код, а только части программы инициализации и работы с флагами приема, прерываний с двумя портами. С одним вроде ясно. И что же такое "пакет"? Как узнать конец пакета? По таймуату или разбирать протокол? Можно просто сделать два FIFO-потока, чтоб не привязываться к таймаутам и протоколам. Принятый пакет пока не собиралась разбирать, возможно позже понадобится. Про таймауты выше писала. Без них нельзя. Ну если прочитать первое сообщение топика, то всё должно быть понятно :) Немного подправлю: 1. Принял пакет по UART1 - выплюнул пакет в UART2. 2. Принял пакет по UART2 - выплюнул пакет в UART1. 3. goto 1. Вам понятно, а у меня код не работает. Но уже это смахивает на "У попа была собака...". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 14 августа, 2016 Опубликовано 14 августа, 2016 · Жалоба но только мой код не работает Обычно в таких ситуациях говорят: "код в студию". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alla_student 0 16 августа, 2016 Опубликовано 16 августа, 2016 · Жалоба Обычно в таких ситуациях говорят: "код в студию". "код в студию" :( ... Всем спасибо. Прочитала еще раз название раздела конференции: "В помощь начинающему > ARM, 32bit" - вроде по адресу вопрос задала, но так реальной помощи не получила. Буду дальше искать проблему и возможно в других конференциях найду все таки ответ или кто нибудь приведет пример рабочего кода. С уважением. Вечный студент Алла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться