addi II 1 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба Здравствуйте! Подскажите пожалуйста как лучше сделать, я сделал, но видимо не правильно и значения не совсем совпадают(например 50 % по факту 40, 99 по факту 90) Приходят значения периода заполнения ШИМ в процентах, от 0 до 99 Необходимо преобразовать в значение аппаратного регистра сравнения от 0 до 255 прошу подсказать Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 29 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба Не понятна проблема? Масштабировать как? Умножить на (255/99) и округлить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 1 31 августа, 2022 Опубликовано 31 августа, 2022 (изменено) · Жалоба проблема, - как реализовать правильно на си я уже реализовал, но видимо не правильно вот так: volatile unsigned char tv,tvl,tvh; volatile unsigned char PWM1_value; volatile char data1[16]; /* data1[4] - первый ASCII сивол десятичного значения = */ /* data1[5] - второй ASCII сивол десятичного значения = */ tvl = data1[4] - 0x30; tvh = data1[5] - 0x30; tvl= tvl *20; tvh = tvh*5; tv = tvl + tvh; PWM1_value = tv; PWM1_update(); Изменено 31 августа, 2022 пользователем addi II Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 1 час назад, addi II сказал: Приходят значения периода заполнения ШИМ в процентах, от 0 до 99 Необходимо преобразовать в значение аппаратного регистра сравнения от 0 до 255 Например так: uint x = ...; //input value 0...99 uint y = x * (((u32)1u << 24) / 100u) + (1u << 15) >> 16; //output value 0...255 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 1 31 августа, 2022 Опубликовано 31 августа, 2022 (изменено) · Жалоба не совсем понял что за коэффициент - " (((u32)1u << 24) / 100u) + (1u << 15) >> 16; " получается Изменено 31 августа, 2022 пользователем addi II Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 4 минуты назад, addi II сказал: не совсем понял что за коэффициент Что непонятного? Делим на 100 и умножаем на 256 (сдвинутое на 16 влево, для fixed point). А предложенное выше 255/99 - неверно. Правильно нужно умножать на 256/100. Что и делается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 1 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 25 minutes ago, jcxz said: Что непонятного? Делим на 100 и умножаем на 256 (сдвинутое на 16 влево, для fixed point). А предложенное выше 255/99 - неверно. Правильно нужно умножать на 256/100. Что и делается. 0 -> 0 99 -> 255 числа 100 там нету, не влезо, и очень возможно что 99 должно соответствовать полному заполнению шима 255, а не 99*(256/100) == 253. ((data[4]-'0')*6594+(data[5]-'0')*659 + 128) >> 8 ну или ((data[4]-'0')*6554+(data[5]-'0')*655 + 128) >> 8 если всё-таки 99 это именно 99% Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 1 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба да, 99 это 99 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 17 минут назад, _pv сказал: числа 100 там нету, не влезо, и очень возможно что 99 должно соответствовать полному заполнению шима 255, а не 99*(256/100) == 253. При преобразовании 256/100 сохраняется равномерность распределения выходных значений для всех значений 0...99. Т.е. - каждой входной дискрете соответствует шаг 256/100=2.56 в выходном диапазоне. А у вас для значений 0...98 выходной шаг будет: 255/99=~2.58, а для 99 - только одно единственное значение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 36 minutes ago, jcxz said: При преобразовании 256/100 сохраняется равномерность распределения выходных значений для всех значений 0...99. Т.е. - каждой входной дискрете соответствует шаг 256/100=2.56 в выходном диапазоне. А у вас для значений 0...98 выходной шаг будет: 255/99=~2.58, а для 99 - только одно единственное значение. шаг там в любом случае будет равномерный, особенно на выходе после округления до 8 бит, или 2 или 3, вопрос лишь в том чему должно соответствовать значение 99: 253 или 255 (полностью '1' на выходе шима). data d*255/99 d*256/100 0 0 0 0 0 1 2.576 3 2.56 3 2 5.152 5 5.12 5 3 7.727 8 7.68 8 4 10.303 10 10.24 10 5 12.879 13 12.8 13 6 15.455 15 15.36 15 7 18.03 18 17.92 18 8 20.606 21 20.48 20 9 23.182 23 23.04 23 10 25.758 26 25.6 26 11 28.333 28 28.16 28 ... 88 226.667 227 225.28 225 89 229.242 229 227.84 228 90 231.818 232 230.4 230 91 234.394 234 232.96 233 92 236.97 237 235.52 236 93 239.545 240 238.08 238 94 242.121 242 240.64 241 95 244.697 245 243.2 243 96 247.273 247 245.76 246 97 249.848 250 248.32 248 98 252.424 252 250.88 251 99 255 255 253.44 253 раз ТС говорит что 99 это 99% то да 256/100, ну или 253/99, что с 8ми битной точностью одно и то же. а вообще пусть lookup таблицу на 100 байт делает и заполняет её как хочет :) O - оптимизация Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 5 минут назад, _pv сказал: а вообще пусть lookup таблицу на 100 байт делает и заполняет её как хочет :) O - оптимизация Какой МК у ТСа - можно только гадать. Если ARM, то табличное преобразование может оказаться медленнее, чем умножение/сложение/сдвиг в моей формуле. Ведь чтение из флешь. Не говоря уже о размере. А значит скорее - деоптимизация получится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
addi II 1 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба AMSC-96, 16 бит Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 31 августа, 2022 Опубликовано 31 августа, 2022 · Жалоба 45 минут назад, addi II сказал: AMSC-96, 16 бит Печалька. Но если он имеет команду умножения 16x16=32, то для 16-разрядного МК может быть оптимальнее: u16 x = ...; //input value 0...99 u32 y = (u32)(x << 2) * (((u32)1u << 22) / 100u); u16 y = (u16)(y >> 16) + ((u16)y >> 15); //output value 0...255 Но зависит от системы команд. Я её не знаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Intel4004 1 5 сентября, 2022 Опубликовано 5 сентября, 2022 (изменено) · Жалоба unsigned char data_0_99 = (data1[4] - 0x30) * 10 + data1[5] - 0x30; unsigned char data_0_255 = (data_0_99*256+100/2)/100; // если 0..100 -> 0..256 unsigned char data_0_255 = (data_0_99*255+99/2)/99; // если 0..99 -> 0..255 В 16 бит вписывается. А со сдвигами лучше пока не заморачиваться, со временем само придет. Компилятор сам *256 превратит в <<8, если оно будет оптимальнее. Изменено 5 сентября, 2022 пользователем Intel4004 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться