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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
mr_smit
сообщение Dec 17 2011, 17:20
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



Здравствуйте. Необходимо обмениваться данными с устройством. Каждые 250 мс необходимо отправить:
Запрос: 82 10 F1 21 01 A5
и получить:
Ответ: 80 F1 10 26 61 01 3B 90 41 04 00 00 00 00 47 80 00 00 00 52 52 80 18 00 8E 00 5C 00 00 00 00 00 00 00 00 00 FF FF DD A4 47 02 CE

Данные в ответе выделены зеленым (меняются). Длинна ответа не меняется. Как принять этот массив???

В CVAVR использую мастер начальной настройки. Там создается кольцевой буффер. Т.е. первый байт который попал в буффер первым из него и выйдет. Запрос этого байта через функцию getchar(). Никак не соображу как реализовать. Т.е. получается мне надо вызвать эту функцию "длинна массива" раз. Или создать ещё один промежуточный буффер и в него считывать при каждом вызове getchar() ? Или может какой алгоритм существует. Короче запутался.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Dec 17 2011, 19:08
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да, заведите второй буфер, для пакета. Заведите счётчик принятых байтов. При отправке запроса обнуляйте его. И потом начинайте увеличивать по приёму каждого байта. Пока счётчик меньше пяти - проверяем заголовок. Досчитали до пяти - значит пошли данные, складываем их в буфер. Досчитали до скольки-то там - данные закончились, проверяем хвостик пакета, и, если всё правильно, то обрабатываем принятые данные. После этого можно снова отправлять запрос.
Добавьте ещё тайм-аут на приём символа, для надёжности.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Dec 17 2011, 20:33
Сообщение #3


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



80 F1 10 26 , а вот 0x26 это счётчик передаваемых байт - похоже


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 17 2011, 21:24
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



Цитата(ILYAUL @ Dec 17 2011, 23:33) *
80 F1 10 26 , а вот 0x26 это счётчик передаваемых байт - похоже

CE - контрольная сумма (2 младших разряда)

Цитата(AHTOXA @ Dec 17 2011, 22:08) *
Да, заведите второй буфер, для пакета

Да я вот думаю может нафиг вообще этот кольцевой буффер blink.gif Чего то он меня с толку сбивает. Создать буффер в который будут приниматься байты. Когда нужно - читать его. А при каждом следующем запросе начинать прием байтов в начало буффера, перезаписывая его.

Сообщение отредактировал mr_smit - Dec 17 2011, 21:27
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Dec 18 2011, 05:13
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Кольцевой буфер оставьте, он вам никак не мешает. Зато поможет не пропустить символ на приёме, если вдруг затянете с обработкой предыдущего символа. Сделайте его небольшим, байт на 8, авось памяти хватитsm.gif
А остальное - всё как вы написали:
Цитата(mr_smit @ Dec 18 2011, 03:24) *
Создать буффер в который будут приниматься байты. Когда нужно - читать его. А при каждом следующем запросе начинать прием байтов в начало буффера, перезаписывая его.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 18 2011, 06:24
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



Просто я не понимаю каким образом мне вызывать getchar()

Код
if (rx_counter>42) {     // всего 43 байта в ответе
      char i;
      char buf[50];
      for (i=0;i<42;i++) {
        buf[i] = getchar();
      };
}

Так как то криво sad.gif

Сообщение отредактировал mr_smit - Dec 18 2011, 07:05
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 18 2011, 09:07
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



В общем убрал кольцевой буффер и сделал вот так:
Код
#define BUFFER_SIZE 200
unsigned char buffer[BUFFER_SIZE];    // приемный буффер
unsigned char startCommunication[] = {0x81,0x10,0xf1,0x81,0x03};
volatile unsigned char counter;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   buffer[counter]=data;
   counter++;
   if (counter >= BUFFER_SIZE) {  
     counter = 0;
     }
   }
}

Если вдруг буффер переполнится то пишем данные в его начало. Просто не сойдется контрольная сумма. Получим данные при следующем запросе.

Теперь отправка команды.
Код
void SendCommand (unsigned char *command) {
  counter = 0;
  while (*command) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}

Использование:
Код
SendCommand(startCommunication);


Работает (смотрю COM порт сниффером). Но если написать:
Код
flash unsigned char startCommunication[] = {0x81,0x10,0xf1,0x81,0x03};

То на строчке:
Код
SendCommand(startCommunication);

Выдает ошибку:
Error: function argument #1 of type 'flash unsigned char [5]' is incompatible with required parameter of type 'unsigned char *'
Я так понимаю нельзя со строкой из флеша напрямую работать. Так то конечно всё равно, но строчки статичные, пусть лучше во флеше лежат. Как то можно к ним обратиться в моём случае?

Сообщение отредактировал mr_smit - Dec 18 2011, 09:14
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 18 2011, 12:14
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



И еще:
Код
unsigned char startCommunication[] = {0x81,0x10,0xf1,0x81,0x03};
...
void SendCommand (unsigned char *command) {
  counter = 0;
  while (*command) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}
