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

Участник

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

|
Цитата(sigmaN @ Dec 19 2011, 11:16)  Курс этот я видел/читал. Просто подумал может кто сталкивался с такой задачей. Может как то проще можно. Хотя куда уж  Остановлюсь на этом пока. Вот так сделал: Код 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
|
|
|
|
|
Dec 20 2011, 11:07
|

Участник

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

Участник

Группа: Участник
Сообщений: 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 Правильно? Или нет?
|
|
|
|
|
Dec 20 2011, 17:56
|

Гуру
     
Группа: Свой
Сообщений: 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;
|
|
|
|
|
Dec 20 2011, 18:48
|

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

|
Цитата(mr_smit @ Dec 20 2011, 21:35)  Код if ((temp >> 8) == 1) { // если отрицательное Правильно? Или нет? а не проще вот так? Код if (temp & 0x80) { // если отрицательное да и %02u - вроде как тут нужно %03 d, одно место останется под знак, да и число будет выводиться как обычное десятичное знаковое, а не беззнаковое
|
|
|
|
|
Dec 20 2011, 19:27
|

Участник

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

|
Цитата(toweroff @ Dec 20 2011, 21:48)  а не проще вот так? Код if (temp & 0x80) { // если отрицательное да и %02u - вроде как тут нужно %03 d, одно место останется под знак, да и число будет выводиться как обычное десятичное знаковое, а не беззнаковое Решил потестировать немного: Код 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
|
|
|
|
|
Dec 20 2011, 19:44
|

Гуру
     
Группа: Свой
Сообщений: 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, должно быть нормально. Сама она должна разруливать отрицательные числа
|
|
|
|
|
Dec 20 2011, 19:51
|

Участник

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

Участник

Группа: Участник
Сообщений: 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
|
|
|
|
|
Dec 21 2011, 21:09
|
Гуру
     
Группа: Свой
Сообщений: 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]
|
|
|
|
|
Dec 21 2011, 22:03
|

Участник

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

|
Просто вроде как sizeof должна возвращать длину массива. Но тут да, точно, указатель, а не массив (я начинаю понимать  ) Может тогда убрать указатель из аргумента функции? Просто хочу писАть: 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]; } } Но чет ругается компилятор
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|