Main idea . Serial port interruptions are rare, so they should not affect the continuous cycle of the pressure regulator. Here is a piece of code with interruption from an incoming message, parsing of an incoming control line, and reading of an analog port.

Committer:
Aleksk
Date:
Thu Apr 09 22:38:58 2020 +0000
Revision:
0:342c0ede45d5
Child:
1:ad293c65b02c
Parsing long string from serial port by interrupt (RTOS mbed os5)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Aleksk 0:342c0ede45d5 1 #include "mbed.h"
Aleksk 0:342c0ede45d5 2 //10.04.2020 00:07
Aleksk 0:342c0ede45d5 3 //Программа для пошагового чтения байтов из порта (файла) и разделения потока байтов на подстроки в реальном времени. Разделитель - запятая.
Aleksk 0:342c0ede45d5 4 //Строка сообщения должна заканчиваться только одним символом /r или /n
Aleksk 0:342c0ede45d5 5 //Программа нормально разбивает принимаемую строку на подстроки в количестве равном количеству запятых, плюс последняя подстрока без запятой
Aleksk 0:342c0ede45d5 6 //$COMAND,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A - здесь W*6A будет нормапльно принята
Aleksk 0:342c0ede45d5 7 DigitalOut led(LED1);
Aleksk 0:342c0ede45d5 8 RawSerial pc(USBTX, USBRX);
Aleksk 0:342c0ede45d5 9 EventQueue *queue = mbed_event_queue(); //инициализация очереди событий RTOS mbed5
Aleksk 0:342c0ede45d5 10
Aleksk 0:342c0ede45d5 11 #define maxnstr 20 // maximum nbr of params(sybstrings) used to hold the data fields
Aleksk 0:342c0ede45d5 12 #define maxnsym 20 // maximum nbr of symbols
Aleksk 0:342c0ede45d5 13 char comand[maxnstr][maxnsym]={""}; //
Aleksk 0:342c0ede45d5 14 int nstr=0; //номер строки
Aleksk 0:342c0ede45d5 15
Aleksk 0:342c0ede45d5 16 void onDataReceived(); // callback
Aleksk 0:342c0ede45d5 17
Aleksk 0:342c0ede45d5 18 void read_serial() {
Aleksk 0:342c0ede45d5 19 char message[maxnstr][maxnsym]={""}; //обнуление строк (локального двумерного массива символов фиксированного размера)
Aleksk 0:342c0ede45d5 20 int zap=0; // счетчик запятых
Aleksk 0:342c0ede45d5 21 char chr; //байтовый символ полученный из порта (или файла)
Aleksk 0:342c0ede45d5 22 nstr=0; //обнуление счетчика строк (на самом деле счетчика запятых в сообщении)
Aleksk 0:342c0ede45d5 23 rs1:
Aleksk 0:342c0ede45d5 24 int string_possition=0; //номер символа (в строке) в массиве входящей строки сообщения
Aleksk 0:342c0ede45d5 25 do{ chr = pc.getc(); //вынимаем символ из буфера последовательного порта
Aleksk 0:342c0ede45d5 26 if (chr == ',')
Aleksk 0:342c0ede45d5 27 {
Aleksk 0:342c0ede45d5 28 zap++;
Aleksk 0:342c0ede45d5 29 message[nstr][string_possition] ='\0';
Aleksk 0:342c0ede45d5 30 nstr++;
Aleksk 0:342c0ede45d5 31 goto rs1;
Aleksk 0:342c0ede45d5 32 }
Aleksk 0:342c0ede45d5 33 if (chr == '\n' || chr == '\r'){message[nstr][string_possition] ='\0';break;} //если сообщение кончилось, то вставка окончания строки и выход из цикла
Aleksk 0:342c0ede45d5 34 message[nstr][string_possition] = chr; //складываем символы в строку
Aleksk 0:342c0ede45d5 35 string_possition++; //номер позиции символа увеличиваем на единицу
Aleksk 0:342c0ede45d5 36 }while (1);
Aleksk 0:342c0ede45d5 37 pc.printf("caught message_nstr is : %s\r\n", message[nstr]); //пойманное сообщение
Aleksk 0:342c0ede45d5 38 pc.printf("****Detect _,_ ****=%d\r\n",zap);
Aleksk 0:342c0ede45d5 39 for (int i=0; i<=nstr; i++) {strcpy(comand[i],message[i]);} //копирование строк в глобальный массив , размеры массивов должны совпадать!
Aleksk 0:342c0ede45d5 40
Aleksk 0:342c0ede45d5 41 pc.attach(&onDataReceived, Serial::RxIrq); // reattach interrupt - переподключение прерывания перед выходом из функции
Aleksk 0:342c0ede45d5 42 }
Aleksk 0:342c0ede45d5 43
Aleksk 0:342c0ede45d5 44 void onDataReceived() {
Aleksk 0:342c0ede45d5 45 pc.attach(NULL, Serial::RxIrq); // detach interrupt
Aleksk 0:342c0ede45d5 46 queue->call(read_serial); // process in a non ISR context - переход к функции приема строки в статусе отключенного прерывания (учим указатели!)
Aleksk 0:342c0ede45d5 47 }
Aleksk 0:342c0ede45d5 48
Aleksk 0:342c0ede45d5 49 int main() {
Aleksk 0:342c0ede45d5 50 pc.attach(&onDataReceived, Serial::RxIrq); //подключение прерывания и имя функции обработчика прерывания по входящему символу в serial порту
Aleksk 0:342c0ede45d5 51 while (1) {
Aleksk 0:342c0ede45d5 52 for (int i=0; i<=nstr; i++) {pc.printf("main cycle - comand_nstr is : %s\r\n", comand[i]);} //печать подстрок пойманного сообщения
Aleksk 0:342c0ede45d5 53 ThisThread::sleep_for(2000); // (mc) правильный оператор задержки для mbed5
Aleksk 0:342c0ede45d5 54 led = !led;
Aleksk 0:342c0ede45d5 55 }
Aleksk 0:342c0ede45d5 56 }