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

Не такая и тяжелая эта операция. У меня счас буфер 384 байта. Раз в секунду ищется подстрока "$GPRMC", выкопирываются оттуда секунды, минуты, часы, дни, месяцы, годы. Все это передается RTC и выводиться на textlcd. Еще остается времени для другой работы.

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

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


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

Та ладна, чё там тяжелого.Гляньте исходник в вашем компиляторе.

Там тупо перебор от забора и до обеда (gcc). Пробовал как-то так делать и это оказалось жутко медленно. Например, принято 200 байт и из них нужно найти 5 - это делалось в цикле, а приём в прерывании, так кроме поиска подстроки проц на 100 МГц больше ничего не мог делать.

 

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


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

Там тупо перебор от забора и до обеда (gcc). Пробовал как-то так делать и это оказалось жутко медленно. Например, принято 200 байт и из них нужно найти 5 - это делалось в цикле, а приём в прерывании, так кроме поиска подстроки проц на 100 МГц больше ничего не мог делать.

 

А если так:

 

unsigned char RMCStrHead[]="GPRMC,";// длина 6 байт 
unsigned char RMCRxState, NMEASum;

// приём нового байта в прерываниии:
if (NextByteReceived) {
    unsigned char new_byte=GetByteFromGPSUART();// чтение нового байта
    if (RMCRxState>0 && RMCRxState<NMEA_READ_SUM_STATE) NMEASum^=new_byte;
    switch (RMCRxState) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        if (new_byte==RMCStrHead[RMCRxState])
            RMCRxState++;
        else RMCRxState=0;
        if (RMCRxState==1) NMEASum=new_byte;
        break;
    case 6:
    case 7:
    case 8:
    case ...:// столько, сколько нужно
        //выделение нужных полей по запятым
        //при приёме символа CR или LF - сброс в RMCRxState 0
        //при прёме * - след. 2 байта - сумма считывание суммы
        //если сумма совпала - первичное обновление данных
        //если сумма не совпала - начать приём сначала
        break;
    }
}

 

Например, принято 200 байт и из них нужно найти 5 - это делалось в цикле, а приём в прерывании, так кроме поиска подстроки проц на 100 МГц больше ничего не мог делать.

 

Использовал ATMega128 на 11,0592МГц, приём в прерывании 10 кГц и разбор строки в прерывании 1 кГц, скорость порта приёмника 9600. Занимало производительности чуть более чем ничего.

 

 

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


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

Это что-то вроде дерева получается, должно быть очень эффективно, спасибо за идею

А ещё можно так: в прерывании в буфер записывается символ и ++указатель. В цикле проверяется изменился ли указатель с прошлого раза. Если да - был приём, берём разницу (сколько байт принято) и делаем memcmp с нужными подстроками от буфер[указатель - длина искомой строки - i ], где i счётчик в цикле от 1 до кол-ва принятых байт.

Использовал ATMega128 на 11,0592МГц, приём в прерывании 10 кГц и разбор строки в прерывании 1 кГц, скорость порта приёмника 9600. Занимало производительности чуть более чем ничего.

Ну значит я где-то накосячил. Ладно, пускай будет strstr :)

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


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

А ещё можно так: в прерывании в буфер записывается символ и ++указатель. В цикле проверяется изменился ли указатель с прошлого раза. Если да - был приём, берём разницу (сколько байт принято) и делаем memcmp с нужными подстроками от буфер[указатель - длина искомой строки - i ], где i счётчик в цикле от 1 до кол-ва принятых байт.

 

Тогда лучше так:

struct TRxBuffer {
unsigned char Buf[BUF_SIZE];
unsigned char Next, First, ByteToRead;
void WriteByte(unsigned char b) {
    Buf[Next]=b;
    ItemCount++;
    if (++Next==BUF_SIZE) Next=0;
}
/// и т.д.
}

 

И лучше сделать шаблонный класс.

 

 

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


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

В свое время столкнулся с задачей разбора RMC и GGA строк на 51 контроллере, ни о каком сохранении строк там речи быть не может - памяти там минимум, так что парсер работает из прерывания и сразу разбирает строку. В прерывании не сидит долго.

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

Парсер проверен с несколькими видами gps и глонасс приемников, на разных контроллерах от 51 до ARM, работает стабильно, надеюсь кому нибудь будет полезен:

gps_parser

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


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

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

 

Насколько я понял из стандарта нмеа поле значения это ascii цифры разделенные запятыми и в общем случае переменной длинны.

Допускается ли делать поля фиксированной длинны - дополняя число нулям.

 

И такой вопрос в стандарте говорится что если для поля нет данных то остаются только запятые, в тоже время в описании GPS сентенций

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

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


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

Допускается ли делать поля фиксированной длинны - дополняя число нулям.

Это как это - вы анализируете протокол НМЕА, или его формируете? Во втором случае дополняйте на здоровье. А при анализе ешьте то, что дают.

И такой вопрос в стандарте говорится что если для поля нет данных то остаются только запятые, в тоже время в описании GPS сентенций

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

Все известные мне GPS-приемники и компасы (работающие в нмеа) знаков подчеркивания не формировали, при пустом поле идут запятые подряд

 

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


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

Данные я формирую так что по первому пункту первому хорошо.

А по второму переделаю. Спасибо

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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