Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USART передача пакетов
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Anub
Имеется два МК между которыми необходимо произвести пакетную передачу команд. Первый мк отсылает два пакета с периодом в пол секунды после чего дает на порта лог1 и уходит в бесконечный цикл.
Переменные
Код
char COMMAND[30];
int i = 0;

Код

      putsf("run/");
      delay_ms(500);
      putsf("runb/");
      PORTA=0xFF;
      while(1){};

Второй МК принимает эти пакеты в обработчике прерывания получения символа. Обработчик собирает все сибволы в массив пока не будет получен символ окончания пакета - /.
Код
if (data != '/')
   {
   COMMAND[i] = data;
   i++;  
   }
else
   {
   i = 0;
   activeCommand(COMMAND);
   }
}

Функция activeCommand проверяет совпадения и если совпадения верны то отправляет в потра разные комбинации(зажигает нужные светодиоды)
Код
void activeCommand(char c[])
{  
if (c[0]=='r'&c[1]=='u'&c[2]=='n')
   {
   PORTA=0x03;  
   }
if (c[0]=='r'&c[1]=='u'&c[2]=='n'&c[3]=='b')
   {
   PORTA=0x07;
   }
}

Проблема состоит в том что первый пакет передается и проверяется правильно, а вот на второй пакет реакцию нулевая.
И еще пугает вот что - на RXD принимающего напряжение равное напряжению питания...
aaarrr
Вообще-то оператор & - это битовый AND, для логических выражений существует &&. Кроме того, при получении второго пакета будут успешно выполняться оба условия.

Цитата
И еще пугает вот что - на RXD принимающего напряжение равное напряжению питания...

Почему пугает? 07.gif
Anub
В прерывание добавил PORTC=0x00; а в функцию PORTC=0xFF; . На портц лог0, это получается прерывание вызывается постоянно, cчетчик i постоянно тикает и в итоге команда записывается в произвольно место массива! Эт как так?
rezident
Я бы посоветовал на приеме проверять не только на совпадением с символом конца пакета, но и на выход на границы диапазона буфера. Если символ конца пакета будет принят с ошибкой, то вы рискуете переполнением буфера запороть другие данные в ОЗУ, находящиеся вне выделенного буфера.
А вообще при пакетной передаче обычно используют два маркера: начало пакета и конец пакета.
aaarrr
Цитата(Anub @ Aug 16 2008, 17:35) *
В прерывание добавил PORTC=0x00; а в функцию PORTC=0xFF; . На портц лог0, это получается прерывание вызывается постоянно, cчетчик i постоянно тикает и в итоге команда записывается в произвольно место массива! Эт как так?

Код полностью выложите, тогда можно будет что-нибудь определенное сказать.
Anub
Код
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index]=data;
   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      };
   };
if (data != '/')
   {
   COMMAND[i] = data;
   i++;  
   }
else
   {
   i = 0;
   activeCommand(COMMAND);
   }
   PORTC=0x00;
}


Код
void activeCommand(char c[])
{  
if (c[0]=='r'&&c[1]=='u'&&c[2]=='n')
   {
   PORTA=0x03;  
   }          
if (c[0]=='r'&&c[1]=='u'&&c[2]=='n'&&c[3]=='b')
   {
   PORTA=0x07;
   }
   PORTC=0xFF;
}
aaarrr
Ну, теперь понятно, почему PORTC всегда равен 0x00:

Код
interrupt [USART_RXC] void usart_rx_isr(void)
{
   ...
   activeCommand(COMMAND); // PORTC=0xFF
   }
   PORTC=0x00;
}



Я бы несколько изменил процедуру обработки прерывания:
Код
interrupt [USART_RXC] void usart_rx_isr(void)
{
    char data = UDR;

//if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) - такая проверка бессмысленна, так как Вы все равно получите ошибочный пакет

    if(!rx_done)
    {
        rx_buffer[rx_wr_index++] = data;
        if(data == '/') rx_done = 1;
        else if(rx_wr_index >= RX_BUFFER_SIZE)
        {
            rx_wr_index = 0;
            rx_buffer_overflow = 1;
        }
    }
    else rx_data_overrun = 1;
}


И обрабатывал бы полученные данные в main'е по флагу rx_done.
SysRq
Автору стоит вообще разобраться с тем кодом который он сам не писал (насколько я вижу, код обработчика прерывания сгенерил CodeVision) и либо воспользоваться им, либо удалить...
Anub
Все, разобрался. Пакет стал приниматься только после того как я ввел байт начала пакета.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.