Перейти к содержанию
    

SED1335,PIC18F4550 и LCD320x240

поменял значение синуса.Результат- практически сплошной частокол.палки имеют разную высоту

 

Илья, чем вы такие красивые графики строите?

 

мне кажется , что некорректно выполняется функция

Buf_FFT[k++]=pow((Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5);

В справке написано , что обе переменные должны быть float, а у нас только одна из них

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Илья, чем вы такие красивые графики строите?

 

Данные обсчитываю в программке которую написал вчера. А график строю в Excell

 

 

мне кажется , что некорректно выполняется функция

Buf_FFT[k++]=pow((Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5);

В справке написано , что обе переменные должны быть float, а у нас только одна из них

Дык она должна ее автоматом во флоат переколбасить, или CCS и это не делает???

 

 

ЗЫ могу выслать программку с исходником. Если у вас есть Borland)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

автоматом нет наверное, но есть другой механизм приведения

Buf_FFT[k++]=pow((float)(Buf_FFT*Buf_FFT+Buf_FFT[i+1]*Buf_FFT[i+1]),0.5);

я попробовал- толку мало

борланд где-то валялся,не знаю теперь где он. а exe-шник отдельно от него работает? если да, то давайте

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот программка:

FFT.rar

 

В левый столбец забейте исходный сигнал.

Укажите N - число точек в сигнале (должно быть 2^n)

Для подсчета нажмите CALC

 

Программка слеплена за несколько минут, такчто извиняйте). Никаких защит от дурака в программке конечно нет, такчто следите за тем, что вы вводите.

 

Программа специально все расчеты делает в unsigned int. Для того чтобы можно было сравнить с контроллером. Также перед выводом спектр нормируется на максимльное значение 230

 

 

Вот исходник:

fftcpp.rar

Найдите десять отличий)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мысли поводу формулы

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

скорее всего из-за этого на экране столько лишних палок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так я уже пробовал, не помогает

Значит проблема не в этом.... Как видите код абсолютно рабочий, неужели компилер гонит? Может в нем отключить какуюнибудь оптимизацию?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Считаю что нужно точно определиться с типами переменных и диапазоном их значений.

Итак,

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 ; ???

Иначе получается полная ерунда, потому что ПИК где-то искажает результаты вычислений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ура !!!! Совершенно неожиданно нашёл решение проблемы.

Самым подходящим типом переменных для буфера оказался

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:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашёл более удачный способ обновления экрана.

Мерцание экрана исчезло и смена кадра происходит практически незаметно . Картинка стала ярче.

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
//##################################################

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Слышал я краем уха, что в спектроанализаторах, для того , чтобы повысить точность показаний и убрать ложные сигналы с экрана, применяют какие-то оконные процедуры. Что это за зверь такой ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются

"тонкие моменты"....

 

я смотрю вы буфер переопределили как 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);
}

 

Короче, блин, я как всегда ПРОБУХАЛ все самое интересное..... И требую в

студию последние варианты процедур, для очередной критики! ;)

 

Слышал я краем уха, что в спектроанализаторах, для того , чтобы повысить точность показаний и убрать ложные сигналы с экрана, применяют какие-то оконные процедуры. Что это за зверь такой ?

Есть такое, что конкретно хотите про это узнать??? ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень рад за вас, что у вас хоть что-то получилось, но все равно остаются
"тонкие моменты"....

спасибо, а какие имено?

 

я смотрю вы буфер переопределили как 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 МГц. Внизу шкала, всё соответствует реалиям.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понял, если теперь применить обратное преобразование Фурье, то можно восстановить и вывести на экран первоначальную форму сигнала? Если это так , то можно считать, что верхняя частота осциллографа поднимается до 40 МГц ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...