andreichk 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба поменял значение синуса.Результат- практически сплошной частокол.палки имеют разную высоту Илья, чем вы такие красивые графики строите? мне кажется , что некорректно выполняется функция Buf_FFT[k++]=pow((Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); В справке написано , что обе переменные должны быть float, а у нас только одна из них Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба Илья, чем вы такие красивые графики строите? Данные обсчитываю в программке которую написал вчера. А график строю в Excell мне кажется , что некорректно выполняется функция Buf_FFT[k++]=pow((Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); В справке написано , что обе переменные должны быть float, а у нас только одна из них Дык она должна ее автоматом во флоат переколбасить, или CCS и это не делает??? ЗЫ могу выслать программку с исходником. Если у вас есть Borland) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба автоматом нет наверное, но есть другой механизм приведения Buf_FFT[k++]=pow((float)(Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); я попробовал- толку мало борланд где-то валялся,не знаю теперь где он. а exe-шник отдельно от него работает? если да, то давайте Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба Вот программка: FFT.rar В левый столбец забейте исходный сигнал. Укажите N - число точек в сигнале (должно быть 2^n) Для подсчета нажмите CALC Программка слеплена за несколько минут, такчто извиняйте). Никаких защит от дурака в программке конечно нет, такчто следите за тем, что вы вводите. Программа специально все расчеты делает в unsigned int. Для того чтобы можно было сравнить с контроллером. Также перед выводом спектр нормируется на максимльное значение 230 Вот исходник: fftcpp.rar Найдите десять отличий) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба мысли поводу формулы Buf_FFT[k++]=pow((float)(Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); 255*255 + 255*255=130050 тут уже никакой int16 не справится, только Long или float скорее всего из-за этого на экране столько лишних палок Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба Тогда сделайте так: Buf_FFT[k++]=pow((float)(Buf_FFT)*Buf_FFT+(float)(Buf_FFT[i+1])*Buf_FFT[i+ 1],0.5); Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба так я уже пробовал, не помогает Значит проблема не в этом.... Как видите код абсолютно рабочий, неужели компилер гонит? Может в нем отключить какуюнибудь оптимизацию? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 11 апреля, 2008 Опубликовано 11 апреля, 2008 · Жалоба Считаю что нужно точно определиться с типами переменных и диапазоном их значений. Итак, 1. буфер Buf_FFT[256 или 512];//Global Buffers for FFT. Диапазон на входе- данные с порта от 0 до 240. Подходящие типы - unsigned int, unsigned int8 0-255, unsigned int16 0 to 65535, signed int16 -32768 to 32767, unsigned int32 0 to 4294967295, signed int32 -2147483648 to 2147483647 float32 -1.5 x 1045 to 3.4 x 1038 диапазон значений буфера после ДФТ realFFT(Buf_FFT,256 или 512); ????? диапазон значений буфера после Buf_float[k++]=pow((Buf_float*Buf_float+ Buf_float[i+1]*Buf_float[i+1]),0.5); ??? тоже тут Buf_FFT =226.0 - 190.0*Buf_float/max ; ??? Иначе получается полная ерунда, потому что ПИК где-то искажает результаты вычислений. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 12 апреля, 2008 Опубликовано 12 апреля, 2008 · Жалоба Ура !!!! Совершенно неожиданно нашёл решение проблемы. Самым подходящим типом переменных для буфера оказался signed int32 Buf_FFT[256]; // переобъявим массив как int32 -2147483648 to 2147483647 процедура void realFFT(signed int32 *a, unsigned int16 tnn) также приняла этот тип далее привожу полный текст рисования спектра и полученные фото 1. синус ( данные в тексте ) 2. меандр ( данные в тексте ) 3. реальный меандр 10 МГц void spectrum() { unsigned int16 i=0,k=0;float32 max=0.0, s=0.0; unsigned int8 x=1 , y , yy; for(i=0;i<256;i++){ #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm Buf_FFT[i] = input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm } //----------------------------------------------------------------------------- //for(i=0;i<256;i++){ // if (k<14) {Buf_FFT[i]=10;k++;} // else if (k<28) {Buf_FFT[i]=150;k++;} // else {Buf_FFT[i]=10;k=1;} // } //for(i=0;i<256;i++) // { // Buf_FFT[i]=120.0 - 100.0*(sin( s+=0.5)); // } realFFT(Buf_FFT,256);k=0; for(i=0;i<256;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<128;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<128;i++) Buf_FFT[i] =226.0 - 190.0*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой for(x=1;x<127;x++){ yy=y; y = Buf_FFT[x]; if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y);// Рисуем спад pixel(x,y,1); // Рисуем вершину } } //############################################## картинка получается хоть и немного бледноватой из-за частого обновления , но устойчивой. Единственное огорчение, это то, что её нельзя растянуть на весь экран из-за недостаточности объёма внутренней ОЗУ, но и на пол-экрана это уже замечательно. Хотя можно растянуть на весь экран, если изменить эти циклы for(i=0;i<256; i++ ){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<255;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<255;i++) Buf_FFT[i] =226.0 - 190.0*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой for(x=1;x<254;x++){ Как это выглядит, видно на последней фото реального меандра 10МГц Илье очередной :a14: и уважуха :beer: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 12 апреля, 2008 Опубликовано 12 апреля, 2008 · Жалоба Нашёл более удачный способ обновления экрана. Мерцание экрана исчезло и смена кадра происходит практически незаметно . Картинка стала ярче. void spectrum() { unsigned int16 i=0,k=0;float32 max=0.0, s=0.0; unsigned int8 x=1 , y , yy; for(i=0;i<256;i++){//переписываем порт в буфер #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm Buf_FFT[i] = input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm } realFFT(Buf_FFT,256);k=0;//вызываем ДТФ(FFT) for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<255;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<255;i++) Buf_FFT[i] =226.0 - 190.0*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой //-------------------- ОБНОВЛЕНИЕ ЭКРАНА --------------------------- setCursorAddress(0x2581); // чистить экран clear_graphic(); //-------------------- РИСОВАНИЕ --------------------------- for(x=1;x<254;x++){ yy=y; y = Buf_FFT[x]; if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y);// Рисуем спад pixel(x,y,1); // Рисуем вершину } }//--------------------------OK //################################################## Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 12 апреля, 2008 Опубликовано 12 апреля, 2008 · Жалоба Слышал я краем уха, что в спектроанализаторах, для того , чтобы повысить точность показаний и убрать ложные сигналы с экрана, применяют какие-то оконные процедуры. Что это за зверь такой ? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 12 апреля, 2008 Опубликовано 12 апреля, 2008 · Жалоба Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются "тонкие моменты".... я смотрю вы буфер переопределили как signed int32 Buf_FFT[256]; Следовательно половина циклов потеряло смысл... Во первых, я не понял от куда взялся цикл: for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Я, конечно понимаю, что может быть для некоторых сигналов такая обработка выглядит "красивее" но здравого смыла в ней нет!!!! Должно быть: for(i=0;i<255;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Короче, блин, я как всегда ПРОБУХАЛ все самое интересное..... И требую в студию последние варианты процедур, для очередной критики! ;) Слышал я краем уха, что в спектроанализаторах, для того , чтобы повысить точность показаний и убрать ложные сигналы с экрана, применяют какие-то оконные процедуры. Что это за зверь такой ? Есть такое, что конкретно хотите про это узнать??? ;) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 12 апреля, 2008 Опубликовано 12 апреля, 2008 · Жалоба Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются "тонкие моменты".... спасибо, а какие имено? я смотрю вы буфер переопределили как signed int32 Buf_FFT[256]; Следовательно половина циклов потеряло смысл... никакая другая размерность не прокатила.Размер буфера пришлось уменьшить наполовину и как следствие это for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } потому что с этим правая половина, начиная со 128 пикселя по горизонтали выглядит ужасно for(i=0;i<255;i+=2){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } такой цикл хорошо работал, когда я использовал для прорисовки только левую половину экрана, но поскольку я растянулся на весь экран , пришлось немножко извратиться.Но уверяю вас, всё выглядит в наилучшем виде. Есть такое, что конкретно хотите про это узнать??? ;) всё, что влезет в оставшиеся 4 кБ //#################################################################### // --------------- ЦИФРОВОЙ АНАЛИЗАТОР СПЕКТРА ---------------------- //Диапазон зависит от текущей частоты оцифровки (F) следующим образом: // от 0 до F/2 //промежуточные частоты равны: i*F/512, где 1<i<N/2 //#################################################################### void spectrum_analizator(void) // Рисуем спектр сигнала { unsigned int16 n=0;unsigned int8 amplitude; #asm BCF 0x0F8B,0 //Output_bit(PLCD_FIFO_RES,0);//PIN_C0 сброс FIFO в "0" BSF 0x0F8B,0 //Output_bit(PLCD_FIFO_RES,1);//PIN_C0 и разрешение на считывание BSF 0x0F8B,1 //Output_bit(READ_FIFO_B,1);//PIN_C1 запрет канала B #endasm //-------------------- синхронизация --------------------------- for(ever){ #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm amplitude=input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm amplitude = (amplitude > 200) ? 200 : amplitude; //ограничитель до выбранной величины amplitude = 255 - amplitude; // разворот на 180° по вертикали if (n++>MAXN) break;// В этой попытке смотреть дальше не имеет смысла if (syncA){//синхронизация по фронту A if(amplitude>sync_volume_A) continue; else break; }else{//синхронизация по спаду A if(amplitude<=sync_volume_A+115) continue; else break; } } spectrum();n=0;//Сюда попадем только если нашли фронт синхронизации }//--------------------------OK //#################################################################### void spectrum() { unsigned int16 i=0,k=0, max=0; unsigned int8 x=1 , y , yy; for(i=0;i<256;i++){//переписываем порт в буфер #asm BCF 0x0F8B,2//LATC2=0;//Output_bit(READ_FIFO_A ,0);//PIN_C2. разрешить #endasm Buf_FFT[i] = input_b(); //чтение порта В #asm BSF 0x0F8B,2//LATC2=1;//Output_bit(READ_FIFO_A ,1);//PIN_C2.запретить #endasm } realFFT(Buf_FFT,256);k=0;//вызываем ДПФ(FFT) for(i=0;i<256;i++){ Buf_FFT[k++]=pow((Buf_FFT[i]*Buf_FFT[i]+ Buf_FFT[i+1]*Buf_FFT[i+1]),0.5); } Buf_FFT[0]=Buf_FFT[1]; for(i=0;i<255;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i]; //ищем max for(i=0;i<255;i++) Buf_FFT[i] =226 - 190*Buf_FFT[i]/max;//нормировка по max, и инвертирование перед распечаткой //-------------------- ОБНОВЛЕНИЕ ЭКРАНА --------------------------- setCursorAddress(0x2581); // чистить экран clear_graphic(); //-------------------- РИСОВАНИЕ --------------------------- for(x=1;x<254;x++){ yy=y; y = Buf_FFT[x]; if (yy>y) front(x,yy,y);// Рисуем фронт if (yy<y) spad(x,yy,y);// Рисуем спад pixel(x,y,1); // Рисуем вершину } }//--------------------------OK //####################################### вот фото меандра 4 МГц. Внизу шкала, всё соответствует реалиям. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 13 апреля, 2008 Опубликовано 13 апреля, 2008 · Жалоба Вторая часть марлезонского балета http://ru.youtube.com/watch?v=x_T5DVZDE3w Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 14 апреля, 2008 Опубликовано 14 апреля, 2008 · Жалоба Насколько я понял, если теперь применить обратное преобразование Фурье, то можно восстановить и вывести на экран первоначальную форму сигнала? Если это так , то можно считать, что верхняя частота осциллографа поднимается до 40 МГц ? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться