|
|
  |
Скорость выполнения кода на atmega640 |
|
|
|
Jul 24 2009, 17:22
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Leonmezon @ Jul 24 2009, 21:02)  Просчитал - не получить, я ограничен возможностями компилятора ( максим на тип signed long - 4 байта), а для работы в чисто целочисленном (без использования плавующей точки - (плавующая то же 4 байтная)) - надо 8 байт. Компилятор - менять не буду! Вы ограничены не компилятором, а собственным воображением. У компилятора, наверное, есть тип long long. Но это все равно не поможет, если сначала делить на 16777215, а затем умножать на 1000000. С таким подходом никакой разрядности не хватит, надо менять образ мышления. Цитата(Leonmezon @ Jul 24 2009, 21:02)  Может конструкция switch {} заменить на if? (здесь можно что то выиграть) По сравнению с остальным это такая мелочь, что не выйграете ровным счетом ничего.
|
|
|
|
|
Jul 24 2009, 17:44
|
Частый гость
 
Группа: Участник
Сообщений: 191
Регистрация: 11-02-09
Из: Краснодар
Пользователь №: 44 686

|
Цитата(aaarrr @ Jul 24 2009, 21:22)  Вы ограничены не компилятором, а собственным воображением. У компилятора, наверное, есть тип long long. Но это все равно не поможет, если сначала делить на 16777215, а затем умножать на 1000000. С таким подходом никакой разрядности не хватит, надо менять образ мышления.
По сравнению с остальным это такая мелочь, что не выйграете ровным счетом ничего. Причем здесь мышление не совсем понятно, код в целочисленном виде я могу записать вот так (чтобы не было точно double!!!). Код rez=((rez*215540000)/16777215)-107700000; // где при максимальном rez=0xFFFFFF - получим в первой скобке число 3616160921100000=0xCD8E113271EE0 - 8байт
|
|
|
|
|
Jul 24 2009, 18:14
|
Частый гость
 
Группа: Участник
Сообщений: 191
Регистрация: 11-02-09
Из: Краснодар
Пользователь №: 44 686

|
Цитата(aaarrr @ Jul 24 2009, 22:05)  Да не нужно заниматься ерундой и делить на 16777215! В самом начале Вы получаете 24-х битное число, так и работайте дальше с ним. Как я могу обойтись без деления, если мне необходимо перевести из коды АЦП в напряжение??? Весь диапазон: 20 В - или 0xFFFFFF в кодах, используя простое правило пропрции - получаем искомое, как можно еще иначе? (причем если значения коэффициентов: масштабного и учет смещения в Вольтах).
|
|
|
|
|
Jul 24 2009, 18:41
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Leonmezon @ Jul 25 2009, 00:14)  Как я могу обойтись без деления, если мне необходимо перевести из коды АЦП в напряжение??? Вы огласите сначала, с какой точностью вам нужно проводить измерения? А то мучаетесь тут с каким-то микровольтами и 24-разрядным результатом измерения АЦП, а требуется, допустим, 0,1% относительная приведенная погрешность. Для этого при диапазоне входных напряжений -10В...+10В достаточно измерять с разрешением (10В-(-10В))/(0,1%*100)<=20мВ скажем 1мВ. Для представления напряжения с точностью 1мВ в указанном диапазоне вполне достаточно 16-и разрядного знакового числа. И соответственно типа long вполне хватит для всех вычислений.
|
|
|
|
|
Jul 24 2009, 18:58
|
Частый гость
 
Группа: Участник
Сообщений: 191
Регистрация: 11-02-09
Из: Краснодар
Пользователь №: 44 686

|
Цитата(aaarrr @ Jul 24 2009, 22:40)  Деление на 16777215 и умножение на 20000000 эквивалентно умножению 1.1921. В целых числах делается умножением и сдвигом. Коэффициенты пересчитайте отдельно. 1. Для меня это сложно! Умножать на 1,1921 со сдвигом. (точнее правильно с масштабом 1,077 умножить надо на К=1,283884124987371265135482855766 чтобы использовать уменьшению формулу: rez=(rez*К)-107700000; 2. Точность необходима полная - все 24 разряда.
|
|
|
|
|
Jul 24 2009, 19:10
|
Частый гость
 
Группа: Участник
Сообщений: 191
Регистрация: 11-02-09
Из: Краснодар
Пользователь №: 44 686

|
Цитата(rezident @ Jul 24 2009, 23:02)  Ерунду написали. АЦП измеряет напряжение. Напряжение принято выражать в Вольтах. С какой относительной погрешностью (в процентах) и в каком диапазоне напряжений (в Вольтах) вам нужно проводить измерения? Повторюсь - 24 разряда АЦП или +- 10 В с максимальной точностью что дает АЦП (по заявленным характеристикам без ухищрений +- 150 мкВ).
|
|
|
|
|
Jul 24 2009, 19:52
|
Частый гость
 
Группа: Участник
Сообщений: 191
Регистрация: 11-02-09
Из: Краснодар
Пользователь №: 44 686

|
Цитата(rezident @ Jul 24 2009, 23:25)  150мкВ при опоре 2,5В (или 1,25В?) это уже никак не "все 24 разряда". Плюс потеря точности на делителе/преобразователе, который приводит диапазон -10В...+10В ко входному 2,5В(1,25В). В результате относительная точность измерения входного напряжения скорее всего не лучше 0,01%. Но вы конечно же можете продолжать использовать "все 24-разряда" для вычислений.  Вы не правы! Для начала посмотрите даташит на АЦП (AD7732) где при ИОН 2,5 В за счет внутренних резисторов !!!!!!! (выполненых с точность не менее 0.006 %) и получаеться заявленная мною неустойчивость, так что реально необходимы все разряды АЦП без округления. Между прочим - я просил код помочь оптимизировать на быстродействие - а не рассказыват о точности АЦП - в любом случае Ваши знания не точнее информации из даташита!
|
|
|
|
|
Jul 25 2009, 03:25
|
Профессионал
    
Группа: Участник
Сообщений: 1 273
Регистрация: 3-03-06
Пользователь №: 14 942

|
Цена деления 1,2 мкВ при точности ±150 мкВ.. Кстати, вы, вероятно, ошиблись. В описании на AD7732 явно указано «% of FSR», а не процент от опорного. Получается около ±6 мВ. По поводу оптимизации. Посмотрите в таком направлении, может что и получится: Думаю, не обязательно перемножать каждый раз то, что можно перемножить заранее. «Используя простое правило пропорции», никто вас не обязывает брать крайние значения. Например можно взять половину от hFFFFFF. rez = (Kd - h7FFFFF) * (10^7*KU) / h7FFFFF1. Вычитание со знаком; 2. Умножение (6 байт включая знак!). 3. Деление (фактически сдвиг на 7 бит с отбросом двух байт с сохранением знака). Осталось одно умножение, которое, видимо, можно сделать заблаговременно (10^7 * Ka). Погрешность у меня получилась ~1,2 мкВ при цене деления 1,2 мкВ. Вам правильно указали, что надо определиться с точностью. И тогда, может быть, выбрать еще более приятную всё ту же пропорцию. Удачи.
Сообщение отредактировал x736C - Jul 25 2009, 03:34
|
|
|
|
|
Jul 25 2009, 16:24
|
Частый гость
 
Группа: Участник
Сообщений: 191
Регистрация: 11-02-09
Из: Краснодар
Пользователь №: 44 686

|
Если вот так записать код, насколько будет быстрее первоначального? (и что еще можно упростить, без применения ухишрений (типа сдвига...). И можно что то сделать с отниманием 1 (или она мало занимает кода). Код const signed int K11=-831; // программный учет смещения в 1 канале 1 АЦП const signed int K12=-999; // программный учет смещения в 2 канале 1 АЦП const double KU=10770000; // коэффициент передачи сигнала в аналоговой части 1.077 умноженный на 1000000х10 const double Kd=8388608; // половина всего диапазона для +-10В - 0xFFFFFF/2 . . // Функция получения данных от 1-го АЦП signed long uzmerenie1(void) { . . . rez=(C+(B<<8)+(A<<16)); /* Далее преобразуем с типу double и преобразуем к напряжению с упрощением операций, конечный результат: напряжение от -10 В до 10 В в микровольтах*/ U=((double)(rez))/Kd; U=U-1; // Отнимаем 1 - для сдига в биполярный сигнал rez=(signed long)(U*KU); // Изменяем масштаб и преобразуем в микровольты и возращаем результат rez=rez-K; //Учитываем смещение в каждом из каналов АЦП: 1К - К11; 2К- К12 return (rez); }
Сообщение отредактировал Leonmezon - Jul 25 2009, 16:26
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|