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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> USART запрос/ответ, как принять массив через функцию getchar() ?
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 ???
Прикрепленное изображение
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
mr_smit
сообщение Dec 19 2011, 08:48
Сообщение #16


Участник
*

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



Цитата(sigmaN @ Dec 19 2011, 11:16) *
Вот тут покрутите учебный курс http://easyelectronics.ru/category/avr-uchebnyj-kurs

Курс этот я видел/читал. Просто подумал может кто сталкивался с такой задачей. Может как то проще можно. Хотя куда уж sm.gif Остановлюсь на этом пока.

Вот так сделал:
Код
volatile bit OldState, StartSend;
...
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)     // каждые 250 мс
{
  OldState = StartSend;    // запоминаем состояние
  StartSend^=1;            // инвертируем бит
}
...
if (StartSend != OldState) {}


Сообщение отредактировал mr_smit - Dec 19 2011, 12:03
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 20 2011, 11:07
Сообщение #17


Участник
*

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



У меня тут вопрос появился. Нигде не смог найти толкового описания как переводить из одной системы исчисления в другую. В общем что мне надо:

В "моём" ответе 11-й байт это температура. Формула для пересчета в реальную температуру: N=E-40 [°C]. E - передаваемое значение, N - физическая величина. В примере это значение равно 47. Берем windows калькулятор. Переводим 47 hex в dec. Получаем 71. Дальше 71-40=31°C. Собственно говоря как это сделать? И как быть если температура будет отрицательной?

Код
unsigned char temp;
char convert[16];
...
temp = buffer[10];
temp =  (преобразовать в dec) - 40;     // ????
sprintf(convert,"%u",temp);
// вывод на дисплей char

Т.е. 0х47 hex -> 71 dec ??? И как быть с отрицательной температурой?
И есть ли что то быстрее sprintf ?
Go to the top of the page
 
+Quote Post
toweroff
сообщение Dec 20 2011, 12:17
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



как обычно, наверное... знаковый байт, старший бит - знак... если 1 - число отрицательное и содержимое 7 младших битов есть дополнение до 0
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 20 2011, 17:35
Сообщение #19


Участник
*

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



Ладно, мне надо вычесть 40. Т.е. 40 dec в hex будет 28. Тогда:
Код
unsigned char temp;
char convert[16];
...
temp = buffer[10];
temp = temp - 28;
if ((temp >> 8) == 1) {       // если отрицательное
  sprintf(convert,"-%02u",temp);
}
else {
  sprintf(convert,"%02u",temp);
}
// вывод на дисплей char

Правильно? Или нет?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 20 2011, 17:56
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(mr_smit @ Dec 20 2011, 21:35) *
Ладно, мне надо вычесть 40. Т.е. 40 dec в hex будет 28. ... Правильно? Или нет?

Коль нужно вычесть сорок, то и вычитайте
Код
temp = temp - 40;

Если нужно использовать шестнадцатиричную константу:
Код
temp = temp - 0x28;
Go to the top of the page
 
