STM Урок 116. FreeRTOS. Прерывания. Очереди в прерываниях. Часть 2

 

 

 

 

В предыдущей части нашего занятия мы познакомились с механизмом использования API FreeRTOS в телах обработчиков прерываний, создали и настроили проект и написали код для отправки байта, принятого по шине USART, в очередь.

Теперь в функции задачи для обработки байта и разбора строк TaskParseUSART мы создадим несколько локальных переменных и указатель на структуру очереди для передачи строки функции задачи для вывода строк на дисплее

 

void TaskParseUSART(void const * argument)

{

  osEvent event;

  static char str[30];

  static uint8_t cnt=0;

  uint8_t b;

  int yp;

  struct_out *qstruct;

 

Зададим цвет для строки, выводимой на дисплей

 

struct_out *qstruct;

TFT_SetTextColor(LCD_COLOR_BLUE);

 

Добавим бесконечный цикл

 

TFT_SetTextColor(LCD_COLOR_BLUE);

for(;;)

{

}

 

В бесконечном цикле примем байт из очереди

 

for(;;)

{

  event = osMessageGet(USART_Queue, 100);

 

Добавим условие наличия данных в очереди

 

event = osMessageGet(USART_Queue, 100);

if (event.status == osEventMessage)

{

}

 

В теле условия заберём байт из очереди в переменную

 

if (event.status == osEventMessage)

{

  b= event.value.v;

 

Если превысили количество байтов для строки, обнулим счётчик

 

b= event.value.v;

//если вдруг случайно превысим длину буфера

if(cnt>25)

{

  cnt=0;

}

 

Сохраним байт в массив в позицию, соответствующую значению счётчика, перед этим выйдя из тела условия

 

  cnt=0;

}

str[cnt] = b;

 

Наша тестовая строка будет состоять из двух символов и заканчиваться будет символами возврата каретки и перевода строки. Последний из них будет 0x0A.

Поэтому исследуем наш байт на равенство коду данного символа, а в противном случае инкрементируем счётчик

 

str[cnt] = b;

if(b==0x0A)

{

}

else cnt++;

 

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

Обнулим предыдущий символ, так как это скорей всего 0x0D. Это и будет окончание принятой строки

 

if(b==0x0A)

{

  str[cnt-1]=0;

 

Вообще наша строка будет состоять из строки «String» и двух символов однозначного целого числа, первое из которых будет номером строки, а второе — множителем для позиции по вертикали.

Выделим память под структуру для очереди и проинициализируем нашу структуру

 

str[cnt-1]=0;

qstruct = osMailAlloc(strout_Queue, osWaitForever);

qstruct->tick_count = osKernelSysTick();

yp = atoi(str+7);

qstruct->y_pos = yp*60;

 

Мы преобразовали элемент по 7-му адресу в строке в число. Умножили данное число на 60. Это и будет позиция по вертикали.

 

 

На всякий случай проверим, что мы не ушли за пределы позиции, затем обнулим в строковом массиве элемент, где был индекс позиции, теперь это будет конец строки, так как нам не нужно отображать данное число, затем соответствующему элементу очереди приравняем указатель на нашу строку и отправим нашу структуру в очередь для последующего приёма её в функции задачи, отвечающей за вывод строк на дисплее. Также затем, выйдя из условия, обнулим счётчик

 

qstruct->y_pos = yp*60;

if ((yp<=3)&&(yp>=1))

{

  str[cnt-2]=0;

  sprintf(qstruct->str, "%s", str);

  osMailPut(strout_Queue, qstruct);

}

cnt=0;

 

Соберём наш код и прошьём контроллер.

В результате мы получим лишь только шапку, так как мы ещё не послали в шину USART нашего контроллера никакие строки

 

 

Как же можно нам это сделать, чтобы как-то автоматизировать процесс? Не вводить же нам постоянно строки в терминальной программе.

Есть вариант подключения ещё одного контроллера и передачи с него строк по тому же USART, такой вариант у меня в мыслях был. Но потом меня вдруг осенило! Ведь можно же в терминальной программе Terminal 1b писать скрипты. Вот этим мы сейчас и займёмся. Конечно, я не буду подробно описывать механизм написания скриптов, так как урок не об этом, но как и куда их писать, я конечно же расскажу.

Запустим программу Terminal 1b, соединимся с нашим портом, настроив порты и нажав и нажмём в программе кнопку Connect, а затем нажмём кнопку Scripting

 

 

Теперь в открывшееся окно вставим скрипт следующего содержания

 

program test;

var i,j: integer;

str1: string;

begin

  str1:='String';

  while (true) do

  begin

    for j:=1 to 5 do

    begin

      for i:=1 to 3 do

      begin

        comsendstr(str1+inttostr(j)+inttostr(i)+#13+#10);

      end;

      Delay(1000);

    end;

  end;

end.

 

Если кто-то программировал в Pascal, ну или на худой конец в Basic, ничего здесь нового для себя не откроет, а если и не программировал, то здесь всё подобно и языку C, только вместо открывающей фигурной скобки здесь оператор begin, а вместо закрывающей — end. Остальное всё, в принципе, так же. API используется встроенный в программу.

Мы в данном скрипте создали и проинициализировали строковый массив. Здесь не нужно указывать его размер. Затем мы создали цикл от 1 до 5 для передачи различных пяти строк, отличающихся друг от друга лишь последней цифрой. затем мы в данном цикле создали ещё один цикл от 1 до 3, чтобы к строке ещё и присоединить индекс последующего отображения в определённом месте по вертикали на дисплее нашей Discovery. То есть каждая из 5 строк будет передаваться по 3 раза, только с разным индексом на конце, затем будет задержка на 1 секунду, чтобы мы успели рассмотреть наши 3 одинаковые строки в разных местах дисплея. Вот в принципе и весь код скрипта.

Сохраним на будущее наш скрипт в специальном формате с помощью кнопки Save

 

 

Затем нажмём кнопку Run и наш скрипт начнёт выполняться, если конечно в нём нет ошибок

 

 

А вот и результат

 

 

Можно попробовать изменить задержку. Я пробовал менять её до 1, всё работало корректно, что значит, что мы создали вполне вменяемый и оптимальный код, имеющий полное право на существование.

Итак, сегодня мы научились пользоваться механизмом очередей в обработчиках прерываний, и, оказывается, благодаря API, разработанному для контроллеров STM, мы не встретились ни с какими трудностями, так как борьбу с этим трудностями взял на себя данный API.

Благодарю за внимание!

 

Предыдущая часть Программирование МК STM32 Следующий урок

 

Исходный код

 

 

Отладочную плату можно приобрести здесь 32F746G-DISCOVERY

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM FreeRTOS. Прерывания. Очереди в прерываниях

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*