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

SED1335,PIC18F4550 и LCD320x240

может я не прав, но мне кажется, что такие вычисления, вплоть до самого момента рисования, нужно производить только с переменными типа float, а не int.И только потом приводить их к int, иначе весь этот процесс округляется до невозможности.

Провёл все последние изменения- результат никакой, то есть никаких изменений :(

попробовал заменить процедуру ффт на всякие другие- тоже ничего не изменилось.

 

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

сдаётся мне, что этого как раз и не происходит,так как при закоментировании строки

//four2(Buf_FFT, 512, 0); в тестовой процедуре не приводит ни к каким изменениям.

вывод- обращение к процедуре преобразования не изменяет содержимое буфера :(

нужно копать глубже :help:

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


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

может я не прав, но мне кажется, что такие вычисления, вплоть до самого момента рисования, нужно производить только с переменными типа float, а не int.И только потом приводить их к int, иначе весь этот процесс округляется до невозможности.

Нет, у вас АЦП всего 8 разрядов. int предостаточно (тем более у вас памяти нехватит под массив float :) )

 

А вычистения для конкретной точки делаються во float

 

вывод- обращение к процедуре преобразования не изменяет содержимое буфера :(

Короче, если у вас такая хрень не проканает, то выкидывайте свой компилятор куда подальше:

 

void test(int *a){
   unsigned int i=0;
   for(i=0;i<256;i++){
      a[i]=100;
   }
}

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

    test(Buf_FFT);

    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);           // Рисуем вершину
    } 
}

 

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

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


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

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

void test(int *a){
   unsigned int16 i=0;float s=0;
   for(i=0;i<256;i++){
      a[i]=120 -  100.0*(sin( s+=0.1));
   }
}

левая половина синус 4 периода, правая меандр тоже 4 периода.Выкидывать или помучаемся ищо ? :07:

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


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

Синус нарисовался точно в центре экрана- 8 периодов. Выкидывать или помучаемся ищо ? :07:

Значит адресация работает...

 

Вы все-таки выложите процедуру realFFT() которая используется у вас на данный момент

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


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

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

void realFFT(int *a, unsigned int tnn)
{
    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; int tempr,tempi;
    if( tnn==1 )return;
    ttheta = 6.28318530717959/tnn;
    c1 = 0.5;
    c2 = -0.5;
    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;
    }
        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];
}

А теперь, у вас же есть возможность отладки программы, хотя бы в симуляторе? Давайте ставте breakpoint, и следите как выполняются операции в этой функции и изменяются ли данные в буффере

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


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

симулятор без подключения какой-то оригинальной хрени к ком или усб порту не работает

Я говорю не про "железный" отладчик (ICD 2). А про эмуляцию работу PICа вашим CCS. посмотрите, гденить наверное должна быть галочка для настройки.

 

Тогда просто делаете чтонить типа Set PC at Cursor напротив вызова функции testspectr(). А дальше по шагам...

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


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

да нету там нифига такого, я бы уже его давно обнаружил, обычно симулятор сидит на кнопках F7 F8.

ОЧЕНЬ ХРЕНОВО

 

Чтобы вым еще посоветовать....

 

у меня такое ощущение, что он вообще в этой процедуре какой-то хренью занимаеться... можно попробывать повставлять в разных местах процедуры RealFFT() return-ы и распечатывать на экран получившиеся данные...

 

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

 

короче нужно отлаживать ее как-то...

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


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

непонятки с размерностью некоторых переменных

realFFT(Buf_FFT, 512);

а в процедуре она unsigned int8

unsigned int8 занимает от 0 до 255, значит н и 512 ни 256 уже не катит, а 255 не кратно 2.Остаётся только одно макс.допустимое значение- 128. и при нём рисуется что-то отдалённо напоминающее спектр, но только при искусственном меандре.При заполнении буфера реальным сигналом от ФИФО- опять полная каша :help:

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


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

непонятки с размерностью некоторых переменных

realFFT(Buf_FFT, 512);

а в процедуре она unsigned int8

несколькими постами выше написано:

void realFFT(int *a, unsigned int tnn)

и где здесь unsigned int8???

 

unsigned int === WORD === 2 байта

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


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

Илья, 512 не попадает ни в инт ни в инт8(оба в CCS равнозначны, тоже с unsigned).

-127 +127 или 0-255 соотв.

в тестовой процедуре вызов такой realFFT(Buf_FFT, 512);unsigned int16 или просто int16.

в самой процедуре естьместо, где сравнивается 512 с переменной int (n = tnn;) фигня получается. я об этом

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


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

Илья, 512 не попадает ни в инт ни в инт8(оба в CCS равнозначны, тоже с unsigned).

Бред какой-то :07:

 

Тогда меняйте все int на signed int16

а все unsigned int на unsigned int16

 

Везде, включая определение массива Buf_FFT[]

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


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

Итак, при заданных параметрах меандра

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

получилась вот такая картинка. Во всяком случае видно, что есть привязка к начальному уровню и всплески имеют постояную амплитуду.

теперь о размерности переменных

void realFFT(signed int16  *a, unsigned int16 tnn)
{
    float twr,twi,twpr,twpi,twtemp,ttheta;
    signed int16 i,i1,i2,i3,i4;
    float c1, c2, h1r, h1i, h2r,h2i,wrs, wis;
    signed int16 nn,ii, jj,n, mmax, m,j,istep,isign;
    float wtemp, wr,wpr, wpi, wi,theta, tempr,tempi;

 

 

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

 

и процедура отрисовки целиком

 

unsigned int co=0;
void testspectr(unsigned int16 n)
{
   unsigned int16 i=0,k=0,max=0;float s=0;
   unsigned int8 x=1 , y , yy;

//   for(i=0;i<512;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 
//        }
//-----------------------------------------------------------------------------
co++;
if (co==2){
    setCursorAddress(0x2581); // чистить экран 
    clear_graphic();co=0;
    }

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;}
                  }
     //for(i=0;i<512;i++)
    // { 
    //  Buf_FFT[i]= 120 +  100.0*(sin( s+=0.02));
    // }

    realFFT(Buf_FFT, 512);

    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]=226.0 - (200.0*Buf_FFT[i]/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);           // Рисуем вершину
                   } 
}
//##########################################

правая картинка спектр-синуса(параметры в процедуре).

Палки какие-то частые.

Какие будут предложения?

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


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

Картина, все еще далека от нужной.

В спектре синуса должна быть только одна палка, а спектр меандра долен быть один в один как у меня.

 

Нашел косяк:

перед циклом

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

нужно занулить k:

k=0;

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


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

странно, но зануление никак не повлияло .Вернее совсем немножечко, в самом начале внизу слева, вместо сплошняка палка вниз до начального уровня.

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


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

странно, но зануление никак не повлияло .

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

 

Для синуса, вы мало чего увидите, т.к. слишком низкая частота. Картинка вот:

post-11630-1207900524_thumb.jpg

 

Сделайте частоту повыше:

120 + 100.0*(sin( s+=0.5));

Должно получиться вот так:

post-11630-1207900558_thumb.jpg

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


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

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