Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F051K8 передача данных с UART1 на UART2 и обратно
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Alla_student
Здравствуй 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 просто боюсь связываться.
В конференциях аналогичного ничего рабочего не нашла.
Буду признательна, если кто нибудь объяснит и даст пример рабочего кода для этой задачи.

С уважением. Вечный студент Алла.
RabidRabbit
По-моему, с таким алгоритмом и прерываний не требуется, достаточно опроса флагов состояния UART sm.gif В документе RM0091 содержаться даже примеры по работе с UART, как настройка, так и передача/приём.

www.st.com/resource/en/reference_manual/dm00031936.pdf
toweroff
Цитата(RabidRabbit @ Aug 13 2016, 21:54) *
В документе RM0091 содержаться даже примеры

bb-offtopic.gif
ну едрён батон, сколько ж можно sad.gif
что делают? - содЕржатся
что БУДУТ делать - будут содержАться

А по теме - да, ничего и не нужно
Ждем байт из одного UART, если нет ничего - смотрим приемный UART
и тупо перекидываем принятое туда-сюда. В тупом цикле while(1)
TSerg
Цитата(toweroff @ Aug 13 2016, 23:26) *
ну едрён батон, сколько ж можно sad.gif


bb-offtopic.gif
Инвалиды ЕГЭ.
Alla_student
Цитата(RabidRabbit @ Aug 13 2016, 22:54) *
По-моему, с таким алгоритмом и прерываний не требуется, достаточно опроса флагов состояния UART sm.gif В документе RM0091 содержаться даже примеры по работе с UART, как настройка, так и передача/приём.

www.st.com/resource/en/reference_manual/dm00031936.pdf


Спасибо, читала этот документ, но мне сложно завести именно два UART-а, а в документе этого нет, надо расставить приоритеты - работа с флагами и буферами данных, здесь видимо для меня засада.
Да, и я спрашивала про реализацию алгоритма именно с двумя буферами выделенными в ОЗУ, или возможно реализацию FIFO с DMA или без. Это уже для меня "темный лес". Для чего это надо - я не указала, что скорость передачи данных на UART-ах разная. Поэтому уважаемый ALL! - Прошу привести примеры реализации этого алгоритма, если конечно не сложно, без примера я не разберусь, уже вторую неделю пытаюсь. Думаю и другим новичкам будет интересно.

PS: В интернете не одного рабочего примера моста между внутренними UART-ами с буферизацией не нашла, только тупо перекладыванием байта, что при кратковременной паузе в данных или при разных скоростях на портах, не будет работать.

Заранее спасибо за помощь!
adnega
Я бы сделал реализацию кольцевого 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 - тривиально.
x893
Алгоритм работы раскрыт не полностью.
1. Что происходит если приходит байт из устройства, а
а. буфер от PC не заполнен
б. буфер от PC передан на устройство не полностью

2. Что проиодит, если данные передаются в PC, а
а. Приходят данные от устройства
б. приходят данные от PC

Нарисуйте на бумажке диаграмму работы (из стрелок и квадратиков).
Начальных точек входа у Вас 4
1. Приняты данные от PC
2. Отправлены данные в PC
3. Приняты данные от устройства
4. Отправлены данные в устройство.

