-
Постов
4 850 -
Зарегистрирован
-
Победитель дней
3
Весь контент Xenia
-
В данном случае варианты компиляции выражения WDTCR |= (1<<WDCE) | (1<<WDE); несущественны, поскольку запись в регистр WDTCR всегда будет ПОСЛЕДНЕЙ инструкцией. А, стало быть, протяжка перед следующей строкой WDTCR = 0; зависит исключительно от сложности обнуления регистра. Дольше двух тактов это не затянется при любых способах оптимизации или отсутствия оной.
-
Длиннее просто невозможно скомпилировать, т.к. операции с константами всегда производятся еще при компиляии, а не в runtime. Приведенная в моем прошлом посте компиляция одинакова как при отсутствии оптимизации, так и при оптимизации по скорости или размеру. Поскольку из-за примитивности примера ее невозможно оттранслировать ни длиннее, ни короче. Константы невозможно "приготовить заранее". Если вы намереваетесь поместить их в память, то вытаскивание оттуда обойдется дороже - тогда действительно в 4 такта можно не уложиться. А если положить в регистр, то примерно так оно и получится. P.S. Мой предыдущий пост, адресованный вам, был мною отредактирован. Ознакомьтесь с ним пожалуйста еще разик.
-
Вот, пожалуйста, результат компиляции на IAR EWAVR: WDTCR |= (1<<WDCE) | (1<<WDE); 00000000 B501 IN R16, 0x21 00000002 6108 ORI R16, 0x18 00000004 BD01 OUT 0x21, R16 WDTCR = 0; 00000006 E000 LDI R16, 0 00000008 BD01 OUT 0x21, R16 - между записями в регистр WDTCR только одна лишняя команда. Итого всего 2 такта между операциями записи. А про оптимизацию вы не совсем правы, когда речь идет о записи в регистры, то компилятор (IAR) никогда не опускает присваивание, даже если оно повторное. И это при любом типе оптимизации - как по размеру, так и по скорости. Однако не забывайте название темы - сказано, что WatchDog запустить удалось. А, значит, компиляция велась в условиях, когда требование 4-х тактов соблюдалось. Поэтому это условие я не стала особо оговаривать.
-
А вы пытались останавить его тоже комбинацией или простой записью? Может быть так попробовать: WDTCSR |= (1<<WDCE); WDTCSR = 0; или так: WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = 0; Только не забудьте прерывания блокировать на время исполнения этих двух строк. Ну в крайнем случае так: cli(); wdt_reset(); MCUSR &= ~(1<<WDRF); WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = 0; sei(); Ну тут уж кажется всё предусмотрено с запасом...
-
Кстати, у AT32UC3 на борту имеется 16-bit Stereo Audio Bitstream – Sample Rate Up to 50 KHz. Что такое битстрим и чем он от PWM отличается, я так и не поняла, но этот МК позиционируется как раз для высококачественных аудиопроигрывателей с закачкой контента из интернета (видимо для этого у него еще и Ethernet на борту). А ваша MSP 16 бит на 50-ти мегагерцах потянет? :)
-
А что, разве АРМы превосходят АВРы в том, что биты поштучно из памяти таскают? :)
-
Несуразности возникают только в сознании :), когда путают переменную типа bool и операцию с битами. ЛЮБАЯ ПЕРЕМЕННАЯ - это одна или несколько ячеек памяти, а потому быть тождественной с битом она принципиально не может. А если нужны операции с битами, то это делается не с помощью bool-типа, а с помощью побитово расписанной структуры. Например: struct mystruct bool a : 1; bool b : 1; bool c : 1; bool d : 1; bool e : 1; bool f : 1; bool g : 1; bool h : 1; ) flag; Вот тут уже все становится ясно и компилятору, и процессору, и программисту - видно, что в памяти ассигнован блок в один байт (8 бит), из которого велено таскать биты. Ни у одного процессора в мире нет в памяти однобитных переменных. И это уже потому, что память побитно не адресуется. Однако компиляторы обычно предоставляют пользователям удобные способы работы как с битами, так и с битовыми полями (см. мою предыдущую реплику). Однако надо понимать, что делается это "через ухо", т.е. компилятор достает слово памяти целиком, а потом вырезает из него нужные биты. Модификация бита стоит еще дороже - сначала процессор прочитывает целиком слово памяти, к которому этот бит относится, при помощи операций or и and модифицирует в нем нужный бит или группу битов, а затем записывает модифицированное слово обратно в память. Инструкции ряда микропроцессоров (и AVR в том числе) позволяют модифицировать отдельные биты в собственных регистрах и портах, только в этом случае битовые операции над ними реализуются эффективно. Поэтому битовые флаги лучше всего держать в регистрах, а не в памяти. Во всех же остальных случаях, выгоднее не экономить на спичках, а заводить переменную bool типа. Такая кодировка действительно оказывается избыточной, зато ее применение компенсируется максимально высокой скоростью использования. Можно с полным основанием считать, что тип bool является атрибутом оптимизации как по скорости, так и по объему кода, когда как его недостаток состоит лишь лишнем расходе памяти.
-
Грустно, что обсуждение перешло обсуждение на размерности булевской переменной. По всей видимости, это произошло из-за того, что участники дискуссии путают "битность" процессора и шириной шины данных. Между тем, как это вещи в общем случае разные. Разрядность регистров процессора может превосходить ширину шины данных (т.е. сетку физической адресации памяти), но наоборот быть не может. В своё время процессор i80386SX уже имел 32-разрядные регистры, когда как работал с 16-разрядной шиной памяти. Такая ситуация означает лишь необходимость в наличии инструкций по чтению/записи старшей и младшей части регистра и их комбинацию, обеспечивающую двухступенчатый обмен между целым регистром и двумя последовательными ячейками памяти. Вопрос о размерности булевской переменной связан исключительно с шириной шины памяти. Не процессор виноват в том, что один бит из памяти он достать не может, а вынужден читать или писать целиком область памяти, равную разрядности шины данных - это атрибут памяти, которая не может считываться или записываться побитно. При этом заметим, что и от адресации памяти (виртуальной) размер булевской переменной не зависит. Адресация памяти может быть побайтная, в то время как шина данных быть в 4 байта. Такая ситуация мешает процессору сразу записать байт в память, а вынуждает его сперва прочитать из нее 4 байта, потом заменить один из байтов на новый, и уж только затем записать назад эти 4 байта. Как видим, операция с булевскими переменными становятся неэффективными, если размерность такой переменной отличается от ширины шины данных. Причем это же касается и операций с текстовыми символами, которые в практическом отношении встречаются гораздо чаще, чем булевские переменные. Возвращаясь к микропроцессорам замечаем, что разрядность шины данных у них обычно мала. Т.е. данные передаются во внешнюю память силами одного, максимум двух портов. Например, у AVR32 шина данных памяти 16 бит (шину адреса я не посчитала). Это означает, 3что 32-битность на память не распространяется, поскольку ФИЗИЧЕСКИ память обменивается с процессором сразу 2-мя байтами. Стало быть и булевская переменная, если уж она так сильно вам нужна, будет в данном случае иметь 16-битную размерность. Гораздо более существенным вопросом, чем размерность булевской переменной, является вопрос о размерности АДРЕСА памяти, что в первую очередь определяется максимальным объемом рабочей памяти. У AVR32 этот адрес занимает 24 бита. Именно отсюда и возникает преимущества 32-битности, что адрес целиком помещается в регистр. Тут уже не надо маяться, работая с адресом, как регистровой парой (операция по ее инкрементированию более сложна). Ну а главное все-таки арифметика! Все мы знаем, что размерность произведения вдвое больше размерности данных. Вот тут-то длинные регистры очень кстати. И, наконец, преимущества длинных регистров поймут все те, кто хотя бы краешком глаза заглядывал на то, как реализуется в библиотеках эмуляция работы с плавающей точкой.
-
Почитала эту тему, и вот на какие мысли это меня навело. Сначала оценила тему, как очередное бодание типа какой язык программирования лучше, какой процессор лучше или какая лучше футбольная команда. Конечно и тут не без этого, но суть все-таки в том, что на 8 битах действительно становится тесно. И вроде бы никаких особо сложных расчетных задач на микропроцессорах не решают, а всё ж теснота ощущается. Раньше тесновата была оперативка (SRAM) и за этой теснотой про 8 бит и не думали. Когда сильно жмет в одном месте, то на другие места внимание не очень обращаешь. А тут как оперативки и флэша добавили, так сразу и зачесалось в другом месте - перестало хватать разрядности и тактовой скорости. Когда-то почти такое же произошло с компьютерами клона IBM PC. Пока памяти мало было, хватало и 16-ти разрядов, а увеличилась память - потянуло на 32 разряда. А сейчас кое-кого тянет уже на 64 и 128 (SSE). Все это, впрочем, понятно. Парадокс в другом. Вот если каждый день есть манную кашу :) (тут можно выбрать любое другое блюдо), то очень скоро такая еда приедается. Да еще так, что глаза на нее не смотрят. А вот как начнешь на каком-то микропроцессоре работать, то никак потом с него не слезешь. А точнее не конкретного микропроцессора, а его семейства. Тут более продвинутые члены семейства психологически рассматриваются как его улучшенные копии, а потому отторжения не возникает. Впрочем, есть и такие, кто сразу на всех типах микропроцессоров работать поспевал - такие указанной болезнью не болеют, или болеют в легкой форме. А вот если год-два с одним типом микропроцессоров возишься, то болезнь протекает в острой форме. Поэтому прежде чем указывать на соринки с чужих глазах, должна признаться в том, что сама на AVR крепко подсела, т.к. с никакими иными МК дела не имела. Болезненным сознанием :) недостатки АВР вроде бы осознаются, однако все другие МК выглядят при этом крайне непривлекательно. Особенно Пики :). А АРМ кажутся монстрообразными нагромождениями несуразностей. Причем не столько в смысле архитектуры, сколько их мерзким :) набором инструкций. А теперь вот у меня развилась совсем "злокачественная форма" - заочно влюбилась :) в AT32UC3. Тут дело такое, что по инструкциям он не АРМ, а несомненно АВР, хотя набор инструкций и претерпел заметные изменения. Однако тут произошло то главное, о чем мечтала душа, - большая разрядная сетка + большая память + высокая скорость. И при этом цена соизмерима со старшими моделями AVR8. Опять же встроенный USB-канал, а то и Ethernet. Один только видимый недостаток - ног слишком много, приходится из-за этого число слоёв на плате увеличивать. На моем примере видно, что на самом деле это не тяга к АРМам, а простое желание расширить разрядность операций и память. Просто жизнь такова, что АРМы в настоящее время наиболее широко распространены (думаю, что это из-за сотовых телефонов). Отсюда и мысль получается плоская и примитивная, если куда-то линять с АВР, то обязательно на АРМ. А вот я хочу предложить на АРМ не линять, а остаться на АВР. Только там, где тесно, перейти на AVR32. Сейчас вы все завопите, что де тупиковая это ветка, и что мол АРМы выпускают десятки компаний, а AVR32 только одна. Начнете сомнения выдвигать, что Atmel долго не проживет. И т.д. Как будто сами собрались тыщу лет жить :). Да Atmel переживет и вас, и ваши проектики!!! И вот еще что. Это только на первый взгляд кажется, что популярность модели МК зависит от широты ассортимента, предлагаемых многочисленными фирмами. На самом же деле все наоборот! Это именно популярность и спрос заставляет расширять номенклатуру того, что им пользуется. И тот же спрос вызывает конкуренцию, заставляющую другие фирмы делать их аналоги. Поэтому, в конечном счете, всё от нас зависит, от разработчиков. Пока мы заказываем чипы - их производят, а как спрос падает, так умирает и производство. Из-за этого было бы глупо каждый раз делать ставку на самую распространенную модель. Эдак бы мы все до сих пор С51 юзали :). Ведь нашлись же энтузиасты, которые от С51 архитектуры перешли в свое время на AVR8? Вы же не считаете их придурками? Всегда находятся те, кто осваивает Америки, и те, кто до самой свой смерти живет в старой доброй Англии, руководствуясь традициями. Вот и сейчас народ колеблется между двумя традициями, АВР и АРМ, когда как то и другое уже традиции с бородой. А вот AVR32 очень перспективное направление. Только, чтобы осознать это, надо вникать не только содержимое прайс-листов. К слову скажу, что набор инструкций AVR32 на треть производительнее АРМовского набора, а потому можете считать, что у вас таковая на треть увеличилась. И вообще Atmel много новых идей вложила в свою разработку AVR32-архитектуры. Просто обидно видеть, что все это отложено разработчиками "до лучших времен", а ставка делается на АРМ-архитектуру, которая почти так же стара, как С51 :). Ну за счет прогресса в электронике (в основном скорости) АРМы сильно прибавили в весе, но это лишь постольку, поскольку всякая RISC-архитектура отзывается на прибавку в скорости.
-
Огромное спасибо! Теперь мне стала абсолютно ясна причина, по которой у меня расстановка сегментов не соответствовала файлу конфигурации lnkm8s.xcl - компилятор брал его из другого файла cfg1soim.xcl, поскольку та галка у меня в проекте стояла. Стало быть разница в укладке сегментов следует из содержимого файлов конфигурации cfg1soim.xcl и cfg1toim.xcl. В модели tiny стеки выше tiny-данных: -Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE -Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE -Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE -Z(DATA)IOSTREAM_N#_..X_SRAM_TBASE:+_..X_SRAM_TSIZE -Z(DATA)TINY_HEAP+_..X_TINY_HEAP_SIZE=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE -Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END -Z(DATA)NEAR_I,NEAR_Z=_..X_SRAM_BASE-_..X_SRAM_END -Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END -Z(DATA)NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END А в модели small стеки ниже near-данных: -Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_TBASE:+_..X_SRAM_TSIZE -Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_CSTACK_BASE-_..X_CSTACK_END -Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END -Z(DATA)IOSTREAM_N#_..X_SRAM_BASE-_..X_SRAM_END -Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END -Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_RSTACK_BASE-_..X_RSTACK_END -Z(DATA)NEAR_I,NEAR_Z,NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END Еще раз спасибо за исчерпывающее разъяснение!
-
В tiny-модели вроде бы CSTACK кверху рос. Впрочем, я не твердо в том уверена, поскольку старалась локальные переменные в функциях размещать в мусорных регистрах. Но в какую бы сторону ни рос стек, мой вопрос остается в силе. Я привела явные доказательства того, что в small-модели стеки организуются ниже данных. Об этом однозначно свидетельствует выдержка из map-файла, которую я привела в первом сообщении. Пока мой вопрос о причинах этого явления остается без ответа.
-
Это не так! Для ATmega8 по умолчанию имеются два файла для конфигурации линкера: lnkm8t.xcl (для tiny-модели) и lnkm8s.xcl (для small-модели). Смотрим конфигурацию для small-модели (файл lnkm8s.xcl): /* Internal data memory */ -Z(DATA)TINY_I,TINY_Z,TINY_N=60-FF -Z(DATA)NEAR_I,NEAR_Z=60-45F -Z(DATA)RSTACK+_..X_RSTACK_SIZE=60-45F -Z(DATA)CSTACK+_..X_CSTACK_SIZE=60-45F -Z(DATA)HEAP+_..X_HEAP_SIZE=60-45F -Z(DATA)IOSTREAM_N#60-45F -Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=60-45F Как видим, стеки перечислены ПОСЛЕ данных, но, тем не менее, располагаются они в обратном порядке (RSTACK+CSTACK ниже чем NEAR_I+NEAR_Z). Примерно таже последовательность и в файле конфигурации tiny-модели. Если отбросить все то, что к делу не относится (хипы и иостримы), но порядок перечисления сегментов -Z(DATA) для обоих моделей использован одинаковый - память раньше стеков, но результат компиляции получается разный. Ваше утверждение уже потому не может быть правдой, что в конфигурациях линкера строка RSTACK стоит раньше чем CSTACK, когда как каждому известно, что CSTACK всегда ниже RSTACK'а, т.к. первый растет вверх, а второй вниз.
-
Почему в small-модели стеки находятся снизу и как это исправить? Работая с ATtiny2313 я уже привыкла к тому, что стеки (CSTACK и RSTACK) находятся сверху (в старших адресах). Это было очень удобно тем, что в программе можно было явно установить указатель RSTACK'а на самый верх, тем самым, задействуя всю неиспользованную память под стеки. Вручную же рассчитывать размеры стеков крайне неудобно, т.к. CSTACK запрашивают в байтах, а RSTACK в словах. А я не арифмометр, чтобы подбирать эти значения так, чтобы они вписались во весь объем памяти. Тем более что такую операцию мне пришлось бы выполнять каждый раз, когда бы я заводила или удаляла какую-нибудь переменную или изменяла размеры массива. А так, устанавливаешь указатель на вершину памяти и никакой тебе головной боли. Однако перейдя со временем на МК с большим объемом ОЗУ, пришлось перейти и на модель памяти small. И тут меня ждало неприятное известие о том, что теперь стеки находятся внизу, за ними данные, а пустое пространство сверху. Теперь его уже никак нельзя использовать, кроме как вручную каждый раз изменять размеры стеков в проекте. В таком расположении стеков я ничуть не виновата - IAR так делает сам. Вот посмотрите на контрольный тест для ATmega8. Этот МК выбран только потому, что допускает обе модели памяти: как tiny, так small. Пишу простейшую программу, содержащую массив данных Buffer, и компилирую ОДИН И ТОТ ЖЕ ПРОЕКТ на tiny и small моделях, переключая в проекте ТОЛЬКО тип модели и не трогая ничего остального. unsigned char Buffer[70]; C_task main( void ) { Buffer[0] = 0; } В модели tiny получаю: SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN ======= ===== ============= =========== ==== ==== ===== TINY_I DATA 00000060 dse 0 TINY_Z DATA 00000060 - 000000A5 46 rel 0 CSTACK DATA 000000A6 - 000000B9 14 dse 0 RSTACK DATA 000000BA - 000000C9 10 dse 0 А в модели small вот это: SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN ======= ===== ============= =========== ==== ==== ===== CSTACK DATA 00000060 - 00000073 14 dse 0 RSTACK DATA 00000074 - 00000083 10 dse 0 NEAR_I DATA 00000084 dse 0 NEAR_Z DATA 00000084 - 000000C9 46 rel 0 Абсолютно та же самая ситуация со small-моделью во всех остальных моделях МК (проверяла еще и на AT90USB647). Мой вопрос: Какими соображениями обусловлено такое распределение памяти в small-модели? Можно ли как-то изменить такое распределение памяти и заставить компилятор размещать данные ниже стеков?
-
Я вот тоже сильно смеялась, вот над этим:
-
Скажите пожалуйста, а что может быть принято за эталонное напряжение? Где его берут? Делители на сопротивлениях - ерунда, т.к. у резисторов номинал редко выдерживается точнее 1%, а любой АЦП на порядок точнее. А если меня 20-ти и более разрядный АЦП, то как определить на сколько он врет при измерении? Даже источники опорного напряжения тут не годятся, т.к. несмотря на то, что напряжение они держат неплохо, но сама величина этого напряжения варьируется в пределах 0.1 вольта даже в одной партии. Измерителные приборы? А за них кто поручится? Ведь даже самый точный вольтметр не потянет на одну миллионную часть шкалы. А вот 20-разрядный АЦП как раз имеет примерно такую величину дискреты. ЦАПы? Но они и по разрядности уступают АЦПам, и наверняка сами имеют собственные погрешности, превосходящие АЦП, поскольку приготовить высокоточное напряжение технологически сложнее, чем его измерить. Ситуация оказывается плачевной - АЦП имеют "класс точности" выше, что то напряжение, которые мы можем подать на их вход. P.S. Такие вопросы возникают у меня из-за того, что все измерительные приборы положено "поверять". Таково формальное требование закона. Вот и любопытно мне, как можно АЦП "поверить", если подойти к делу честно.
-
Если один раз получилось прошить, то, значит, USB DFU Bootloader у вас все-таки есть! Поделитесь!
-
Именно такая плата мне и попалась. Успела побывать в чужих руках, отчего всё вместе с загрузчиком стерто. Тем не менее, мне не понятно ваше утверждение, что мне всё равно потребуется JTAG. Ведь вам же удалось прошить через AVRDRAGON? И еще вопросик: не знает ли вы, где можно раздобыть прошивку USB-загрузчика или, на крайний случай, COMport-загрузчика? На сайте Atmel выставлено руководство по его использованию, а самой прошики там не нашла. А из ваших постов на формум я поняла так, что у вас имеется даже не бинарник, а исходники загрузчика, только что-то там не компилировалось.
-
altlogic, вы по-прежнему вот так прошиваете: http://electronix.ru/forum/index.php?s=&am...st&p=534487 или с тех пор изобрели способ, которым можно прошить в стандартном режиме?
-
программирование USB на AVR
Xenia ответил тема в MCS51, AVR, PIC, STM8, 8bit
Вот полезная тема по близкой проблеме: http://electronix.ru/forum/index.php?showt...=41715&st=0 Лично мне эта информация сильно помогла. -
Расскажите, пожалуйства, подробнее! Каков размер прошивки вам удалось таким образом загнать? А то про AVRDRAGON сказано, что у него ограничение в 32 кб. Распознает ли AVRDRAGON чип AT32UC3 или там распознавание не используется? Какая версия AVR Studio поддерживает AT32UC3 через AVRDRAGON. Ну и вообще любые подробности на эту тему.
-
Откуда это вам известно? И еще другой вопрос: отчего эта плата такая дорогая? Сам процессор стоит в розницу 519 руб. штука (если 3 штуки покупаешь, то - 448 руб.) [ http://www.terraelectronica.ru/get_pos.php...p;CODES=281595; ], а остальные тыщи за что? Вроде бы ничего столь же дорогого на той плате боьше нет. Разве что вот только дисплейчик, но он не может так дорого стоить. Процессор этот меня сильно интересует, а мне самой 144-ножку мне никогда не припаять. Вот и положила глаз на эту плату. Но за 6 тыщ ее покупать я, конечно, не стану. А вот за 3 тысящи можно было бы и купить.
-
AtMega, спектральный анализ
Xenia ответил AnisimovSlava тема в AVR
Мои советы: 1) Если есть возможность, не заморачиваться с float-арифметикой. Особенно, если исходные данные у вас целые (например, измерения АЦП), вам нужна лишь оценка частотного спектра и вы не собираетесь делать ему обратное FFT-преобразование. В этом случае лучше всего создать ЦЕЛОЧИСЛЕННУЮ таблицу синусов, содержащую столько же ячеек, сколько и в буфере данных, которые будут подвергнуты преобразованию (то и другое - массивы, кратные целой степени двойки: 64, 128, 256, 1024, 2048 и т.д.). Однйо этой таблицы достаточно, чтобы все значения синусов и синусов, необходмые для вычислений, можно было выбрать из нее. Для большинства целей бывает достаточно массива синусов с ячейкой типа char (1 байт). При этом синус нормируется на величину +-128 (signed char). Поскольку максимальные пределы синуса лежат в интервале от -1 до +1, то достаточно значение синуса для угла i*360/n градусов (где i-номер элемента массива) умножить на 128, а затем округлить до БЛИЖАЙШЕГО целого. Эту таблицу прошить во flash, чтобы не тратить под нее оперативку. Есть вариаты нормировать на 2^15 = 32768, т.е. на MAX_INT, используя массив типа int. Тут точность получится совсем хорошая, но дольше станет умножение. Однако даже этот вариант летает со свистом по сравнению с умножением во float-числах. Теоретически таблицу можно сделать в четверо короче, используя симметрию функции синуса, но тогда станет несколько сложнее алгоритм выборки. 2) Заранее решить, нужна ли вам реальная (косинусная) и мнимая (синусная) части разложения, или вам, как большинству электронщиков, нужно только значение мощности (корень из суммы квадратов дествительной и мнимой амплитуд). Если это так, то существует алгоритм FFT-преобразования, который сразу дает мощность. В противном случае вам придется n-раз исчислять корень квадратный, что неприятно. -
Вау! Так просто?! Т.е. забираю из буфера по мере использования, а заботиться о том, что он переполнится мне не надо? Так это же кайф! А то я приметила что флэшка (виртуальный диск) тоже начинает внезапно томозить, когда в нее закачиваешь длинный файл. Я еще сильно удивлялась, как ей удается сопротивляться внешнему накачиванию данными. Ведь у нее скорость записи медленнее, чем скорость передачи по USB2.0.