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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> USART запрос/ответ, как принять массив через функцию getchar() ?
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

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

 


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


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