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

SED1335,PIC18F4550 и LCD320x240

Во первых уберите [x] при вызове функции

а во вторых, я уже исправил предыдущий пост, нужно сделать так:

four2(Buf_FFT,128,1)

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


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

всё исправил, но всё равно рисует просто кривую

еще раз посмотрел на вашу функцию four2(),

во первых это опять функция для комплексного преобразования фурье, вам нужно преобразование для реальных чисел (гдето раньше вы уже выкладывали нужную процедуру)

 

Хотя... лучше возьмите вот эту:

void realFFT(float a[], unsigned int tnn, char inversefft)
{
    float twr,twi,twpr,twpi,twtemp,ttheta;
    int i,i1,i2,i3,i4;
    float c1, c2, h1r, h1i, h2r,h2i,wrs, wis;
    int nn,ii, jj,n, mmax, m,j,istep,isign;
    float wtemp, wr,wpr, wpi, wi,theta,tempr,tempi;
    if( tnn==1 )return;
    if( !inversefft ){
        ttheta = 6.28318530717959/tnn;
        c1 = 0.5;
        c2 = -0.5;
    }else{
        ttheta = 6.28318530717959/tnn;
        c1 = 0.5;
        c2 = 0.5;
        ttheta = -ttheta;
        twpr = -2.0*(sin(0.5*ttheta))*(sin(0.5*ttheta));
        twpi = sin(ttheta);
        twr = 1.0+twpr;
        twi = twpi;
        for(i = 2; i <= tnn/4+1; i++){
            i1 = i+i-2;
            i2 = i1+1;
            i3 = tnn+1-i2;
            i4 = i3+1;
            wrs = twr;
            wis = twi;
            h1r = c1*(a[i1]+a[i3]);
            h1i = c1*(a[i2]-a[i4]);
            h2r = -c2*(a[i2]+a[i4]);
            h2i = c2*(a[i1]-a[i3]);
            a[i1] = h1r+wrs*h2r-wis*h2i;
            a[i2] = h1i+wrs*h2i+wis*h2r;
            a[i3] = h1r-wrs*h2r+wis*h2i;
            a[i4] = -h1i+wrs*h2i+wis*h2r;
            twtemp = twr;
            twr = twr*twpr-twi*twpi+twr;
            twi = twi*twpr+twtemp*twpi+twi;
        }
        h1r = a[0];
        a[0] = c1*(h1r+a[1]);
        a[1] = c1*(h1r-a[1]);
    }
    if( inversefft ) isign = -1;
    else isign = 1;
    n = tnn;
    nn = tnn/2;
    j = 1;
    for(ii = 1; ii <= nn; ii++)
    {
        i = 2*ii-1;
        if( j>i )
        {
            tempr = a[j-1];
            tempi = a[j];
            a[j-1] = a[i-1];
            a[j] = a[i];
            a[i-1] = tempr;
            a[i] = tempi;
        }
        m = n/2;
        while(m>=2&&j>m)
        {
            j = j-m;
            m = m/2;
        }
        j = j+m;
    }
    mmax = 2;
    while(n>mmax)
    {
        istep = 2*mmax;
        theta = 6.28318530717959/(isign*mmax);
        wpr = -2.0*(sin(0.5*theta))*(sin(0.5*theta));
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for(ii = 1; ii <= mmax/2; ii++)
        {
            m = 2*ii-1;
            for(jj = 0; jj <= (n-m)/istep; jj++)
            {
                i = m+jj*istep;
                j = i+mmax;
                tempr = wr*a[j-1]-wi*a[j];
                tempi = wr*a[j]+wi*a[j-1];
                a[j-1] = a[i-1]-tempr;
                a[j] = a[i]-tempi;
                a[i-1] = a[i-1]+tempr;
                a[i] = a[i]+tempi;
            }
            wtemp = wr;
            wr = wr*wpr-wi*wpi+wr;
            wi = wi*wpr+wtemp*wpi+wi;
        }
        mmax = istep;
    }
    if( inversefft )
    {
        for(i = 1; i <= 2*nn; i++)
        {
            a[i-1] = a[i-1]/nn;
        }
    }
    if( !inversefft )
    {
        twpr = -2.0*(sin(0.5*ttheta))*(sin(0.5*theta));
        twpi = sin(ttheta);
        twr = 1.0+twpr;
        twi = twpi;
        for(i = 2; i <= tnn/4+1; i++)
        {
            i1 = i+i-2;
            i2 = i1+1;
            i3 = tnn+1-i2;
            i4 = i3+1;
            wrs = twr;
            wis = twi;
            h1r = c1*(a[i1]+a[i3]);
            h1i = c1*(a[i2]-a[i4]);
            h2r = -c2*(a[i2]+a[i4]);
            h2i = c2*(a[i1]-a[i3]);
            a[i1] = h1r+wrs*h2r-wis*h2i;
            a[i2] = h1i+wrs*h2i+wis*h2r;
            a[i3] = h1r-wrs*h2r+wis*h2i;
            a[i4] = -h1i+wrs*h2i+wis*h2r;
            twtemp = twr;
            twr = twr*twpr-twi*twpi+twr;
            twi = twi*twpr+twtemp*twpi+twi;
        }
        h1r = a[0];
        a[0] = h1r+a[1];
        a[1] = h1r-a[1];
    }
}

