Отлавливаю CR "0x0d" в USART

Обсуждаем контроллеры компании Atmel.
Ответить
Аватара пользователя
legalize
Открыл глаза
Сообщения: 69
Зарегистрирован: Чт авг 11, 2011 12:59:42
Откуда: Луганск

Отлавливаю CR "0x0d" в USART

Сообщение legalize »

Привет Коты!
Вспух мозг.
Пытаюсь ловить конец строки с компа. По таймеру все работает. Но хочу отлавливать это дело по символу CR.
Ловлю его таки

Код: Выделить всё

putchar('\r');
        putchar('\n');

проходит.
, но блин, не идут символы отправленные раньше.

Терминал PuTTY.
Заранее огромное спасибо.

Код: Выделить всё

interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
PORTD &=(~0x20);
status=UCSRA;
data=UDR;
if (data == 0x0d)
    {
    rx_end = 1;
    }
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index++]=data;
#if RX_BUFFER_SIZE == 256
   // special case for receiver buffer size=256
   if (++rx_counter == 0)
      {
#else
   if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
#endif
      rx_buffer_overflow=1;
      PORTD |=0x40;
      }
   }
PORTD |=0x20;

//TCCR0=0x05;//Запускаем таймер
//TCNT0 = 0x00; //Обнуляем таймер
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
rx_end = 1;
TCCR0=0x00;//Останавливаем таймер
}

while (1)
      {
      // Place your code here
     
      i = 0;
     
      if (rx_end)
        {
        rx_end = 0;
        delay_ms(400);
        #asm("cli")
        for (i = 0; rx_counter != 0; i++)
            {
            test[i] = getchar();
            //delay_ms(200);
            }
        #asm("sei")
     
        for (i = 0; test[i] != '\0'; i++)
            {
            putchar(test[i]);
            test[i] = 0x00;
            //delay_ms(200);
            }
        putchar('\r');
        putchar('\n');
       
        }
      //delay_ms(2000);
      }
}
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Отлавливаю CR "0x0d" в USART

Сообщение coredumped »

А как putchar() влияет на поиски конца строки в принимаемых данных? Вы что-то совсем запутались. Вам нужно анализировать принимаемые данные на наличие LF, например так:

Код: Выделить всё

        for (i = 0; rx_counter != 0; i++)
            {
            test[i] = getchar();
            if(test[i] == 0x0A) // получен конец строки, обрабатываем
            {
                //здесь код обработки
                break;
            }
           //delay_ms(200);
            }
 
Все будет только лучше, в крайнем случае - хуже.
Аватара пользователя
legalize
Открыл глаза
Сообщения: 69
Зарегистрирован: Чт авг 11, 2011 12:59:42
Откуда: Луганск

Re: Отлавливаю CR "0x0d" в USART

Сообщение legalize »

Неее тут немного не так. Я конец строки ищу в прерывании по приему символа.

Код: Выделить всё

if (data == 0x0d) 
    {
    rx_end = 1;
    }

Выставляю флаг rx_end и по нему в основном теле проги перегоняю из буфера в переменную test[]
Во как.
А потом уже эту переменную посылаю в putchar, обратно.
Опять же по прерываниям таймера все работает. Но правильнее по CR. Кстати Putty не посылает LF. Проверено.
den_sad
Родился
Сообщения: 3
Зарегистрирован: Ср дек 04, 2013 22:34:39

Re: Отлавливаю CR "0x0d" в USART

Сообщение den_sad »

Код: Выделить всё

//глобальные переменные
unsigned char rx_cnt=0; //счетчик принятых байт
unsigned char rx_buff[250]; //приемный буфер
unsigned char rx_end =0; //конец строки

//прием строки
interrupt [USART_RXC] void usart_rx_isr(void)
{
   unsigned char data;
   data=UDR;

   if (data == 0x0d)
    {
      rx_end = 1;
    }
   else
   {rx_buff[rx_cnt]=data;rx_cnt++;}  //заполняем приемный буфер
}


//главная процедура
#asm("sei")  //разрешаем прерывания
while (1)
  {
 
          if (rx_end==1)
     {
           rx_end=0;
     
        while (rx_cnt>=0)
           {
              putchar(rx_buff[rx_cnt]);  //печатаем нашу принятую строку обратно в терминал задом наперед без символа конца строки
              rx_cnt--;
            }
              rx_cnt=0;
      }

   
   }
     



предполагаю пишете под Codevision? не совсем понятно почему местами if{}else{} А местами #if{}#else{}
На начальном этапе можно забить на проверки ошибок приема

Старайтесь оформлять код чтобы его было удобно читать
codenamehawk
Вымогатель припоя
Сообщения: 528
Зарегистрирован: Вт фев 09, 2010 17:52:26

Re: Отлавливаю CR "0x0d" в USART

Сообщение codenamehawk »

Для начала упростите код.
И приведите его полностью.

Переменная rx_end должна быть объявлена с приставкой volatile, чтобы при оптимизации, компилятор ее не выкинул.
Аватара пользователя
blackx
Говорящий с текстолитом
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Re: Отлавливаю CR "0x0d" в USART

Сообщение blackx »

Е-мое, извините за оффтоп :facepalm:

От этого CVAVR и пухнут мозги. Ничего в вашем коде не понял.

den_sad, #if и прочее - это директивы препроцессора Си.

Командный интерпретатор на USART пишется очень просто, на основе обычного switch. Вот примерный псевдокод:

Код: Выделить всё


interrupt () {

char next = getchar() // получили
putchar(next); // возвращаем сразу обратно

switch(next) {
case 0x0d:
   buffer_put(0); // завершаем строку
   handle_cmd(buffer); // обработчик команд
   buffer_offset = 0; // "очищаем" буфер для новых команд
   break;

case .... // обрабатываем другие управляющие символы

default:
   put_buffer(next);
   break;
}

}

Изображение only pure true norwegian blackx Изображение
Ответить

Вернуться в «AVR»