Перейти к содержанию
    

STM32F051K8 передача данных с UART1 на UART2 и обратно

Здравствуй 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В документе RM0091 содержаться даже примеры

:bb-offtopic:

ну едрён батон, сколько ж можно :(

что делают? - содЕржатся

что БУДУТ делать - будут содержАться

 

А по теме - да, ничего и не нужно

Ждем байт из одного UART, если нет ничего - смотрим приемный UART

и тупо перекидываем принятое туда-сюда. В тупом цикле while(1)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Спасибо, читала этот документ, но мне сложно завести именно два UART-а, а в документе этого нет, надо расставить приоритеты - работа с флагами и буферами данных, здесь видимо для меня засада.

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

 

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

 

Заранее спасибо за помощь!

Изменено пользователем Alla_student

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы сделал реализацию кольцевого 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 - тривиально.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Алгоритм работы раскрыт не полностью.

1. Что происходит если приходит байт из устройства, а

а. буфер от PC не заполнен

б. буфер от PC передан на устройство не полностью

 

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

а. Приходят данные от устройства

б. приходят данные от PC

 

Нарисуйте на бумажке диаграмму работы (из стрелок и квадратиков).

Начальных точек входа у Вас 4

1. Приняты данные от PC

2. Отправлены данные в PC

3. Приняты данные от устройства

4. Отправлены данные в устройство.

 

Коды наколбасить для STM или любого другого - два часа максимум.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Алгоритм работы раскрыт не полностью.

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

Заранее спасибо! Вечный студент Алла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот полный код с инициализацией мне бы помог.

Заранее спасибо! Вечный студент Алла.

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

1. Принял по UART1 - выплюнул в UART2.

2. Принял по UART2 - выплюнул в UART1.

3. goto 1.

 

 

:bb-offtopic:

 

смотрим приемный UART

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Принял по UART1 - выплюнул в UART2.

Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600.

Что будет, если в UART1 придет 2 символа?

Первый запишется в UART2 и начнется передача по UART2.

А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать.

 

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

Заранее спасибо! Вечный студент Алла.

С такими запросами в раздел "предлагаю работу".

Что именно не понятно с флагами и приоритетами?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600.

Что будет, если в UART1 придет 2 символа?

Первый запишется в UART2 и начнется передача по UART2.

А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать.

Ну если прочитать первое сообщение топика, то всё должно быть понятно :) Немного подправлю:

1. Принял пакет по UART1 - выплюнул пакет в UART2.

2. Принял пакет по UART2 - выплюнул пакет в UART1.

3. goto 1.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну если прочитать первое сообщение топика, то всё должно быть понятно :)

И что же такое "пакет"? Как узнать конец пакета?

По таймуату или разбирать протокол?

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.к. скорости разные, то предположим, что UART1 115200 бод, а UART2 9600.

Что будет, если в UART1 придет 2 символа?

Первый запишется в UART2 и начнется передача по UART2.

А второй не может быть записан, т.к. UART2 уже передает и будет еще долго передавать.

Не внимательно читали выше мою писанину. - Не будет такой ситуации.

С такими запросами в раздел "предлагаю работу".

Что именно не понятно с флагами и приоритетами?

Спасибо за совет о разделе "предлагаю работу", а мне только остается подавать объявление "ищу работу" :(

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

 

И что же такое "пакет"? Как узнать конец пакета?

По таймуату или разбирать протокол?

 

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

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

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

 

Ну если прочитать первое сообщение топика, то всё должно быть понятно :) Немного подправлю:

1. Принял пакет по UART1 - выплюнул пакет в UART2.

2. Принял пакет по UART2 - выплюнул пакет в UART1.

3. goto 1.

Вам понятно, а у меня код не работает. Но уже это смахивает на "У попа была собака...".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но только мой код не работает

Обычно в таких ситуациях говорят: "код в студию".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обычно в таких ситуациях говорят: "код в студию".

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

 

С уважением. Вечный студент Алла.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...