реклама на сайте
подробности

 
 
> Мост между юсартами, STM32F205, usart2 - usart3
Volldemar
сообщение Mar 19 2014, 05:09
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 27-04-09
Из: Украина
Пользователь №: 48 342



Задача: по юсарт2 идут данные с темпом 1 сек, но разного объёма, типа:
Код
$GPRMC,074038.00,A,4912.3940,N,03151.9618,E,00.00,314.7,190314,,,A*59
$GPGSV,4,1,14,01,39,183,24,04,20,314,00,11,12,181,00,13,27,237,29*7F
$GPGSV,4,2,14,17,17,275,01,20,86,111,18,23,63,242,45,25,05,022,00*7C
$GPGSV,4,3,14,31,39,059,00,32,44,102,00,33,18,235,00,37,33,193,00*7F
$GPGSV,4,4,14,39,33,189,00,40,29,150,00*7D

эти данные нужно обрабатывать и выдавать в юсарт3.

Как задумывалось решение:
Настраиваю аппаратный таймер (ТИМ2) на длительность передачи одного байта при скорости 115200. В прерывании юсарт2 принятые байты складываю в массив и обнуляю ТИМ2:
Код
if( USART_GetITStatus( USART2, USART_IT_RXNE ) == SET )
      {
         cChar = USART_ReceiveData( USART2 );
         if ((USART2_Idx == USART2_SIZE-1) || (cChar == '$'))
            {
               USART2_Idx = 0;
            }
         USART2_Buf[USART2_Idx] = cChar;
         USART2_Idx++;
         TIM_SetCounter(TIM2, 0);
         TIM_Cmd(TIM2, ENABLE);
      }

В прерывании ТИМ2, если он таки досчитает до конца, значит байтов больше нет, выставляю семафор:
Код
void TIM2_IRQHandler(void)
{
   portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

   if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
      {
         TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //Очищаем бит обрабатываемого прерывания
         TIM_Cmd(TIM2, DISABLE); //выключаю таймер
         xSemaphoreGiveFromISR (xSemaphore_usart2, &xHigherPriorityTaskWoken ); //семафорим задаче
      }
}

Ну и сама задача:
Код
   for(;; )
   {
      xSemaphoreTake(xSemaphore_usart2, portMAX_DELAY );
      for (i=0; i<USART2_Idx; i++)
         {
            cChar = USART2_Buf[i];
            xQueueSend( usart3_TxQueue, &cChar, xNoBlock );
         }
      USART2_Idx = 0;
      USART_ITConfig( USART3, USART_IT_TXE, ENABLE );
   }

Вопрос, что не так делаю, но выдача в юсарт3 происходит не стабильно, может в принципе построение решения не правильное? Надеюсь на конструктивное советы и пожелания wink.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Genadi Zawidowsk...
сообщение Mar 19 2014, 05:17
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Поможет? Посимвольный приём. В некоторых местах форумный движок заменил латинский символ ЦЕ в скобочках на какую-то хрень.
CODE
static uint_fast8_t nmea_state = NMEAST_INITIALIZED;
static uint_fast8_t nmea_checksum;
static uint_fast8_t nmea_chsval;
static uint_fast8_t nmea_param; // номер принимаемого параметра в строке
static uint_fast8_t nmea_chars; // количество символов, помещённых в буфер

#define NMEA_PARAMS 20
#define NMEA_CHARS 12 // really need 11
static char nmea_buff [NMEA_PARAMS] [NMEA_CHARS];
static timeholder_t nmea_time;
static timeholder_t th;
static volatile uint_fast8_t secoundticks;

static unsigned char hex2int(uint_fast8_t c)
{
if (isdigit©)
return c - '0';
if (isupper©)
return c - 'A' + 10;
if (islower©)
return c - 'a' + 10;
return 0;
}

static void nmea_parsrchar(uint_fast8_t c)
{

switch (nmea_state)
{
case NMEAST_INITIALIZED:
if (c == '$')
{
nmea_checksum = '*';
nmea_state = NMEAST_OPENED;
nmea_param = 0; // номер принимаемого параметра в строке
nmea_chars = 0; // количество символов, помещённых в буфер
}
break;

case NMEAST_OPENED:
nmea_checksum ^= c;
if (c == ',')
{
// закрываем буфер параметра, переходим к следующему параметру
nmea_buff [nmea_param][nmea_chars] = '\0';
nmea_param += 1;
nmea_chars = 0;
}
else if (c == '*')
{
// закрываем буфер параметра, переходим к следующему параметру
nmea_buff [nmea_param][nmea_chars] = '\0';
nmea_param += 1;
// переходим к приёму контрольной суммы
nmea_state = NMEAST_CHSHI;
}
else if (nmea_param < NMEA_PARAMS && nmea_chars < (NMEA_CHARS - 1))
{
nmea_buff [nmea_param][nmea_chars] = c;
nmea_chars += 1;
//stat_l1 = stat_l1 > nmea_chars ? stat_l1 : nmea_chars;
}
else
nmea_state = NMEAST_INITIALIZED; // при ошибках формата строки
break;

case NMEAST_CHSHI:
nmea_chsval = hex2int© * 16;
nmea_state = NMEAST_CHSLO;
break;

case NMEAST_CHSLO:
nmea_state = NMEAST_INITIALIZED;
if (nmea_checksum == (nmea_chsval + hex2int©))
{
if (nmea_param > 2 &&
strcmp(nmea_buff [0], "GPRMC") == 0 &&
strcmp(nmea_buff [2], "A") == 0 &&
1)
{
// разбор времени
const char * s = nmea_buff [1]; // начало буфера, где лежит строка времени.формата 044709.00 или 044709.000
nmea_time.hours = (s [0] - '0') * 10 + (s [1] - '0');
nmea_time.minutes = (s [2] - '0') * 10 + (s [3] - '0');
nmea_time.secounds = (s [4] - '0') * 10 + (s [5] - '0');
nmea_time.ms = 0; //strtoul(s + 7, NULL, 10);
time_next(& nmea_time); // какое время надо будет поставить для установки в следующий PPS
}
}
break;
}
}


Сообщение отредактировал Genadi Zawidowski - Mar 19 2014, 05:19
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th August 2025 - 12:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01393 секунд с 7
ELECTRONIX ©2004-2016