|
USART запрос/ответ, как принять массив через функцию getchar() ? |
|
|
|
Dec 17 2011, 19:08
|

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

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

Участник

Группа: Участник
Сообщений: 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)  Да, заведите второй буфер, для пакета Да я вот думаю может нафиг вообще этот кольцевой буффер  Чего то он меня с толку сбивает. Создать буффер в который будут приниматься байты. Когда нужно - читать его. А при каждом следующем запросе начинать прием байтов в начало буффера, перезаписывая его.
Сообщение отредактировал mr_smit - Dec 17 2011, 21:27
|
|
|
|
|
Dec 18 2011, 06:24
|

Участник

Группа: Участник
Сообщений: 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(); }; } Так как то криво
Сообщение отредактировал mr_smit - Dec 18 2011, 07:05
|
|
|
|
|
Dec 18 2011, 09:07
|

Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Dec 18 2011, 12:14
|

Участник

Группа: Участник
Сообщений: 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); Почему то выдает один лишний байт  Откуда 04 ???
 Уменьшено до 75%
682 x 415 (73.3 килобайт)
|
|
|
|
|
|
Dec 18 2011, 14:06
|

фанат дивана
     
Группа: Свой
Сообщений: 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)  Почему то выдает один лишний байт  Откуда 04 ??? Это вам ещё повезло, что всего один лишний байт  У вас в SendCommand идёт проверка на ноль (признак конца команды). А нуля-то и нет! Добавьте: unsigned char startCommunication[] = {0x81,0x10,0xf1,0x81,0x03, 0};
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 18 2011, 18:20
|

Участник

Группа: Участник
Сообщений: 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 в комманды? Просто я с этими указателями чего то путаюсь  А вот этот кусок вообще не понимаю: Код while (*command) {} каким макаром тут проверка на ноль идет  Это же указатель на первый элемент массива. Причем тут ноль? P.S. Да, не сам писАл. Нашел пример.
|
|
|
|
|
Dec 18 2011, 20:39
|

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

|
Цитата там наверно дальше где-то есть Код command++; аа вот оно Код UDR = *command++; т.е. UDR присваивается значение первого элемента массива, а сам указатель после операции указывает уже на второй, потом на следующей итерации снова while проверяет его и если не ноль, то снова идёт присвоение UDR а command указывает на следующий элемент.... и так пока не встретится ноль в общем )
--------------------
The truth is out there...
|
|
|
|
|
Dec 18 2011, 21:06
|

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

|
Цитата(mr_smit @ Dec 19 2011, 00:20)  А вот этот кусок вообще не понимаю: конструкция Код while (выражение) {команды} выполняет команды пока выражение не ноль. command - указатель, да. А *command - то, на что указывает указатель. Про продвижение указателя sigmaN уже объяснил. ЗЫ. Читать букварь по Си, срочно! Без понимания основ трудно написать что-то приличное.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 18 2011, 21:26
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(mr_smit @ Dec 18 2011, 20:20)  А может можно как то переделать функцию SendCommand так чтобы не дописывать 0 в комманды? Просто я с этими указателями чего то путаюсь  Переделать можно, например так: Код 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) {} каким макаром тут проверка на ноль идет P.S. Да, не сам писАл. Нашел пример. *command = чтение байта по указателю command и если там 0, то получается while (0) - цикл заканчивается. Цитата(mr_smit @ Dec 18 2011, 20:20)  Это же указатель на первый элемент массива. Причем тут ноль? На первый байт он указывал на входе в функцию. Код: Код UDR = *command++; означает, что в UDR пишется байт по указателю, затем указатель инкрементируется (++ - постинкремент).
|
|
|
|
|
Dec 19 2011, 08:16
|

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

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