вызывайте ее так:

realFFT(Buf_FFT, 256, 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]=0;

 

Затем распечатайте на экран первые 128 значений буффера

 

Только перед распечаткой нужно еще пронормировать на максимальное значение (чтобы было равно высоте экрана)

 

Да, еще старайтесь чтобы на экран умещалось побольше периодов сигнала, чтобы лучше увидеть пик

 

 

 

Кстати, почитайте, очень похожий проект:

http://rf.atnn.ru/s10/digital_osc.html

 

там и про FFT че-то написано, даже есть исходник в низу страницы.

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


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

экран замирает и ничего не происходит :07:

void spectrum_analizator(unsigned int8 y_pos)
{unsigned int8 x=0,y,yy,k=0,i=0;unsigned int16 n=0;
//-----------------------------------------------------------------------------        
      if (n++>8192){// Если дошли до сюда, значит не удалось найти период
      return;// Занулим частоту (типа не посчитали... )
      }  
//-----------------------------------------------------------------------------
for(x=0;x<255;x++){
    #asm
       BCF 0x0F8B,2//LATC2=0;
    #endasm
      Buf[x]=255 - input_b(); //чтение порта В 
    #asm
      BSF 0x0F8B,2//LATC2=1;
    #endasm 
}
for(x=0;x<255;x++){
      Buf_FFT[x]=Buf[x];// 
      
}
realFFT(Buf_FFT, 256, 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]=0;

for(x=0;x<128;x++){
         yy=y;
         y = Buf_FFT[x] + y_pos;//
         y = (y > 200) ? 200 : y; //ограничитель до выбранной величины
         if (yy>y) front(x,yy,y);// Рисуем фронт  
         if (yy<y) spad(x,yy,y); // Рисуем спад  
         pixel(x,y,1);           // Рисуем вершину
         
               } 
  setCursorAddress(0x2581);
  clear_graphic();
}
//#########################################

 

закрыл это- опять стала рисовать просто импульсы

//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);
//}

 

изменил размерность переменной i на unsigned int16- на экране появились импульсы в два раза уже , чем обычные и прим. на одну треть выше

Изменено пользователем andreichk

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


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

Что-то вы шаманством каким-то занимаетесь... :(

 

Не вижу у вас нормировки сигнала....

 

Давайте сделаем так:

signed int16 Buf_FFT[512]; // переобъявим массив как int

void spectrum_analizator(void)
{
    unsigned int8 x=0,y,yy;
    unsigned int16 i=0,max=0,k=0;

    setCursorAddress(0x2581); //Я так понимаю чистить экран нужно перед отрисовкой а не после...
    clear_graphic();

    #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(i=0;i<512;i++){
        #asm
               BCF 0x0F8B,2//LATC2=0;
        #endasm
          Buf_FFT[i]=input_b(); //чтение порта В 
        #asm
              BSF 0x0F8B,2//LATC2=1;
        #endasm 
    }
    realFFT(Buf_FFT, 512, 0);
    for(i=0;i<512;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]=0;
    for(i=0;i<256;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i];    // ищем max
    for(i=0;i<256;i++) Buf_FFT[i]=236-(Buf_FFT[i]*230/max);  //нормировка по max, и инвертирование перед распечаткой
    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);           // Рисуем вершину
    } 
}

