AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
27.01.2021, 19:10
|
|
Прописка
Регистрация: 07.01.2010
Сообщений: 104
Сказал спасибо: 60
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
CodevisionAVR си
Здравствуйте форумчане.
Прошу помочь в написании маленького кода.. что-то у самого не получается...
Есть переменные:
char a=0x01 b=0x02 c=0x03 d=0x04;
int X=0;
Как мне сделать так, чтобы X=0x1234
Что-то не соображу никак ;(
Спасибо!
|
|
|
|
27.01.2021, 19:22
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: CodevisionAVR си
X = ((a & 0x0F) ‹‹ 12) | ((b & 0x0F) ‹‹ 8) | ((c & 0x0F) ‹‹ 4) | (d &0x0F);
выражение (a & 0x0F) нужно для того, чтобы убрать влияние верхнего полубайта в байте, в случае если значение переменной превысит 0x0F. Если значение переменных гарантированно не превышает 0x0F, то операцию & 0x0F можно убрать.
Последний раз редактировалось NewWriter; 27.01.2021 в 19:33.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
27.01.2021, 20:59
|
|
Прописка
Регистрация: 07.01.2010
Сообщений: 104
Сказал спасибо: 60
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Re: CodevisionAVR си
Спасибо большое!
Вы мне правильно написали.
Только если честно - я не верно поставил задачу которую решаю и не могу решить.
Есть измеренное значение АЦП в переменной:
int ADCW;
мне хочется знать сколько там в десятичной системе, для этого у меня вот такой код:
Код:
|
ADC_buf_temp = ADCW; //
d=ADC_buf_temp%10; // единицы
ADC_buf_temp=(ADC_buf_temp-d)/10;
c=ADC_buf_temp%10; // десятки
ADC_buf_temp=(ADC_buf_temp-c)/10;
b=ADC_buf_temp%10; // сотни
ADC_buf_temp=(ADC_buf_temp-b)/10;
a=ADC_buf_temp%10; // тысячные
ADC_buf_temp=(ADC_buf_temp-a)/10;
a = a | 0x30; //
b = b | 0x30; //
c = c | 0x30; //
d = d | 0x30; // |
На выходе у меня получается a=0x30 b=0x37 c=0x34 d=0x36
Я почему-то думаю, что преобразовал значение АЦП в десятичный вид в число 0746.
Правильно я считаю или это не так?
Моя задача заключается в том, как мне "запихнуть" в переменную ADCW1, чтобы после такого же преобразования получилось ,например, a=0x31 b=0x35 c=0x37 d=0x31
Нужна "обратная" функция моему коду. Но как я могу написать обратную функцию, если с пониманием этой функции проблемы
|
|
|
|
27.01.2021, 21:44
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: CodevisionAVR си
А, так вы хотите в формате BСD (binary-coded decimal, двоично-десятичное значение), да еще в ANSI-коде?
Значения a=0x30 b=0x37 c=0x34 d=0x36 - это четырехразрядный ANSI-код. Цифры в ANSI начинаются с 0x30. Если из указанных вычесть 0x30 (отбросить старший полубайт, получатся цифры 0, 7, 4, 6. То есть, число 0746.
ANSI-представление нужно только для прямого вывода на дисплей-двустрочник или в терминал.
Обратное преобразование производится ровно наоборот. Вначале убираем старший полубайт в каждом числе, преобразовывая из ANSI-кода в числовой.
a = a & 0x0F;
b = b & 0x0F;
c = c & 0x0F;
d = d & 0x0F;
Затем складываем их поразрядно, как в начальных классах школы: число единиц плюс число десятков, умноженные на 10, плюс число сотен, умноженные на 100 и плюс число тысяч, умноженные на 1000.
X = a * 1000 + b * 100 + c * 10 + d;
Можно это записать в одну строчку:
X = (a & 0x0F) * 1000 + (b & 0x0F) * 100 + (c & 0x0F) * 10 + (d & 0x0F);
|
|
|
Эти 3 пользователя(ей) сказали Спасибо NewWriter за это сообщение:
|
|
|
28.01.2021, 19:46
|
|
Прописка
Регистрация: 07.01.2010
Сообщений: 104
Сказал спасибо: 60
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Re: CodevisionAVR си
Не получается у меня
Помогите пожалуйста.
Есть переменные char a = 0x30; b = 0x37; c = 0x35; d = 0x39;
Мне нужно выделить 0 7 5 9 - то есть число десятичное 0759
Собираю их в вид:
int ADC;
ADC = (a & 0x0F) * 1000 + (b & 0x0F) * 100 + (c & 0x0F) * 10 + (d & 0x0F);
тут по логике у меня должно получиться 02F7
далее если я число 02F7 обратно хочу перевести в переменные a b c d
то делаю так:
Код:
|
a = 0; b = 0; c = 0; d = 0;
int ADC_temp;
ADC_temp = ADC;
d=ADC_temp%10;
ADC_temp=(ADC_temp-d)/10;
c=ADC_temp%10;
ADC_temp=(ADC_temp-c)/10;
b=ADC_temp%10;
ADC_temp=(ADC_temp-b)/10;
a=ADC_temp%10;
ADC_temp=(ADC_temp-a)/10;
a = a | 0x30;
b = b | 0x30;
c = c | 0x30;
d = d | 0x30; |
Но почему-то результат получается a=0x30 b=0x32 c=0x34 d=37
А нужно a = 0x30 b = 0x37 c = 0x35 d = 0x39
Не пойму
Последний раз редактировалось Виктор_М; 28.01.2021 в 19:48.
|
|
|
|
28.01.2021, 19:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: CodevisionAVR си
Если ADC_Temp=0x02F7 (т.е. 759), то d=ADC_Temp % 10 ну никак не может получиться 7, получится 9.
Видимо, ошибка в начальном числе.
|
|
|
Сказали "Спасибо" pambaru
|
|
|
28.01.2021, 20:09
|
|
Прописка
Регистрация: 07.01.2010
Сообщений: 104
Сказал спасибо: 60
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Re: CodevisionAVR си
Сообщение от pambaru
|
Если ADC_Temp=0x02F7 (т.е. 759), то d=ADC_Temp % 10 ну никак не может получиться 7, получится 9.
Видимо, ошибка в начальном числе.
|
У меня есть микроконтроллер atmega c АЦП.
Я делаю замер и получаю результат int ADCW.
Хочу понимать сколько это в десятичной системе счисления для человеческого понимания.
Создаю char a b c d;
Как мне сделать чтобы:
а - содержало тысячи;
b - сотни;
с - десятки;
d - единицы.
___
Если АЦП намеряло ADCW= 0x03FF или в десятичных 1023
как сделать чтобы а=1 b=0 c=2 d=3
?
|
|
|
|
28.01.2021, 20:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.03.2007
Сообщений: 1,365
Сказал спасибо: 85
Сказали Спасибо 625 раз(а) в 377 сообщении(ях)
|
Re: CodevisionAVR си
Сообщение от Виктор_М
|
Как мне сделать чтобы:
а - содержало тысячи;
b - сотни;
с - десятки;
d - единицы.
|
Вот, так, как у вас и было выше:
Сообщение от Виктор_М
|
ADC_temp = ADC;
d=ADC_temp%10;
ADC_temp=(ADC_temp-d)/10;
c=ADC_temp%10;
ADC_temp=(ADC_temp-c)/10;
b=ADC_temp%10;
ADC_temp=(ADC_temp-b)/10;
a=ADC_temp%10;
ADC_temp=(ADC_temp-a)/10;
|
Только вычитание перед делением на 10 лишнее, оно не влияет на результат.
Цитата:
|
d=ADC_temp%10;
ADC_temp=(ADC_temp-d)/10;
|
равносильно:
Цитата:
|
d=ADC_temp%10;
ADC_temp=ADC_temp/10;
|
|
|
|
|
28.01.2021, 20:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.12.2007
Адрес: Екатеринбург
Сообщений: 2,731
Сказал спасибо: 2,443
Сказали Спасибо 893 раз(а) в 580 сообщении(ях)
|
Re: CodevisionAVR си
a=ADC_temp/1000;
b=ADC_temp%1000/100
c=ADC_temp%100%100/10
d=ADC_temp%1000%100%10
|
|
|
Сказали "Спасибо" baiderin
|
|
|
28.01.2021, 20:53
|
|
Прописка
Регистрация: 07.01.2010
Сообщений: 104
Сказал спасибо: 60
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
|
Re: CodevisionAVR си
Полтергейст какой-то. Пишу
Код:
|
a = 0x31; b = 0x30; c = 0x32; d = 0x33;
ADC = (a & 0x0F) * 1000 + (b & 0x0F) * 100 + (c & 0x0F) * 10 + (d & 0x0F); |
EEPROM int ADC вижу FF03 видимо 03FF = 1023
Другой пример:
Код:
|
a = 0x30; b = 0x37; c = 0x36; d = 0x35;
ADC = (a & 0x0F) * 1000 + (b & 0x0F) * 100 + (c & 0x0F) * 10 + (d & 0x0F); |
EEPROM int ADC вижу FD00 видимо 00FD = 253
а должно быть 02FD
Как так?
Ввожу:
Код:
|
a = 0x30; b = 0x38; c = 0x33; d = 0x34;
ADC = (a & 0x0F) * 1000 + (b & 0x0F) * 100 + (c & 0x0F) * 10 + (d & 0x0F); |
EEPROM int ADC вижу 4200 видимо 0042 = 66
а должно быть 0342
Последний раз редактировалось Виктор_М; 28.01.2021 в 21:00.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:14.
|
|