25.04.2013, 14:30
|
#31
|
Гражданин KAZUS.RU
Регистрация: 06.04.2010
Адрес: Санкт-Петербург - Волжский
Сообщений: 529
Сказал спасибо: 74
Сказали Спасибо 56 раз(а) в 45 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от _Артём_
|
Возможно, лучше будет суммировать так, чтобы переполнения не возникало?
Код:
AdcSum+=ADC;
if (++AdcSumCnt›=64) {
AdcSumCnt=0;
OffAdc();
UpdateResult();
}
К тому же, если суммировать пока не переполнится, то как узнать среднее значение АЦП? Поделить полученную сумму на количество отсчетов? Так это ещё деление. Или задача другая?
|
Да, задача другая. Вычисляю усредненное значение по 4 замерам АЦП размером 8 бит (ADCH). Чтобы не вводить отдельный сч. замеров каждый раз к рез-ту очередного замера в старш.байт добовляю 0b 0100 0000.
При переполнении общей суммы остается только сдвинуть 2 раза регистр SumADC
|
|
|
|
25.04.2013, 14:42
|
#32
|
Гражданин KAZUS.RU
Регистрация: 06.04.2010
Адрес: Санкт-Петербург - Волжский
Сообщений: 529
Сказал спасибо: 74
Сказали Спасибо 56 раз(а) в 45 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от electroTrash
|
Да что там , при таком "методе" получения среднего случайная ошибка при любом количестве членов суммирования будет не меньше случайной ошибки среднего от всего лишь двух измерений. Это собственно показывает ущербность алгоритма ТС, лучше брать сумму с запасом разрядности (т.е. без проверки переполнения) и сдвигать, чем суммировать неопределенное количество значений и делить.
|
Хотите сказать, что даже пусть для 4х замеров будет лучше каждый раз суммировать с новым значением АЦП и тут же приводить к среднему , чем накапливать сумму 4 измерений ?
|
|
|
|
25.04.2013, 14:47
|
#33
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от alvadep
|
Это для ФНЧ. Для полосового и ФВЧ, если не ошибаюсь, сумма коэффициентов должна быть равна 0. Или нет?
|
Здесь ФНЧ 2 варианта приведены. Для ФВЧ и полосового коэффициент передачи расчитывается. В приведённой проге, в хелпе, есть пояснения. Я просто хотел отметить, что в целом вы можете одновременно отфильтровать сигнал и усилить/ ослабить его. И, также, отмечаю что это бывает не только полезно, но и просто необходимо. Дело в том, что при разрядности вх. сигнала 8/10 бит и работе с 16 битной арифметикой, у вас потеря значимости при округлении - значительна. Это легко увидеть моделируя сигнал. Поэтому отработанный фильтр, в реальных условиях может давать не совсем корректный результат. Пример я привёл. Качество восстановления сигнала при применении АРУ у меня увеличилось очень существенно.
|
|
|
|
25.04.2013, 14:55
|
#34
|
Гражданин KAZUS.RU
Регистрация: 06.04.2010
Адрес: Санкт-Петербург - Волжский
Сообщений: 529
Сказал спасибо: 74
Сказали Спасибо 56 раз(а) в 45 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от electroTrash
|
Все эти условия проверки имеют ошибки, так сказать "слабые точки".
Правильно так:
Код:
if(sumADC|temp16)›(temp16+sumADC) // условие проверки переполнения
// отключаем АЦП
ADCSRA&=~(1‹‹ADEN);
|
К примеру здесь:
Цитата:
|
sumADC+=temp16;
if (sumADC‹temp16)
|
, какие слабые точки ?
|
|
|
|
25.04.2013, 15:10
|
#35
|
Заблокирован
Регистрация: 27.03.2007
Сообщений: 1,328
Сказал спасибо: 12
Сказали Спасибо 576 раз(а) в 460 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от MaxiMuz79
|
Чтобы не вводить отдельный сч. замеров каждый раз к рез-ту очередного замера в старш.байт добовляю 0b 0100 0000
|
Ну, Вы - большой оригинал! Тогда в Вашем случае проще и быстрее проверять два старших бита на ноль. Типа, так
Код:
|
if ((sumADC & 0xC000)==0)
{ // накопление закончено,
//сдвигаем 2 раза регистр SumADC
} |
|
|
|
|
25.04.2013, 15:17
|
#36
|
Гражданин KAZUS.RU
Регистрация: 06.04.2010
Адрес: Санкт-Петербург - Волжский
Сообщений: 529
Сказал спасибо: 74
Сказали Спасибо 56 раз(а) в 45 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от Yurkin2007
|
Ну, Вы - большой оригинал! Тогда в Вашем случае проще и быстрее проверять два старших бита на ноль. Типа, так
Код:
|
if ((sumADC & 0xC000)==0)
{ // накопление закончено,
//сдвигаем 2 раза регистр SumADC
} |
|
тогда получается доп.несколько команд процессора, т.к. после сложения рез-т уже готов к проверке
|
|
|
|
25.04.2013, 15:56
|
#37
|
Заблокирован
Регистрация: 27.03.2007
Сообщений: 1,328
Сказал спасибо: 12
Сказали Спасибо 576 раз(а) в 460 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от MaxiMuz79
|
получается доп.несколько команд
|
Это правда. Ну, если Вы боретесь за каждую команду, то проверка carry bit самый быстрый способ.
|
|
|
|
25.04.2013, 20:00
|
#38
|
Прописка
Регистрация: 05.01.2013
Сообщений: 201
Сказал спасибо: 12
Сказали Спасибо 29 раз(а) в 24 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от MaxiMuz79
|
Хотите сказать, что даже пусть для 4х замеров будет лучше каждый раз суммировать с новым значением АЦП и тут же приводить к среднему , чем накапливать сумму 4 измерений ?
|
Нет, совсем наоборот, лучше накапливать сумму измерений и делить в конце, хотя, можно и так SUM=(SUM*2+NEW)/2 , получиться тоже самое, что и при SUM=SUM+NEW, SUM/N
Цитата:
|
if (sumADC›~temp16)
|
абсурдность этого условия очевидна, ввиду того, что, вследствие произвольности числа temp16, произвольно и ~temp16, собственно, с одинаковым правом можно утверждать и что sumADC›temp16 (или sumADC‹temp16).
Последний раз редактировалось electroTrash; 25.04.2013 в 20:05.
|
|
|
|
25.04.2013, 20:33
|
#39
|
Прописка
Регистрация: 05.01.2013
Сообщений: 201
Сказал спасибо: 12
Сказали Спасибо 29 раз(а) в 24 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от SasaVitebsk
|
Тут надо ещё понимать некоторые вещи. Сума коэффициентов должна быть равна 1, если ты хочешь получить сигнал 1:1. Но так бывает не всегда. Например входной сигнал 10 или 12 бит. Увеличить его вдвое (на 1 бит) ничего плохого не произойдёт.
|
А чего тут понимать то, эти коэффициенты определяют вероятность того или иного значения, а их сумма всегда должна P1+P2+... +Pn=1, тогда X=X1*P1+...XnPn, непонятно другое, почему надо брать разные коэффициенты вне зависимости от величины измерения X1, а от порядкового номера, который определяется абсолютно произвольно?
|
|
|
|
25.04.2013, 20:48
|
#40
|
Почётный гражданин KAZUS.RU
Регистрация: 05.05.2011
Адрес: Харьков
Сообщений: 5,049
Сказал спасибо: 592
Сказали Спасибо 3,968 раз(а) в 1,826 сообщении(ях)
|
Re: Как в Си определить выход за приделы кода (переполнение) результата операции ?
Сообщение от electroTrash
|
абсурдность этого условия очевидна, ввиду того, что, вследствие произвольности числа temp16, произвольно и ~temp16, собственно, с одинаковым правом можно утверждать и что sumADC›temp16 (или sumADC‹temp16).
|
Мне кажется, что это утверждение значительно абсурдней.
Где примеры доказывающие обратное.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 13:25.
|
|