|
STM32F051K8 передача данных с UART1 на UART2 и обратно, мост между UART-ами |
|
|
|
Aug 13 2016, 07:18
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 5-04-11
Пользователь №: 64 146

|
Здравствуй 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 просто боюсь связываться. В конференциях аналогичного ничего рабочего не нашла. Буду признательна, если кто нибудь объяснит и даст пример рабочего кода для этой задачи.
С уважением. Вечный студент Алла.
Сообщение отредактировал Alla_student - Aug 14 2016, 05:34
|
|
|
|
|
Aug 13 2016, 20:26
|

Гуру
     
Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514

|
Цитата(RabidRabbit @ Aug 13 2016, 21:54)  В документе RM0091 содержаться даже примеры ну едрён батон, сколько ж можно  что делаю т? - содЕржа тся что БУДУТ дела ть - будут содержА ться А по теме - да, ничего и не нужно Ждем байт из одного UART, если нет ничего - смотрим приемный UART и тупо перекидываем принятое туда-сюда. В тупом цикле while(1)
|
|
|
|
Guest_TSerg_*
|
Aug 13 2016, 20:29
|
Guests

|
Цитата(toweroff @ Aug 13 2016, 23:26)  ну едрён батон, сколько ж можно  Инвалиды ЕГЭ.
|
|
|
|
|
Aug 14 2016, 05:32
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 5-04-11
Пользователь №: 64 146

|
Цитата(RabidRabbit @ Aug 13 2016, 22:54)  По-моему, с таким алгоритмом и прерываний не требуется, достаточно опроса флагов состояния UART  В документе RM0091 содержаться даже примеры по работе с UART, как настройка, так и передача/приём. www.st.com/resource/en/reference_manual/dm00031936.pdf Спасибо, читала этот документ, но мне сложно завести именно два UART-а, а в документе этого нет, надо расставить приоритеты - работа с флагами и буферами данных, здесь видимо для меня засада. Да, и я спрашивала про реализацию алгоритма именно с двумя буферами выделенными в ОЗУ, или возможно реализацию FIFO с DMA или без. Это уже для меня "темный лес". Для чего это надо - я не указала, что скорость передачи данных на UART-ах разная. Поэтому уважаемый ALL! - Прошу привести примеры реализации этого алгоритма, если конечно не сложно, без примера я не разберусь, уже вторую неделю пытаюсь. Думаю и другим новичкам будет интересно. PS: В интернете не одного рабочего примера моста между внутренними UART-ами с буферизацией не нашла, только тупо перекладыванием байта, что при кратковременной паузе в данных или при разных скоростях на портах, не будет работать. Заранее спасибо за помощь!
Сообщение отредактировал Alla_student - Aug 14 2016, 05:39
|
|
|
|
|
Aug 14 2016, 06:55
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Я бы сделал реализацию кольцевого FIFO-буфера. Создал бы два экземпляра - на прием и на передачу. Далее все просто: 1. При приеме символов из UART1 помещал бы их в первый буфер. 2. При приеме символов из UART2 помещал бы их во второй буфер. 3. При наличии символов в первом буфере и готовности передатчика UART2 выбирал бы их оттуда и записывал в UART2. 4. При наличии символов во втором буфере и готовности передатчика UART1 выбирал бы их оттуда и записывал в UART1. Пример реализации кольцевого FIFO-буфера: CODE //----------------------------------------------------------------------------- // 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 - тривиально.
|
|
|
|
|
Aug 14 2016, 15:30
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 5-04-11
Пользователь №: 64 146

