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

 
 
 
Reply to this topicStart new topic
> USART передача пакетов, Получаю только первый пакет
Anub
сообщение Aug 16 2008, 12:11
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-08
Пользователь №: 37 825



Имеется два МК между которыми необходимо произвести пакетную передачу команд. Первый мк отсылает два пакета с периодом в пол секунды после чего дает на порта лог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 принимающего напряжение равное напряжению питания...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 16 2008, 12:31
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



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

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

Почему пугает? 07.gif
Go to the top of the page
 
+Quote Post
Anub
сообщение Aug 16 2008, 13:35
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-08
Пользователь №: 37 825



В прерывание добавил PORTC=0x00; а в функцию PORTC=0xFF; . На портц лог0, это получается прерывание вызывается постоянно, cчетчик i постоянно тикает и в итоге команда записывается в произвольно место массива! Эт как так?

Сообщение отредактировал Anub - Aug 16 2008, 13:40
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 16 2008, 13:41
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Я бы посоветовал на приеме проверять не только на совпадением с символом конца пакета, но и на выход на границы диапазона буфера. Если символ конца пакета будет принят с ошибкой, то вы рискуете переполнением буфера запороть другие данные в ОЗУ, находящиеся вне выделенного буфера.
А вообще при пакетной передаче обычно используют два маркера: начало пакета и конец пакета.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 16 2008, 13:48
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Anub @ Aug 16 2008, 17:35) *
В прерывание добавил PORTC=0x00; а в функцию PORTC=0xFF; . На портц лог0, это получается прерывание вызывается постоянно, cчетчик i постоянно тикает и в итоге команда записывается в произвольно место массива! Эт как так?

Код полностью выложите, тогда можно будет что-нибудь определенное сказать.
Go to the top of the page
 
+Quote Post
Anub
сообщение Aug 16 2008, 13:51
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-08
Пользователь №: 37 825



Код
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;
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 16 2008, 14:00
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Ну, теперь понятно, почему 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.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Aug 16 2008, 21:09
Сообщение #8


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Автору стоит вообще разобраться с тем кодом который он сам не писал (насколько я вижу, код обработчика прерывания сгенерил CodeVision) и либо воспользоваться им, либо удалить...
Go to the top of the page
 
+Quote Post
Anub
сообщение Aug 17 2008, 08:17
Сообщение #9


Участник
*

Группа: Новичок
Сообщений: 47
Регистрация: 26-05-08
Пользователь №: 37 825



Все, разобрался. Пакет стал приниматься только после того как я ввел байт начала пакета.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 2nd August 2025 - 15:48
Рейтинг@Mail.ru


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