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

 
 
> scmRTOS+485-й, Как правильно пользоваться каналом?
Colobox
сообщение Feb 4 2008, 09:18
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 36
Регистрация: 31-10-07
Пользователь №: 31 901



Доброго времени суток!
Простенькая вроде прога и все хорошо и логично, и работает… но только 40 сек.
Программка общения МК с терминалкой. Терминалка посылает каждые 50 мс команду опроса длиной 4 байта плюс кс- 3f 0 0 0 3f, в ответ МК кидает также 4 байта плюс кс: 47 0 0 0 47, но это детали. Проц АТмега 8, 12МГц, сист. тик- 6 мс
Проблема в том, что примерно через 40 сек, видимо, не проходит сброс счетчика принятых байт и контрольной суммы. Перерывания по- уарту (прием байта) вызываются.
Подскажите, где тут может быть баг или неправильное понимание?
Код
#define scmRTOS_ISRW_TYPE   TISRW_SS
……………………………………………………
#define  scmRTOS_CONTEXT_SWITCH_SCHEME      0
……………………………………………………
OS::channel<unsigned char,10> chn_Rx;//канал на 10 байт
……………………………………………………
//-------------------------------------------------------------------------
#pragma vector = USART_RXC_vect
OS_INTERRUPT void RX(void)
{
OS::scmRTOS_ISRW_TYPE ISR;
UART_Rx();
}
//-------------------------------------------------------------------------
void UART_Rx(void)  
{
unsigned char udrx=UDR;//принимаем байт
if(chn_Rx.get_free_size()) chn_Rx.push(udrx);// запихиваем принятый байт в канал
}
//---------------------------------------------------------------------------
…………………………………………………………………………
OS_PROCESS void TPRx::Exec()
{
  unsigned char count_rx_byte=0;// счетчик принятых байт
  unsigned char RxBuffer[LEN_RX];//приемный буфер
  unsigned char rx_crc=0;// контрольная сумма
    for(;;)
    {
    unsigned char rx=0;
     if (chn_Rx.pop(rx,2))//вытаскиваем из очереди очередной байт
         {
          RxBuffer[count_rx_byte]=rx;//в буфер его
          //вычисляем  КС:
          if(count_rx_byte<LEN_RX-1)  rx_crc=rx_crc^RxBuffer[count_rx_byte];
              else  //если подошел последний байт пакета и КС совпала:
                   if((count_rx_byte==LEN_RX-1)&&(RxBuffer[count_rx_byte]==rx_crc))
                                  Answer();//функция загрузки в ответ  первого байта передачи в UDR
// дальнейшие загрузки байтов- по прерыванию от UART (передача)
          count_rx_byte++;//на следующий байт
          }  else  //если через 2 тика сист. таймера (12 мс) ничего не пришло- сбрасываем параметры приема:
          {
           count_rx_byte=0;//сюда через сек 40 уже не приходим...
           rx_crc=0;
          };
     }//end_of_for(;;)
} end_of_ OS_PROCESS
//---------------------------------------------------------------------------
…………………………………………………………………


Еще по-теме,- в одной из веток по scmRTOS:
Цитата(Сергей Борщ @ Oct 1 2007, 17:53) *
Ну например прерывание передачи по UART забирает данные из OS:channel<uint8_t>. А данные там кончились... В этом случае pop() попытается передать управление другой задаче, и это приведет к краху. Поэтому прежде чем вызвать pop() надо проверить - а есть ли данные. Аналогично для push().


Почему должен быть крах? Вроде так и надо- нет работы- уйди… А в случае вызова рор() или push() из обработчика прерывания ,- перепланировщик там же не имеет действия!
Хотя, если из void UART_Rx(void) исключить "if(chn_Rx.get_free_size()) "- проц виснет савсем.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 26th June 2025 - 02:19
Рейтинг@Mail.ru


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