Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
16.10.2010, 00:15
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Нужно пересчитать переменные на "С" помогите
Добрый день всем.
Может подскажет кто как решить задачу на "С".
Есть переменная
volatile unsigned char zadanie_I
которая инкременируется при нажатии кнопки и есть переменная
volatile unsigned char izmerenie_i
которая служит для отображения на индикаторе.
Казалось бы все просто можно было бы присвоить на каждый цикл так
izmerenie_i=zadanie_I;
Но вот беда zadanie_I меняется от 0 до 255, а izmerenie_i должно менятся от 0 до 200.
|
|
|
|
16.10.2010, 00:18
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 886
Сказал спасибо: 119
Сказали Спасибо 1,110 раз(а) в 177 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
izmerenie_i = (zadanie_I * 200) ›› 8
А если подробней, то так:
izmerenie_i = (unsigned char)(((unsigned short)zadanie_I * 200) ›› 8 )
__________________
.
В мире всего два типа людей: те у кого был ZX Spectrum, и те у кого его не было.
Последний раз редактировалось alexgap; 16.10.2010 в 00:21.
|
|
|
Сказали "Спасибо" alexgap
|
|
|
17.10.2010, 09:14
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
alexgap,
Чегото торможу не могу въехать в смысл.
izmerenie_i
zadanie_I
Это как бы две разные но пропорциональные шкалы.
Если по простому то должно выглядеть так
255/200=1,25
izmerenie_i==zadanie_I/1,25;
или так
zadanie_I=izmerenie_i*1,25;
|
|
|
|
17.10.2010, 09:25
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.05.2005
Адрес: Саратов.ru
Сообщений: 1,548
Сказал спасибо: 384
Сказали Спасибо 737 раз(а) в 417 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
...удалил всякий бред...
Сообщение от alexgap
|
izmerenie_i = (zadanie_I * 200) ›› 8
|
все-таки должно быть деление на 255.
Последний раз редактировалось AJScorp; 17.10.2010 в 10:11.
Причина: что-то туплю с утра
|
|
|
Сказали "Спасибо" AJScorp
|
|
|
17.10.2010, 09:44
|
|
Гражданин KAZUS.RU
Регистрация: 17.08.2008
Сообщений: 770
Сказал спасибо: 52
Сказали Спасибо 450 раз(а) в 202 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
255/200=1,275
float izmerenie_2;
izmerenie_2=zadanie_I/1,275;
izmerenie_i=(unsigned char)izmerenie_2;
|
|
|
Сказали "Спасибо" XoDoK11
|
|
|
17.10.2010, 09:49
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
А если еще точнее
то для целочисленной математики, чтобы бороться с округлением в меньшую сторону, добавляют половину делителя, т.е.
формула будет
izmerenie_i =(unsigned char)( ((unsigned int)zadanie_I * 201) + 128 ) ›› 8
Последний раз редактировалось urry; 17.10.2010 в 09:59.
|
|
|
|
17.10.2010, 11:12
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.05.2005
Адрес: Саратов.ru
Сообщений: 1,548
Сказал спасибо: 384
Сказали Спасибо 737 раз(а) в 417 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
Кстати, нормальные компиляторы деление на константу заменяют умножением и сдвигами. Получается весьма быстро и красиво.
Вот что получилось для ARM7TDMI:
Код:
|
unsigned div255(unsigned val)
{
return val*200/255;
[0xe0801180] add r1,r0,r0,lsl #3
[0xe0811200] add r1,r1,r0,lsl #4
[0xe59f02c8] ldr r0,0x00001c54 ; = #0x80808081
[0xe1a01181] mov r1,r1,lsl #3
[0xe0812190] umull r2,r1,r0,r1
[0xe1a003a1] mov r0,r1,lsr #7
} |
|
|
|
|
17.10.2010, 12:13
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
XoDoK11,
Понравилась идея.
Цитата:
|
izmerenie_i=(unsigned char)izmerenie_2;
|
А зачем (unsigned char) если переменная izmerenie_i объявлена как unsigned char. По идее и так все что после запятой откинется.
|
|
|
|
17.10.2010, 12:39
|
|
Гражданин KAZUS.RU
Регистрация: 08.07.2006
Сообщений: 886
Сказал спасибо: 119
Сказали Спасибо 1,110 раз(а) в 177 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
Сообщение от 7Fantomas7
|
Чегото торможу не могу въехать в смысл.
izmerenie_i
zadanie_I
Это как бы две разные но пропорциональные шкалы.
Если по простому то должно выглядеть так
|
Смысл очень простой - борьба за скорость и размер. Наилучший результат достигается при целочисленном умножении и делении на числа, полученным возведением 2 в степень (2, 4, 8, 16, 32 ...). Аппаратная поддержка умножения имеется в ATmega. Деления - нет, есть только сдвиги (некоторые компиляторы умеют преобразовывать деления в сдвиги, но не все). Поэтому, любое подобное вычисление приводится к целочисленному вычислению со сдвигом.
Y(X) = (X * A) ›› N
N можно выбрать произвольно, главное чтобы это давало требуемую точность. Например вы хотите умножить значение переменной unsigned char на 3.1415926. Выберем N, например, 12. Это значит что делитель будет равен 2^12 = 4096. Следовательно А = 3.1415926 * 4096 = 12868. Получается:
Y(X) = (X * 12868 ) ›› 12
Подобного приема достаточно чтобы решить многие задачи.
Если память контроллера позволяет и скорость не особо критична то можно использовать арифметику с плавающей запятой (float, double).
__________________
.
В мире всего два типа людей: те у кого был ZX Spectrum, и те у кого его не было.
|
|
|
Сказали "Спасибо" alexgap
|
|
|
17.10.2010, 13:14
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Нужно пересчитать переменные на "С" помогите
Цитата:
|
некоторые компиляторы умеют преобразовывать деления в сдвиги, но не все
|
CodeVisionAVR умеет?
А то я к своему стыду не знаю.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:30.
|
|