а процедуру realFFT переобъявим следующим образом:

void realFFT(signed int16 a[], unsigned int tnn, char inversefft)

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


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

по-прежнему просто узкие , но очень большие по аплитуде импульсы. Они теперь даже не влезают в экран.

зы.я не шаман,теперь я как все зелёный человечек.

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


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

по-прежнему просто узкие , но очень большие по аплитуде импульсы. Они теперь даже не влезают в экран.

зы.я не шаман,теперь я как все зелёный человечек.

 

 

Хачу видеть 2 картинки - исходного сигнала и его спектра. Не меняя частоту тактирования FIFO.

 

Сделайте так чтобы на экран при этом входило периодов 8 примерно

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


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

выставил сейчас прямоугольники 400кГц, развёртка на 3.2мксек.амплитуда прим. 3 вольта

одно могу сказать пока, они в два раза Уже и по аплитуде скачут то вверх, то вниз.Рисуются медленней и плохо синхронизируются как в режиме спектра, так и в осциллографическом.

 

вот и фотки

1 скоп

2 спектр

 

хачу таааак :crying:

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


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

выставил сейчас прямоугольники 400кГц, развёртка на 3.2мксек.амплитуда прим. 3 вольта

одно могу сказать пока, они в два раза Уже и по аплитуде скачут то вверх, то вниз.Рисуются медленней и плохо синхронизируются как в режиме спектра, так и в осциллографическом.

 

вот и фотки

1 скоп

2 спектр

 

хачу таааак :crying:

 

Да это у вас совсем не спектр... :(

 

Приведите в итоге весь цикл как вы получаете и отрисовываете спектр.

 

Не понял что значит рисуется медленней? У вас чтоли одновременно и спектр и сигнал рисуется, или я че-то не догоняю....

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


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

вызываем процедуру

void spectr_A(unsigned int8 y_pos_A)

 

void spectr_A(unsigned int8 y_pos_A) // пытаемся нарисовать спектр
{  unsigned int16 n=0,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_analizator(y_pos_A,n);//Сюда попадем только если нашли фронт синхронизации
}//--------------------------OK
//####################################################################
void spectrum_analizator(unsigned int8 y_pos,unsigned int16 n)
{
    unsigned int8 x=0,y,yy;
    unsigned int16 i=0,max=0,k=0;
//-----------------------------------------------------------------------------        
      if (n++>8192){// Если дошли до сюда, значит не удалось найти период
      return;// Занулим частоту (типа не посчитали... )
      }  
//-----------------------------------------------------------------------------


    #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(i=0;i<512;i++){
        #asm
               BCF 0x0F8B,2//LATC2=0;
        #endasm
          Buf_FFT[i]=input_b(); //чтение порта В 
        #asm
              BSF 0x0F8B,2//LATC2=1;
        #endasm 
    }
    realFFT(Buf_FFT, 512, 0);
    for(i=0;i<512;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]=0;
    for(i=0;i<256;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i];  //ищем max
    for(i=0;i<256;i++) Buf_FFT[i]=236-(Buf_FFT[i]*230/max);//нормировка по max, и инвертирование перед распечаткой
    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);           // Рисуем вершину
    } 
    setCursorAddress(0x2581); // чистить экран 
    clear_graphic();
}

 

ну насчёт медленнее рисует-это я наверное погорячился.просто чем больше развёртка, тем медленнее рисует. или чем больше элементов для рисования, тем больше времени на это требуется.

 

#define EVER ;; //приколы нашего двора

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


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