...
SendCommand(startCommunication);

Почему то выдает один лишний байт blink.gif Откуда 04 ???
 РЈРјРµРЅСЊС€РµРЅРѕ РґРѕ 75%
Прикрепленное изображение
682 x 415 (73.3 килобайт)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Dec 18 2011, 14:06
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(mr_smit @ Dec 18 2011, 15:07) *
Выдает ошибку:
Error: function argument #1 of type 'flash unsigned char [5]' is incompatible with required parameter of type 'unsigned char *'
Я так понимаю нельзя со строкой из флеша напрямую работать. Так то конечно всё равно, но строчки статичные, пусть лучше во флеше лежат. Как то можно к ним обратиться в моём случае?

Я не знаю, как это сделано в CVAVR, но видимо надо объявить SendCommand как
Код
void SendCommand (flash unsigned char *command)

Ну или что-то типа этого.

Цитата(mr_smit @ Dec 18 2011, 18:14) *
Почему то выдает один лишний байт blink.gif Откуда 04 ???

Это вам ещё повезло, что всего один лишний байтsm.gif
У вас в SendCommand идёт проверка на ноль (признак конца команды). А нуля-то и нет! Добавьте:
unsigned char startCommunication[] = {0x81,0x10,0xf1,0x81,0x03,0};


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 18 2011, 18:20
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



AHTOXA, спасибо!!!!!
Код
void SendCommand (flash unsigned char *command)

Работает!!!
Код
flash unsigned char startCommunication[] = {0x81,0x10,0xf1,0x81,0x03,0};

Работает!!!!

А может можно как то переделать функцию SendCommand так чтобы не дописывать 0 в комманды? Просто я с этими указателями чего то путаюсь sad.gif

А вот этот кусок вообще не понимаю:
Код
while (*command) {}

каким макаром тут проверка на ноль идет blink.gif Это же указатель на первый элемент массива. Причем тут ноль?

P.S. Да, не сам писАл. Нашел пример.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 18 2011, 20:39
Сообщение #11


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Код
while (*command) {}
там наверно дальше где-то есть
Код
command++;


аа вот оно
Код
UDR = *command++;
т.е. UDR присваивается значение первого элемента массива, а сам указатель после операции указывает уже на второй, потом на следующей итерации снова while проверяет его и если не ноль, то снова идёт присвоение UDR а command указывает на следующий элемент.... и так пока не встретится ноль в общем )


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Dec 18 2011, 21:06
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(mr_smit @ Dec 19 2011, 00:20) *
А вот этот кусок вообще не понимаю:

конструкция
Код
while (выражение) {команды}
выполняет команды пока выражение не ноль.
command - указатель, да. А *command - то, на что указывает указатель. Про продвижение указателя sigmaN уже объяснил.
ЗЫ. Читать букварь по Си, срочно! Без понимания основ трудно написать что-то приличное.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 18 2011, 21:26
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(mr_smit @ Dec 18 2011, 20:20) *
А может можно как то переделать функцию SendCommand так чтобы не дописывать 0 в комманды? Просто я с этими указателями чего то путаюсь sad.gif


Переделать можно, например так:

Код
void SendCommand (unsigned char *command, unsigned char length) {
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


B вызывать соотв.:
Код
SendCommand(startCommunication, 5);



Цитата(mr_smit @ Dec 18 2011, 20:20) *
А вот этот кусок вообще не понимаю:
Код
while (*command) {}

каким макаром тут проверка на ноль идет blink.gif

P.S. Да, не сам писАл. Нашел пример.


*command = чтение байта по указателю command и если там 0, то получается while (0) - цикл заканчивается.

Цитата(mr_smit @ Dec 18 2011, 20:20) *
Это же указатель на первый элемент массива. Причем тут ноль?


На первый байт он указывал на входе в функцию.
Код:
Код
UDR = *command++;

означает, что в UDR пишется байт по указателю, затем указатель инкрементируется (++ - постинкремент).
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 19 2011, 07:48
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 62
Регистрация: 22-07-09
Пользователь №: 51 457



Ну примерно понял. Спасибо. И ещё. Как лучше организовать запрос каждые 250 мс? Я завел 16-ти битный таймер на ~250 мс (прерывание по совпадению). Ну не могу же я функцию SendCommand в прерывание ставить. Она ведь долго выполняется. Завести переменную битовую как флаг разрешения, инвертировать её по прерыванию и опрашивать в основном цикле? Изменилась с 0 в 1 - SendCommand, из 1 в 0 - SendCommand. Или как то красивее это можно сделать?

Сообщение отредактировал mr_smit - Dec 19 2011, 07:57
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 19 2011, 08:16
Сообщение #15


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Завести переменную битовую как флаг разрешения, инвертировать её по прерыванию и опрашивать в основном цикле?
Вполне себе нормальный подход. Вопрос только в красоте его исполнения и универсальности.
Вот тут покрутите учебный курс http://easyelectronics.ru/category/avr-uchebnyj-kurs как раз описывается служба таймеров и типа планировщик задач. Всё на Си.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

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

 


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


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