|
Цитата(x893 @ Aug 14 2016, 12:35)  Алгоритм работы раскрыт не полностью. 1. Что происходит если приходит байт из устройства, а а. буфер от PC не заполнен Я выше писала, что работа PC в режиме мастера, уточняю - работа PC запрос устройства посылкой пакета данных со стороны PC и через промежуток времени в течении 10сек ответ устройства. Работа в режиме только запрос - ответ. Цитата б. буфер от PC передан на устройство не полностью - нет и ответа от устройства. Пакетный режим - известно начало и конец пакета, но пока я не хотела его определять, а тупо принимать - передавать. Цитата 2. Что проиодит, если данные передаются в PC, а а. Приходят данные от устройства Не придут без запроса - см. выше. Цитата б. приходят данные от PC Пока PC не получит ответ полностью от устройства, ничего передавать не будет. Цитата Нарисуйте на бумажке диаграмму работы (из стрелок и квадратиков). Начальных точек входа у Вас 4 1. Приняты данные от PC 2. Отправлены данные в PC 3. Приняты данные от устройства 4. Отправлены данные в устройство.
Коды наколбасить для STM или любого другого - два часа максимум. Вроде бы без диаграммы я ясно написала, но если надо - то нарисую. С уважением, Вечный студент Алла. Цитата(adnega @ Aug 14 2016, 10:55)  Я бы сделал реализацию кольцевого FIFO-буфера. Создал бы два экземпляра - на прием и на передачу. Далее все просто: 1. При приеме символов из UART1 помещал бы их в первый буфер. 2. При приеме символов из UART2 помещал бы их во второй буфер. 3. При наличии символов в первом буфере и готовности передатчика UART2 выбирал бы их оттуда и записывал в UART2. 4. При наличии символов во втором буфере и готовности передатчика UART1 выбирал бы их оттуда и записывал в UART1. Пример реализации кольцевого FIFO-буфера: CODE //----------------------------------------------------------------------------- // 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, но как я выше писала, не могу с флагами и приоритетами разобраться, чтобы алгоритм приема передачи между портами работал. Вот полный код с инициализацией мне бы помог. Заранее спасибо! Вечный студент Алла.
|
|
|
|
|
Aug 14 2016, 16:36
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(Alla_student @ Aug 14 2016, 19:30)  Вот полный код с инициализацией мне бы помог. Заранее спасибо! Вечный студент Алла. В упомянутом мной документе имеются также примеры инициализации. А с разной скоростью проблем нет - по Вашему алгоритму приём/передача по UART1 не пересекаются во времени с приёмом/передачей по UART2. 1. Принял по UART1 - выплюнул в UART2. 2. Принял по UART2 - выплюнул в UART1. 3. goto 1. Цитата(toweroff) смотрим приемный UART Наверно, Вы хотели сказать "приемлимый"?
|
|
|
|
|
Aug 14 2016, 17:00
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(RabidRabbit @ Aug 14 2016, 19:36)  1. Принял по UART1 - выплюнул в UART2. Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600. Что будет, если в UART1 придет 2 символа? Первый запишется в UART2 и начнется передача по UART2. А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать. Цитата(Alla_student @ Aug 14 2016, 18:30)  Спасибо за код кольцевого буфера FIFO, но как я выше писала, не могу с флагами и приоритетами разобраться, чтобы алгоритм приема передачи между портами работал. Вот полный код с инициализацией мне бы помог. Заранее спасибо! Вечный студент Алла. С такими запросами в раздел "предлагаю работу". Что именно не понятно с флагами и приоритетами?
|
|
|
|
|
Aug 14 2016, 17:28
|

Местный
  
Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040

|
Цитата(adnega) Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600. Что будет, если в UART1 придет 2 символа? Первый запишется в UART2 и начнется передача по UART2. А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать. Ну если прочитать первое сообщение топика, то всё должно быть понятно  Немного подправлю: 1. Принял пакет по UART1 - выплюнул пакет в UART2. 2. Принял пакет по UART2 - выплюнул пакет в UART1. 3. goto 1.
|
|
|
|
|
Aug 14 2016, 20:33
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 5-04-11
Пользователь №: 64 146

|
Цитата(adnega @ Aug 14 2016, 21:00)  Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600. Что будет, если в UART1 придет 2 символа? Первый запишется в UART2 и начнется передача по UART2. А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать. Не внимательно читали выше мою писанину. - Не будет такой ситуации. Цитата С такими запросами в раздел "предлагаю работу". Что именно не понятно с флагами и приоритетами? Спасибо за совет о разделе "предлагаю работу", а мне только остается подавать объявление "ищу работу"  C флагами все понятно..., почти, но только мой код не работает, поэтому я пишу привести пример работы с двумя портами UART, которого я не нашла в интернете. Я не прошу привести весь код, а только части программы инициализации и работы с флагами приема, прерываний с двумя портами. С одним вроде ясно. Цитата(adnega @ Aug 14 2016, 22:08)  И что же такое "пакет"? Как узнать конец пакета? По таймуату или разбирать протокол?
Можно просто сделать два FIFO-потока, чтоб не привязываться к таймаутам и протоколам. Принятый пакет пока не собиралась разбирать, возможно позже понадобится. Про таймауты выше писала. Без них нельзя. Цитата(RabidRabbit @ Aug 14 2016, 21:28)  Ну если прочитать первое сообщение топика, то всё должно быть понятно  Немного подправлю: 1. Принял пакет по UART1 - выплюнул пакет в UART2. 2. Принял пакет по UART2 - выплюнул пакет в UART1. 3. goto 1. Вам понятно, а у меня код не работает. Но уже это смахивает на "У попа была собака...".
|
|
|
|
|
Aug 16 2016, 06:32
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 5-04-11
Пользователь №: 64 146

|
Цитата(adnega @ Aug 15 2016, 01:35)  Обычно в таких ситуациях говорят: "код в студию". "код в студию"  ... Всем спасибо. Прочитала еще раз название раздела конференции: "В помощь начинающему > ARM, 32bit" - вроде по адресу вопрос задала, но так реальной помощи не получила. Буду дальше искать проблему и возможно в других конференциях найду все таки ответ или кто нибудь приведет пример рабочего кода. С уважением. Вечный студент Алла.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|