Так, на вид, почти все нормально. Но давайте для на чала отладим сам алгоритм FFT.

 

Для этого сделаем тестовую процедуру, и заполним массив известным меандром:

(я специально взял такой период (28 отсчетов) чтобы в 512 отсчетов не укладывалось ровное число периодов, иначе картинка будет слишком красивая, и далекая от реальности)

void testspectr(void)
{
    unsigned int8 x=0,y,yy;
    unsigned int16 i=0,max=0,k=0;

    setCursorAddress(0x2581); // чистить экран 
    clear_graphic();

     for(i=0;i<512;i++){
      if (k<14) {Buf_FFT[i]=10;k++;}
      else if(k<28) {Buf_FFT[i]=230;k++;}
      else {Buf_FFT[i]=10;k=1;}
    }

    realFFT(Buf_FFT, 512, 0);
    for(i=0;i<512;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<256;i++) if(Buf_FFT[i]>max) max=Buf_FFT[i];  //ищем max
    for(i=0;i<256;i++) Buf_FFT[i]=236-(Buf_FFT[i]*230/max);//нормировка по max, и инвертирование перед распечаткой
    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);           // Рисуем вершину
    } 
}

 

Я специально не поленился, и написал программку для Borland. Все один в один.

Получились следующие картинки:

 

СИГНАЛ:

post-11630-1207709614_thumb.jpg

СПЕКТР:

post-11630-1207709678_thumb.jpg

 

P.S. Хочу посмотреть что получиться у вас ;)

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


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

фотки пока нет.

график представляет из себя следующее, слева-направо с отступом от лев.края в 10 пикселей длинная закрашенная палка на весь экран толщиной в 4 пикселя,далее 17 прямоугольников при по 8 пикселей шапка 8 пикселей яма . Всё это рисуется от самого низа экрана

 

Что-то по описанию явно бред какой-то..... :wacko: приведите еще раз ф-ию realFFT();

 

Просто, не понятно в чем косяк - процедурка то ведь рабочая. Я же проверил...

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


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

первое фото было получено при обозначении процедуры

void realFFT(char *a, unsigned int tnn, char inversefft)

а второе при

void realFFT(signed int16 a[] , unsigned int tnn, char inversefft)

в обоих случаях это мало похоже на ожидаемый результат

 

при более детальном рассмотрении второго графика я замечаю интересный момент- мне кажется что первые 4 или 5 всплесков отрисовались в области первых 16ти пикселей, начиная от левого края, но почему-то каждый последующий начинался не с низу, а от какого-то другого значения.Остальной меандр- это просто мусор какой-то

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


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

я тут подумал и мы решили, а вообще в каком диапазоне частот работает наш спектроскоп?

И ещё вопрос- как эта функция передаёт значения в буфер?

void realFFT(signed int16 a[] , unsigned int tnn, char inversefft)

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


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

Да... такое ощущение что у вас вообще буфер не обрабатывается....

 

первое фото было получено при обозначении процедуры

void realFFT(char *a, unsigned int tnn, char inversefft)

Так точно не правильно, лучше попробывать так:

void realFFT(int *a, unsigned int tnn, char inversefft)

 

еще в функции realFFT() есть цикл:

while(m>=2&&j>m)

попробуйте заменить на:

while((m>=2)&&(j>m))

 

также в процедуре есть float переменные tempr и tempi. сделайте их int:

int tempr,tempi;

 

я тут подумал и мы решили, а вообще в каком диапазоне частот работает наш спектроскоп?

Диапазон зависит от текущей частоты оцифровки (F) следующим образом:

от 0 до F/2

 

промежуточные частоты равны: i*F/512, где 1<i<N/2

 

И ещё вопрос- как эта функция передаёт значения в буфер?

void realFFT(signed int16 a[] , unsigned int tnn, char inversefft)

Мы же ей передаем указатель на начало буфера. она присваивает его a. А дальше тупо обращается по индексам...

 

А вообще грешить помоему уже надо на компилятор.... все-таки приведите текст вашей realFFT() может че-то в ней случайно изменилось.

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


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

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