Коды наколбасить для STM или любого другого - два часа максимум.
Alla_student
Цитата(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, но как я выше писала, не могу с флагами и приоритетами разобраться, чтобы алгоритм приема передачи между портами работал. Вот полный код с инициализацией мне бы помог.
Заранее спасибо! Вечный студент Алла.
RabidRabbit
Цитата(Alla_student @ Aug 14 2016, 19:30) *
Вот полный код с инициализацией мне бы помог.
Заранее спасибо! Вечный студент Алла.

В упомянутом мной документе имеются также примеры инициализации. А с разной скоростью проблем нет - по Вашему алгоритму приём/передача по UART1 не пересекаются во времени с приёмом/передачей по UART2.
1. Принял по UART1 - выплюнул в UART2.
2. Принял по UART2 - выплюнул в UART1.
3. goto 1.


bb-offtopic.gif

Цитата(toweroff)
смотрим приемный UART

Наверно, Вы хотели сказать "приемлимый"?

adnega
Цитата(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, но как я выше писала, не могу с флагами и приоритетами разобраться, чтобы алгоритм приема передачи между портами работал. Вот полный код с инициализацией мне бы помог.
Заранее спасибо! Вечный студент Алла.

С такими запросами в раздел "предлагаю работу".
Что именно не понятно с флагами и приоритетами?
RabidRabbit
Цитата(adnega)
Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600.
Что будет, если в UART1 придет 2 символа?
Первый запишется в UART2 и начнется передача по UART2.
А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать.

Ну если прочитать первое сообщение топика, то всё должно быть понятно sm.gif Немного подправлю:
1. Принял пакет по UART1 - выплюнул пакет в UART2.
2. Принял пакет по UART2 - выплюнул пакет в UART1.
3. goto 1.
adnega
Цитата(RabidRabbit @ Aug 14 2016, 20:28) *
Ну если прочитать первое сообщение топика, то всё должно быть понятно sm.gif

И что же такое "пакет"? Как узнать конец пакета?
По таймуату или разбирать протокол?

Можно просто сделать два FIFO-потока, чтоб не привязываться к таймаутам и протоколам.
Alla_student
Цитата(adnega @ Aug 14 2016, 21:00) *
Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600.
Что будет, если в UART1 придет 2 символа?
Первый запишется в UART2 и начнется передача по UART2.
А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать.

Не внимательно читали выше мою писанину. - Не будет такой ситуации.
Цитата
С такими запросами в раздел "предлагаю работу".
Что именно не понятно с флагами и приоритетами?

Спасибо за совет о разделе "предлагаю работу", а мне только остается подавать объявление "ищу работу" sad.gif
C флагами все понятно..., почти, но только мой код не работает, поэтому я пишу привести пример работы с двумя портами UART, которого я не нашла в интернете. Я не прошу привести весь код, а только части программы инициализации и работы с флагами приема, прерываний с двумя портами. С одним вроде ясно.

Цитата(adnega @ Aug 14 2016, 22:08) *
И что же такое "пакет"? Как узнать конец пакета?
По таймуату или разбирать протокол?

Можно просто сделать два FIFO-потока, чтоб не привязываться к таймаутам и протоколам.

Принятый пакет пока не собиралась разбирать, возможно позже понадобится.
Про таймауты выше писала. Без них нельзя.

Цитата(RabidRabbit @ Aug 14 2016, 21:28) *
Ну если прочитать первое сообщение топика, то всё должно быть понятно sm.gif Немного подправлю:
1. Принял пакет по UART1 - выплюнул пакет в UART2.
2. Принял пакет по UART2 - выплюнул пакет в UART1.
3. goto 1.

Вам понятно, а у меня код не работает. Но уже это смахивает на "У попа была собака...".
adnega
Цитата(Alla_student @ Aug 14 2016, 23:33) *
но только мой код не работает

Обычно в таких ситуациях говорят: "код в студию".
Alla_student
Цитата(adnega @ Aug 15 2016, 01:35) *
Обычно в таких ситуациях говорят: "код в студию".

"код в студию" sad.gif ... Всем спасибо. Прочитала еще раз название раздела конференции: "В помощь начинающему > ARM, 32bit" - вроде по адресу вопрос задала, но так реальной помощи не получила. Буду дальше искать проблему и возможно в других конференциях найду все таки ответ или кто нибудь приведет пример рабочего кода.

С уважением. Вечный студент Алла.
adnega
Цитата(Alla_student @ Aug 16 2016, 09:32) *
но так реальной помощи не получила.

Вы спрашиваете: "сколько будет 2+2"?
Вам рассказывают правила арифметики и методики решения задач.
А вы готовы лишь услышать правильный ответ "4".
Какой толк от вашей темы другим людям, которым нужно узнать "3+4" и "5+1"?

Вы же утверждаете, что нерабочий код у вас уже есть. В чем сложность его опубликовать?
Вам бы быстро сказали что и где не так.
x893
Доктору без анализов трудно помочь больному.
Так же и здесь.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.