+Quote Post
toweroff
сообщение Dec 20 2011, 18:48
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(mr_smit @ Dec 20 2011, 21:35) *
Код
if ((temp >> 8) == 1) {       // если отрицательное

Правильно? Или нет?

а не проще вот так?
Код
if (temp & 0x80) {       // если отрицательное


да и %02u - вроде как тут нужно %03d, одно место останется под знак, да и число будет выводиться как обычное десятичное знаковое, а не беззнаковое
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 20 2011, 19:27
Сообщение #22


Участник
*

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



Цитата(toweroff @ Dec 20 2011, 21:48) *
а не проще вот так?
Код
if (temp & 0x80) {       // если отрицательное

да и %02u - вроде как тут нужно %03d, одно место останется под знак, да и число будет выводиться как обычное десятичное знаковое, а не беззнаковое


Решил потестировать немного:
Код
unsigned char temp = 0x19;
char convert[16];
...
temp = temp - 0x28;
if (temp & 0x80) {
  sprintf(convert,"-%03d",temp);
  put_string(115,4,convert,0xF800,1);
}
else {
  sprintf(convert,"%02d",temp);
  put_string(115,4,convert,0xF800,1);
}


Если написать unsigned char temp = 0x47, то выводится число 31, всё правильно (47hex - 28hex = 1F hex ->31dec)
Но если написать unsigned char temp = 0x19, то выводится число -241, а не -15 (19hex - 25hex = FFFFFFFFFFFFFFF1 hex -> -15dec)
Всё равно не понимаю как минус вывести.
P.S. F1 hex = 241 dec

Сообщение отредактировал mr_smit - Dec 20 2011, 19:45
Go to the top of the page
 
+Quote Post
toweroff
сообщение Dec 20 2011, 19:44
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(mr_smit @ Dec 20 2011, 23:27) *
Решил потестировать немного:
Код
unsigned char temp = 0x19;
char convert[16];
...
temp = temp - 0x28;
if (temp & 0x80) {
  sprintf(convert,"-%03d",temp);
  put_string(115,4,convert,0xF800,1);
}
else {
  sprintf(convert,"%02d",temp);
  put_string(115,4,convert,0xF800,1);
}


Если написать unsigned char temp = 0x47, то выводится число 31, всё правильно (47hex -> 71dec -> 71-40)
Но если написать unsigned char temp = 0x19, то выводится число -241, а не -15 (19hex -> 25dec -> 25-40)


ну тогда вот так:
Код
unsigned char temp = 0x19;
char convert[4]; // куда больше-то?
...
temp = temp - 40;
sprintf(convert, "%s%02d", ((temp & 0x80)? "-": ""), ((temp & 0x80)? (unsigned char)(0-temp): temp) );
put_string(115,4,convert,0xF800,1);


ну это на скорую руку. Скорее всего, что-то не так с отображением sprintf, должно быть нормально. Сама она должна разруливать отрицательные числа
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 20 2011, 19:51
Сообщение #24


Участник
*

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



Цитата(toweroff @ Dec 20 2011, 15:17) *
...и содержимое 7 младших битов есть дополнение до 0

Дошло. В случае отрицательной температуры надо добавить: temp = 256 - temp;

Код
unsigned char temp = 0x19;
char convert[16];
...
temp = temp - 0x28;
if (temp & 0x80) {
  temp = 256 - temp;
  sprintf(convert,"-%d",temp);
  put_string(115,4,convert,color_chislo,1);
}
else {
  sprintf(convert,"%d",temp);
  put_string(115,4,convert,color_chislo,1);
}

Выводит -15. Ура! Спасибо!

Сообщение отредактировал mr_smit - Dec 20 2011, 20:02
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 21 2011, 11:18
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Жуть, столько телодвижений вместо того, что бы просто написать signed char temp (как у вас по сути и должно быть)
Код
signed char temp = 0x19;
char convert[16];
...
temp = temp - 0x28;
sprintf(convert,"%d",temp);
Go to the top of the page
 
+Quote Post
toweroff
сообщение Dec 21 2011, 11:57
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(XVR @ Dec 21 2011, 15:18) *
signed char temp

Цитата(toweroff)
ну это на скорую руку. Скорее всего, что-то не так с отображением sprintf, должно быть нормально. Сама она должна разруливать отрицательные числа

ну точно я вчера уработался - сидел еще форматирование printf лопатил biggrin.gif
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 21 2011, 18:10
Сообщение #27


Участник
*

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



Цитата(XVR @ Dec 21 2011, 14:18) *
Жуть, столько телодвижений вместо того, что бы просто написать signed char temp (как у вас по сути и должно быть)
Код
signed char temp = 0x19;
char convert[16];
...
temp = temp - 0x28;
sprintf(convert,"%d",temp);

Спасибо за код.

Скажите ещё почему sizeof не работает. Выводит только первые 2 байта:
Код
void SendCommand (unsigned char *command) {
  unsigned int  length = 0;
  length = sizeof(command);
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


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


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(mr_smit @ Dec 21 2011, 22:10) *
А в чем разница между signed char и char? В учебнике написано что это одно и то же. Но signed char выводит -15, а char выводит 241

signed потому и обрабатывается как число со знаком, со всеми вытекающими (старший бит, дополненте и т.д.)
unsigned - число без знака

посмотрите документацию компилятора на Ваш проц, там должны быть указаны размерности char, signed char и unsigned char с диапазонами значений
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 21 2011, 21:09
Сообщение #29


Гуру
******

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



Цитата(mr_smit @ Dec 21 2011, 20:10) *
Спасибо за код.

Скажите ещё почему sizeof не работает. Выводит только первые 2 байта:
Код
void SendCommand (unsigned char *command) {
  unsigned int  length = 0;
  length = sizeof(command);
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}


Вы не правы: это именно sizeof() и работает, и работает он так как надо, то есть так как Вы указали:

length = sizeof(command); = размер command, который есть тип unsigned char * - на многих 8-битных МК (например АВР), для указателя на байт хватает 2 байта. Вот у Вас два байта и шлются в порт, на 32 битных МК слалось бы, наверное 4 байта.

Совет: Укажите длину посылки как параметр функции.

Код
[code]void SendCommand (unsigned char *command, unsigned int  length ) {
// (unsigned char *command, unsigned int  length = 0), если нужно умолчание, хотя к чему оно здесь?
  while (length--) {
    while(!(UCSRA & (1<<UDRE)));  // ждем окончания передачи байта
    UDR = *command++;
  }
}

[/code]
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 21 2011, 22:03
Сообщение #30


Участник
*

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



Просто вроде как sizeof должна возвращать длину массива. Но тут да, точно, указатель, а не массив (я начинаю понимать sm.gif ) Может тогда убрать указатель из аргумента функции?

Просто хочу писАть: SendCommand(startCommunication); без указания длинны

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

Но чет ругается компилятор
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 21 2011, 23:11
Сообщение #31


Гуру
******

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



Цитата(mr_smit @ Dec 22 2011, 00:03) *
Просто вроде как sizeof должна возвращать длину массива. Но тут да, точно, указатель, а не массив (я начинаю понимать sm.gif ) Может тогда убрать указатель из аргумента функции?

Просто хочу писАть: SendCommand(startCommunication); без указания длинны

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

Но чет ругается компилятор


Что ж ему не ругаться: command - это байт , а вы к нему обращаетесь как элементу массива (хамите).

Понятно Вам что нужно:
функция аналогичная например такому(C#. правда а не Си)
Код
void F1(byte []byte_array) {
    for (int i=0; i<byte_array.Length; i++) {
           byte_array[i]=i;// нужные действия
    }
}


Но в C# каждый массив всегда содержит свою длину, а в Си - нет.
Может и есть что-то такое в Си, а может и нет(утверждать не буду, не помню).
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 22 2011, 10:24
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(_Артём_ @ Dec 22 2011, 03:11) *
Но в C# каждый массив всегда содержит свою длину, а в Си - нет.
Может и есть что-то такое в Си, а может и нет(утверждать не буду, не помню).
Нету такого в С (утверждать буду) biggrin.gif
Go to the top of the page
 
+Quote Post
mr_smit
сообщение Dec 22 2011, 19:31
Сообщение #33


Участник
*

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



Всем спасибо! rolleyes.gif
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 - 23:27
Рейтинг@Mail.ru


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