اطلاعیه

Collapse
No announcement yet.

نمونه برداری از ADC با مدت زمان طولانی

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    نمونه برداری از ADC با مدت زمان طولانی

    با سلام.
    وقت همگی به خیر.
    من میخوام از ADC با فرکانس نمونه برداری 10 الی 20 کیلو هرتز نمونه برداری کنم و مدت زمان مثلا یک الی چند دقیقه و نمونه ها در کارت SD ذخیره بشه و بعد برای پردازش به متلب انتقال داده بشه. حقیقتش میکرو مورد استفاده DSP هست ولی چون انجمن DSP دیگه تقریبا فعالیتی نداره گفتم اینجا بپرسم شاید که بهتر بشه کمک کرد.
    الان مشکلی که دارم اینه که نرخ نمونه برداری درست نیست و یک سری از داده ها از دست میره.
    کد نوشته شده :


    #include "F28x_Project.h"
    #include "fatfs/src/ff.h"
    #include "fatfs/src/diskio.h"
    #include "fatfs/src/integer.h"




    #define numsample 1 // number of ADC sample




    void configuretimer1 (void);
    void configureADC (void);
    interrupt void adca1_isr (void);


    unsigned char Buf1[512],Buf2[512];//adc1[20],adc2[20],adc3[20]; // result of adc conversion
    uint16_t i=0,j=0;
    uint32_t counter=0;
    FATFS fs;
    FIL fp;
    WORD btw = 200; //Number of bytes to write
    WORD bw; //Pointer to number of bytes written


    unsigned char Buf1Full = 'N';
    unsigned char Buf2Full = 'N';




    void main(void)
    {
    FRESULT Fres;
    InitSysCtrl();
    DINT; // disable global interrupt
    InitPieCtrl();


    InitPieVectTable();






    EALLOW;
    PieVectTable.ADCA1_INT = &adca1_isr;
    EDIS;
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
    IER |= M_INT1; //Enable group 1 interrupts
    EINT;


    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;


    // set gpio31 as GPIO
    GpioCtrlRegs.GPAGMUX2.bit.GPIO22 = 0;
    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 0;


    // set GPIO31 as output
    EALLOW;
    GpioCtrlRegs.GPADIR.bit.GPIO22 = 1;
    EDIS;


    while(disk_initialize(0) == STA_NOINIT);
    Fres = f_mount(0,&fs);
    while( Fres != FR_OK);
    Fres = f_open(&fp, "ADC.txt", FA_CREATE_ALWAYS | FA_WRITE);
    while( Fres != FR_OK);


    /*Fres = f_lseek(&fp,10485760);
    while( Fres != FR_OK);
    Fres = f_lseek(&fp, 0);
    while( Fres != FR_OK);*/


    configureADC();
    configuretimer1();


    while(1)
    {
    if (Buf1Full == 'Y')
    {


    //GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;
    f_write(&fp,Buf1, sizeof(Buf1), &bw);
    Buf1Full = 'N';
    //GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;
    //counter++;


    }
    else if (Buf2Full == 'Y')
    {
    f_write(&fp,Buf2, sizeof(Buf2), &bw);
    Buf2Full = 'N';
    counter++;


    }
    if (counter == 2*numsample)
    {
    f_close(&fp);
    asm(" ESTOP0");
    }
    }
    }






    void configuretimer1 (void)
    {
    CpuTimer1Regs.TCR.bit.TIE = 1; // enable timer1 interrupt
    CpuTimer1Regs.TCR.bit.FREE = 1; // FREE:SOFT = 3 for free runs
    CpuTimer1Regs.TCR.bit.SOFT = 1;
    CpuTimer1Regs.TPRH.bit.TDDRH = 0; // TDDRH:TDDR = 9 ----> prescaler = 10
    CpuTimer1Regs.TPR.bit.TDDR = 9;


    CpuTimer1Regs.PRD.all = 60; // 60 : 3000 nsec = 3 usec


    CpuTimer1Regs.TCR.bit.TSS = 0; // start counting
    }


    void configureADC (void)
    {
    EALLOW;
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
    AdcbRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
    AdccRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
    AdcdRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);
    AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);


    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion
    AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion
    AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion


    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCA
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCB
    AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCC
    AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCD


    DELAY_US(1000); //////////////////////delay for 1ms to allow ADC time to power up


    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCINA2 - ADCINA3
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCINB2
    AdccRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCINC2
    AdcdRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCIND2


    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec
    AdccRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec
    AdcdRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec


    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 2;
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 2;
    AdccRegs.ADCSOC0CTL.bit.TRIGSEL = 2;
    AdcdRegs.ADCSOC0CTL.bit.TRIGSEL = 2;


    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;//end of SOC0 will set ADCINT1 flag


    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag


    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//make sure INT1 flag is cleared


    EDIS;
    }




    interrupt void adca1_isr (void)
    {
    //GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;


    static unsigned int m = 0;
    m++;
    if(/*i <= 510 &&*/ Buf1Full == 'N' )
    {
    //m++;
    Buf1[i++] = m;
    Buf1[i++] = m>>8;


    if(i == 512)
    {
    j=0;
    Buf1Full = 'Y';
    }


    }


    else if (/*j <= 510 &&*/ Buf2Full == 'N' )
    {
    //m++;
    Buf2[j++] = m;
    Buf2[j++] = m>>8;


    if(j == 512)
    {
    i=0;
    Buf2Full = 'Y';
    }


    }


    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;


    }



    توضیح کد :
    دو تا بافر تعریف کردم که ابتدا اولی پر بشه و بعدش دومی توی حلقه while هم میاد چک میکنه که اگر بافر ها کامل پر شدن اون وقت شروع به نوشتن در داخل کارت SD میکنیم. الان همون طور که در ادامه عکسش رو گذاشتم یک سری از داده ها نوشته نمیشه و عملا مشکل داره . علتش هم فکر کنم این باشه که زمان نوشتن داخل کارت SD خیلی طولانی هست. چون متغیر m اضافه شده ولی داخل بافر ها نوشته نشده . میخواستم ببینم راه کاری برای رفع این مشکل هست یا نه ؟ توی این برنامه فرکانس نمونه برداری خیلی زیاده ولی وقتی کمش هم میکنم باز همین مشکل رو دارم. در واقع میخوام ببینم این الگوریتم خوبه یا اینکه الگوریتم رو باید عوض کرد . ممنون میشم راهنمایی کنید.
    اینم از عکس محتویات کارت SD که اعداد ناگهانی پرش میکنند.

    این رو هم اضافه کنم که علت شیفت به راست اعدا اینه که متغیر unsigned char در این سری از dsp هشت بیتی هست و برای نوشتن روی کارت SD باید 8 بیت بالا و پایین را توی دو تا خونه جداگانه نوشت.
    خیلی ممنون.

    #2
    پاسخ : نمونه برداری از ADC با مدت زمان طولانی

    من اینکارو برای پایان نامه م با ارزونترین میکروی STM32F0 انجام دادم برا پردازش صدا. نرخ نمونه برداری 16 کیلوهرتز، پنجره hann و فیلتر pre-emphasize روی 20000نمونه (1.25 ثانیه). البته محدودیتی نداره. میتونه مداوم استریم هم بکنه. همه رو میفرسته رو یوآرت که تو متلب تست میکردم.
    جالب اینکه میکرو فقط 4 کیلوبایت رم داره، ضرب کننده هم نداره چه برسه واحد محاسبات اعشار و دستورالعمل های SIMD. به هر حال اگر خواستید سویچ کنید به کورتکس من کاری از دستم بربیاد در خدمتم
    Si vis pacem, para bellum

    دیدگاه


      #3
      پاسخ : نمونه برداری از ADC با مدت زمان طولانی

      نوشته اصلی توسط tiranoid نمایش پست ها
      من اینکارو برای پایان نامه م با ارزونترین میکروی STM32F0 انجام دادم برا پردازش صدا. نرخ نمونه برداری 16 کیلوهرتز، پنجره hann و فیلتر pre-emphasize روی 20000نمونه (1.25 ثانیه). البته محدودیتی نداره. میتونه مداوم استریم هم بکنه. همه رو میفرسته رو یوآرت که تو متلب تست میکردم.
      جالب اینکه میکرو فقط 4 کیلوبایت رم داره، ضرب کننده هم نداره چه برسه واحد محاسبات اعشار و دستورالعمل های SIMD. به هر حال اگر خواستید سویچ کنید به کورتکس من کاری از دستم بربیاد در خدمتم
      خیلی ممنون از توضیحتون.
      ولی مشکل اینه که بورد تهیه شده و پروژه کاملا صنعتی است و این بخشی از پروژه هست که باید از سیگنال موتور نمونه برداری شود و بعدا برای خطایابی مورد استفاده قرار گیرد و نهایتا قراره برای هر موتور یکی از این بورد ها گذاشته بشه و اپراتور هر وقت خواست شروع به نمونه برداری کنه. و ستگاه پورتابل باشه.
      فکر کنم تا حد خوبی مشکل رو رفع کردم .
      الان برای تست میخوام یک ارایه بزرگ اعداد ( از 0 تا 65535 ) رو بدم به متلب و ببینم که این اعداد دارای فاصله مساوی ( برابر 1 ) هستند یا نه ؟
      اگر در این زمینه میتونید کمک کنید خیلی ممنون میشم.
      خیلی لطف کردید.

      دیدگاه


        #4
        پاسخ : نمونه برداری از ADC با مدت زمان طولانی

        نوشته اصلی توسط saati.sms نمایش پست ها
        با سلام.
        وقت همگی به خیر.
        من میخوام از ADC با فرکانس نمونه برداری 10 الی 20 کیلو هرتز نمونه برداری کنم و مدت زمان مثلا یک الی چند دقیقه و نمونه ها در کارت SD ذخیره بشه و بعد برای پردازش به متلب انتقال داده بشه. حقیقتش میکرو مورد استفاده DSP هست ولی چون انجمن DSP دیگه تقریبا فعالیتی نداره گفتم اینجا بپرسم شاید که بهتر بشه کمک کرد.
        الان مشکلی که دارم اینه که نرخ نمونه برداری درست نیست و یک سری از داده ها از دست میره.
        کد نوشته شده :


        #include "F28x_Project.h"
        #include "fatfs/src/ff.h"
        #include "fatfs/src/diskio.h"
        #include "fatfs/src/integer.h"




        #define numsample 1 // number of ADC sample




        void configuretimer1 (void);
        void configureADC (void);
        interrupt void adca1_isr (void);


        unsigned char Buf1[512],Buf2[512];//adc1[20],adc2[20],adc3[20]; // result of adc conversion
        uint16_t i=0,j=0;
        uint32_t counter=0;
        FATFS fs;
        FIL fp;
        WORD btw = 200; //Number of bytes to write
        WORD bw; //Pointer to number of bytes written


        unsigned char Buf1Full = 'N';
        unsigned char Buf2Full = 'N';




        void main(void)
        {
        FRESULT Fres;
        InitSysCtrl();
        DINT; // disable global interrupt
        InitPieCtrl();


        InitPieVectTable();






        EALLOW;
        PieVectTable.ADCA1_INT = &adca1_isr;
        EDIS;
        PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
        IER |= M_INT1; //Enable group 1 interrupts
        EINT;


        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1;


        // set gpio31 as GPIO
        GpioCtrlRegs.GPAGMUX2.bit.GPIO22 = 0;
        GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 0;


        // set GPIO31 as output
        EALLOW;
        GpioCtrlRegs.GPADIR.bit.GPIO22 = 1;
        EDIS;


        while(disk_initialize(0) == STA_NOINIT);
        Fres = f_mount(0,&fs);
        while( Fres != FR_OK);
        Fres = f_open(&fp, "ADC.txt", FA_CREATE_ALWAYS | FA_WRITE);
        while( Fres != FR_OK);


        /*Fres = f_lseek(&fp,10485760);
        while( Fres != FR_OK);
        Fres = f_lseek(&fp, 0);
        while( Fres != FR_OK);*/


        configureADC();
        configuretimer1();


        while(1)
        {
        if (Buf1Full == 'Y')
        {


        //GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;
        f_write(&fp,Buf1, sizeof(Buf1), &bw);
        Buf1Full = 'N';
        //GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;
        //counter++;


        }
        else if (Buf2Full == 'Y')
        {
        f_write(&fp,Buf2, sizeof(Buf2), &bw);
        Buf2Full = 'N';
        counter++;


        }
        if (counter == 2*numsample)
        {
        f_close(&fp);
        asm(" ESTOP0");
        }
        }
        }






        void configuretimer1 (void)
        {
        CpuTimer1Regs.TCR.bit.TIE = 1; // enable timer1 interrupt
        CpuTimer1Regs.TCR.bit.FREE = 1; // FREE:SOFT = 3 for free runs
        CpuTimer1Regs.TCR.bit.SOFT = 1;
        CpuTimer1Regs.TPRH.bit.TDDRH = 0; // TDDRH:TDDR = 9 ----> prescaler = 10
        CpuTimer1Regs.TPR.bit.TDDR = 9;


        CpuTimer1Regs.PRD.all = 60; // 60 : 3000 nsec = 3 usec


        CpuTimer1Regs.TCR.bit.TSS = 0; // start counting
        }


        void configureADC (void)
        {
        EALLOW;
        AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
        AdcbRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
        AdccRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
        AdcdRegs.ADCCTL2.bit.PRESCALE = 6; // ADCCLK = input clock/1
        AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);
        AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
        AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
        AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);


        AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion
        AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion
        AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion
        AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1; //Interrupt pulse generation occurs at the end of the conversion


        AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCA
        AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCB
        AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCC
        AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1; // power on ADCD


        DELAY_US(1000); //////////////////////delay for 1ms to allow ADC time to power up


        AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCINA2 - ADCINA3
        AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCINB2
        AdccRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCINC2
        AdcdRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert ADCIND2


        AdcaRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec
        AdcbRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec
        AdccRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec
        AdcdRegs.ADCSOC0CTL.bit.ACQPS = 19; // acquisition window = 100 nsec


        AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 2;
        AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 2;
        AdccRegs.ADCSOC0CTL.bit.TRIGSEL = 2;
        AdcdRegs.ADCSOC0CTL.bit.TRIGSEL = 2;


        AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;//end of SOC0 will set ADCINT1 flag


        AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag


        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//make sure INT1 flag is cleared


        EDIS;
        }




        interrupt void adca1_isr (void)
        {
        //GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;


        static unsigned int m = 0;
        m++;
        if(/*i <= 510 &&*/ Buf1Full == 'N' )
        {
        //m++;
        Buf1[i++] = m;
        Buf1[i++] = m>>8;


        if(i == 512)
        {
        j=0;
        Buf1Full = 'Y';
        }


        }


        else if (/*j <= 510 &&*/ Buf2Full == 'N' )
        {
        //m++;
        Buf2[j++] = m;
        Buf2[j++] = m>>8;


        if(j == 512)
        {
        i=0;
        Buf2Full = 'Y';
        }


        }


        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;


        }



        توضیح کد :
        دو تا بافر تعریف کردم که ابتدا اولی پر بشه و بعدش دومی توی حلقه while هم میاد چک میکنه که اگر بافر ها کامل پر شدن اون وقت شروع به نوشتن در داخل کارت SD میکنیم. الان همون طور که در ادامه عکسش رو گذاشتم یک سری از داده ها نوشته نمیشه و عملا مشکل داره . علتش هم فکر کنم این باشه که زمان نوشتن داخل کارت SD خیلی طولانی هست. چون متغیر m اضافه شده ولی داخل بافر ها نوشته نشده . میخواستم ببینم راه کاری برای رفع این مشکل هست یا نه ؟ توی این برنامه فرکانس نمونه برداری خیلی زیاده ولی وقتی کمش هم میکنم باز همین مشکل رو دارم. در واقع میخوام ببینم این الگوریتم خوبه یا اینکه الگوریتم رو باید عوض کرد . ممنون میشم راهنمایی کنید.
        اینم از عکس محتویات کارت SD که اعداد ناگهانی پرش میکنند.

        این رو هم اضافه کنم که علت شیفت به راست اعدا اینه که متغیر unsigned char در این سری از dsp هشت بیتی هست و برای نوشتن روی کارت SD باید 8 بیت بالا و پایین را توی دو تا خونه جداگانه نوشت.
        خیلی ممنون.
        سلام
        یه نکته هست که من قبلا باهاش درگیری داشتم، با خودم گفتم بهتره به شما هم بگم، شاید مشکل شما هم به همین بر میگرده.
        من کد شما رو بررسی نکردم ولی با یه نگاه کلی چشمم به تابع f_sync نخورد! ببینید توی کتابخونه ff لازمه با چند بایت نوشتن داده، یک بار تابع f_sync فراخوانی بشه تا ذخیره داده به درستی انجام بشه. جالبه بدونید تابع f_close هم خودش این کار رو میکنه ولی راه درستی نیست که مداوم f_close و f_open فراخوانی بشن. بهتره توی کدتون f_sync رو هم قرار بدید، شاید با این کار مشکل برطرف شد. من خودم قبلا همین مشکل از دست رفتن یا حتی ذخیره نشدن داده داشتم که بعد فهمیدم لازمه به صورت مرتب f_sync فراخوانی بشه.

        دیدگاه


          #5
          پاسخ : نمونه برداری از ADC با مدت زمان طولانی

          نوشته اصلی توسط saati.sms نمایش پست ها
          خیلی ممنون از توضیحتون.
          ولی مشکل اینه که بورد تهیه شده و پروژه کاملا صنعتی است و این بخشی از پروژه هست که باید از سیگنال موتور نمونه برداری شود و بعدا برای خطایابی مورد استفاده قرار گیرد و نهایتا قراره برای هر موتور یکی از این بورد ها گذاشته بشه و اپراتور هر وقت خواست شروع به نمونه برداری کنه. و ستگاه پورتابل باشه.
          فکر کنم تا حد خوبی مشکل رو رفع کردم .
          الان برای تست میخوام یک ارایه بزرگ اعداد ( از 0 تا 65535 ) رو بدم به متلب و ببینم که این اعداد دارای فاصله مساوی ( برابر 1 ) هستند یا نه ؟
          اگر در این زمینه میتونید کمک کنید خیلی ممنون میشم.
          خیلی لطف کردید.
          بجز اینکه میشه با حلقه نوشتش، میشه از روش های دیگه استفاده کرد بسته به کاربرد.
          مثلا یه بردار تعریف کنید به اندازه همون آرایه تون و اعداد توش معادل چیزی باشن که میخواین. یعنی 0، 1، 2، 3 و ...
          بعد داده های خودتونو با این بردار مقایسه کنید با استفاده از norm یا با استفاده از خطا نسبی و مطلق که تو پرسش زیر توضیح داده شده :
          I have two matrices x and y, both are results from different algorithms/routines that are supposed to calculate the same result. While I know that the isequal() would check if x and y are the same ...


          اگر داده ها شیفت زمانی داشته باشن فک نمیکنم بشه از این روش استفاده کرد.
          Si vis pacem, para bellum

          دیدگاه


            #6
            پاسخ : نمونه برداری از ADC با مدت زمان طولانی

            نوشته اصلی توسط tiranoid نمایش پست ها
            بجز اینکه میشه با حلقه نوشتش، میشه از روش های دیگه استفاده کرد بسته به کاربرد.
            مثلا یه بردار تعریف کنید به اندازه همون آرایه تون و اعداد توش معادل چیزی باشن که میخواین. یعنی 0، 1، 2، 3 و ...
            بعد داده های خودتونو با این بردار مقایسه کنید با استفاده از norm یا با استفاده از خطا نسبی و مطلق که تو پرسش زیر توضیح داده شده :
            I have two matrices x and y, both are results from different algorithms/routines that are supposed to calculate the same result. While I know that the isequal() would check if x and y are the same ...


            اگر داده ها شیفت زمانی داشته باشن فک نمیکنم بشه از این روش استفاده کرد.
            سلام مجدد.
            من هر کاری کردم نتونستم که داده های ADC رو داخل کارت SD بنویسم.
            هیچ راهی به ذهنتون نمیرسه. خیلی گیر افتادم.
            هیچ حافظه RAM خارجی خیلی پر سرعت هست که بشه داده ها رو داخل اون ذخیره کرد؟ فرکانس مثلا 20 کیلو نرخ نمونه برداری هست.
            خوب قطعا به حجم بالایی از حافظه هم نیاز دارم.
            خیلی ممنون.

            دیدگاه


              #7
              پاسخ : نمونه برداری از ADC با مدت زمان طولانی

              نوشته اصلی توسط saati.sms نمایش پست ها
              سلام مجدد.
              من هر کاری کردم نتونستم که داده های ADC رو داخل کارت SD بنویسم.
              هیچ راهی به ذهنتون نمیرسه. خیلی گیر افتادم.
              هیچ حافظه RAM خارجی خیلی پر سرعت هست که بشه داده ها رو داخل اون ذخیره کرد؟ فرکانس مثلا 20 کیلو نرخ نمونه برداری هست.
              خوب قطعا به حجم بالایی از حافظه هم نیاز دارم.
              خیلی ممنون.
              20 کیلوهرتز فرکانس بالایی نیست که نیاز به رم سریع داشته باشه.
              حافظه های فلش ارزون قیمت هس که یه بافر 256 بایتی دارن و عملیات 256 بایت نوشتن (پیج رایت) بین 1 تا 3 میلی ثانیه طول میکشه براشون.

              شما در هر ثانیه 20 هزار نمونه (8 بیت با توجه به کدتون) میگیرید. یعنی هر ثانیه 20 کیلوبایت. با این سرعت یه بافر 256 بایت ، 13 میلی ثانیه طول میکشه تا از نمونه های ADC پر بشه. در حالی که نوشتن همین مقدار روی چیپ بین 1 تا 3 میلی ثانیه س.
              روند اینجوریه :
              دو بافر 256 تایی (آرایه 256 بایتی) تعریف میکنید، سیستم DMA رو راه اندازی میکنید. اگر میکروتون این امکان رو داره با تریگر تایمر نمونه برداری کنه خیلی خوبه. توجه کنید 2 بافر نیاز دارید.
              13 میلی ثانیه طول میکشه بافر اول پر بشه. وقتی پر شد، سویچ میشه به بافر دوم در عوض بافر اول با DMA با سرعت بالا منتقل میشه به چیپ حافظه. زمان فرستادن ناچیزه. زمان نوشتن هم 3 میلی ثانیه ماگزیمم طول میکشه.
              بعد همینکار برای بافر بعدی انجام میشه. یعنی شما یه بافر پر میکنی میدی DMA میری رو بافر دوم، تموم که شد بافرها رو سویچ میکنید.

              من دقیقا همین سیستم رو، با خیلی حالات حادتر پیاده کردم. با اینکه DMA باید به جریان سرویس بده ولی خیلی خوب کار میکنه. نرخ 12 تا 16 کیلوهرتز هم هست و استریم میکنه.
              چیپ 8 مگابایتیش قیمتش زیر 10 تومنه و براحتی با SPI وصل میشه به میکرو. دردسر سیم کشی هم نداره. میتونه تا 6 دقیقه داده هاتون رو ضبط کنه.
              Si vis pacem, para bellum

              دیدگاه


                #8
                پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                نوشته اصلی توسط tiranoid نمایش پست ها
                20 کیلوهرتز فرکانس بالایی نیست که نیاز به رم سریع داشته باشه.
                حافظه های فلش ارزون قیمت هس که یه بافر 256 بایتی دارن و عملیات 256 بایت نوشتن (پیج رایت) بین 1 تا 3 میلی ثانیه طول میکشه براشون.

                شما در هر ثانیه 20 هزار نمونه (8 بیت با توجه به کدتون) میگیرید. یعنی هر ثانیه 20 کیلوبایت. با این سرعت یه بافر 256 بایت ، 13 میلی ثانیه طول میکشه تا از نمونه های ADC پر بشه. در حالی که نوشتن همین مقدار روی چیپ بین 1 تا 3 میلی ثانیه س.
                روند اینجوریه :
                دو بافر 256 تایی (آرایه 256 بایتی) تعریف میکنید، سیستم DMA رو راه اندازی میکنید. اگر میکروتون این امکان رو داره با تریگر تایمر نمونه برداری کنه خیلی خوبه. توجه کنید 2 بافر نیاز دارید.
                13 میلی ثانیه طول میکشه بافر اول پر بشه. وقتی پر شد، سویچ میشه به بافر دوم در عوض بافر اول با DMA با سرعت بالا منتقل میشه به چیپ حافظه. زمان فرستادن ناچیزه. زمان نوشتن هم 3 میلی ثانیه ماگزیمم طول میکشه.
                بعد همینکار برای بافر بعدی انجام میشه. یعنی شما یه بافر پر میکنی میدی DMA میری رو بافر دوم، تموم که شد بافرها رو سویچ میکنید.

                من دقیقا همین سیستم رو، با خیلی حالات حادتر پیاده کردم. با اینکه DMA باید به جریان سرویس بده ولی خیلی خوب کار میکنه. نرخ 12 تا 16 کیلوهرتز هم هست و استریم میکنه.
                چیپ 8 مگابایتیش قیمتش زیر 10 تومنه و براحتی با SPI وصل میشه به میکرو. دردسر سیم کشی هم نداره. میتونه تا 6 دقیقه داده هاتون رو ضبط کنه.
                خیلی ممنون.
                داده های ADC شانزده بیتی هستن ولی پردازنده اجازه دسترسی به بایت پایین و بالا رو نمیده ( یا من بلد نیستم ) به خاطر همین شیفت میدم و بایت پایین و بالا رو جداگانه میفرستم.
                DMA هم داره. بی زحمت یک نمونه از اون چیپ ها رو میشه معرفی کنید؟
                سوال اصلیم اینه که چرا زمان نمونه برداری به هم میخوره. یعنی تابع f_write زمان نمونه برداری ADC رو خراب میکنه.
                اگر بشه با همون کارت SD کار کرد که خیلی بهتره. برای این راهکاری ندارین ؟
                باز هم ممنون.

                دیدگاه


                  #9
                  پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                  نوشته اصلی توسط saati.sms نمایش پست ها
                  خیلی ممنون.
                  داده های ADC شانزده بیتی هستن ولی پردازنده اجازه دسترسی به بایت پایین و بالا رو نمیده ( یا من بلد نیستم ) به خاطر همین شیفت میدم و بایت پایین و بالا رو جداگانه میفرستم.
                  DMA هم داره. بی زحمت یک نمونه از اون چیپ ها رو میشه معرفی کنید؟
                  سوال اصلیم اینه که چرا زمان نمونه برداری به هم میخوره. یعنی تابع f_write زمان نمونه برداری ADC رو خراب میکنه.
                  اگر بشه با همون کارت SD کار کرد که خیلی بهتره. برای این راهکاری ندارین ؟
                  باز هم ممنون.
                  همین چیپ های W25 که تو فروشگاه هم هست. w25 سرچ کنید میاد.
                  میکروکنترلرتون چیه ؟
                  SD کارت بدون SDIO بسیار کنده اگر روی SPI کار کنه.
                  از نظر 16 بیت مشکلی نداره فقط تعداد نمونه های کمتری جا میشه. میشه 3 دقیقه برای چیپ 8 مگابایتی.
                  ببینید مشخص نیست کتابخونه SD کارتتون از چه واسطی با چه سرعتی استفاده میکنه. از DMA استفاده میکنه یا نمیکنه، رو چه کانالیه، با وقفه کار میکنه یا بی وقفه.
                  اگه نرم افزاری خالص باشه بشدت کنده.
                  Si vis pacem, para bellum

                  دیدگاه


                    #10
                    پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                    نوشته اصلی توسط tiranoid نمایش پست ها
                    همین چیپ های W25 که تو فروشگاه هم هست. w25 سرچ کنید میاد.
                    میکروکنترلرتون چیه ؟
                    SD کارت بدون SDIO بسیار کنده اگر روی SPI کار کنه.
                    از نظر 16 بیت مشکلی نداره فقط تعداد نمونه های کمتری جا میشه. میشه 3 دقیقه برای چیپ 8 مگابایتی.
                    ببینید مشخص نیست کتابخونه SD کارتتون از چه واسطی با چه سرعتی استفاده میکنه. از DMA استفاده میکنه یا نمیکنه، رو چه کانالیه، با وقفه کار میکنه یا بی وقفه.
                    اگه نرم افزاری خالص باشه بشدت کنده.
                    سلام مهندس.
                    ببخشید من واحد DMA و SPI پردازنده DSP رو راه انداختم. میخواستم فرایند کار رو یک بار مرور کنم ، ببینید درست هست یا نه . خیلی ممنون.
                    1- تایمر رو به گونه ای تنظیم میکنم که سر فرکانس 20 کیلو ، ADC رو تریگر کند.
                    2- توی روتین وقفه ADC ، دو تا بافر داریم که اندازه هرکدام به اندازه یک page ( مثلا اندازه هر پیج 256 بایت باشد ) از ای سی W25 هست. ابتدا بافرا اول رو پر میکنیم و وقتی پر شد DMA رو تریگر میکنیم که بافری که پر هست ارسال بشه و برای ادامه نمونه برداری بافر دوم شروع به پر شدن میکند.
                    ***** چون فرکانس نمونه برداری 20 کیلو هست ، مدت زمانی که طول میکشه تا بافر اول یا دوم پر بشه 12.8 میلی ثانیه هست و چون مدت زمان توشته شدن یک پیچ در ای سی W25 خیلی کمتر است میتوان جای بافر ها رو با خیال راحت جا به جا کرد.
                    خوب الان یه مشکلی دارم اینه که من از کجا باید مدت زمان نوشتن شدن یک پیج در W25 رو بدونم. ( نمونه 64 مگابتی رو خود فروشگاه گفته 0.7 میلی ثانیه ) ولی من توی دیتاشیت چیزی ندیدم که بگه مدت زمان نوشته شدن یک پیج چقدر هست؟(البته یه نگاه گذرا کردم) میخوام مطمین بشم که چه قدر هست سرعتش چه جوری باید بفهمم ؟
                    مشکل دیگه هم اینه که من تا حالا نتونستم یک کتابخونه خوب برای این ای سی پیدا کنم ( البته برای DSP )، نوشتن کتابخونه اش سخته یا سریع نوشته میشه ؟
                    ممنون میشم راهنماییم کنید.

                    دیدگاه


                      #11
                      پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                      سلام
                      W25 یه رجیستر استتوس داره، و یه بیتش اسمش Busy ه. موقه نوشتن یا پاک کردن میشه خوندش. باید بعد از هر نوشتن پیج، سی پی یو مداوم اینو بخونه ببینه کی ریست میشه که بفهمه نوشتن پیج تکمیل شده.
                      خود میکروکنترلر رمش جای یکی دو تا بافر رو نداره ؟ مثلا 2 تا بافر 256 بایتی میشه نیم کیلوبایت.
                      Si vis pacem, para bellum

                      دیدگاه


                        #12
                        پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                        نوشته اصلی توسط tiranoid نمایش پست ها
                        سلام
                        W25 یه رجیستر استتوس داره، و یه بیتش اسمش Busy ه. موقه نوشتن یا پاک کردن میشه خوندش. باید بعد از هر نوشتن پیج، سی پی یو مداوم اینو بخونه ببینه کی ریست میشه که بفهمه نوشتن پیج تکمیل شده.
                        خود میکروکنترلر رمش جای یکی دو تا بافر رو نداره ؟ مثلا 2 تا بافر 256 بایتی میشه نیم کیلوبایت.
                        من الان دیدم بله حافظه ram میکرو نیم کیلو بایت نیست ولی به راحتی یک بافر 1000 خونه ای 16 بیتی رو تعریف میکنم و مقادیر اون رو هم پر میکنم.
                        چه طور ممکنه ؟
                        واینکه نوشتن برنامه برای W25 اسونه یا درد سرش خیلی هست ؟
                        من چه جوری سرعت نوشتن روی W25 رو بفهمم چه قدره ؟

                        دیدگاه


                          #13
                          پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                          1) مدل میکروتون دقیقا چیه یکم بخونم در موردش ؟
                          2) نه سخت نیست. براحتی کار با همون eeprom هاس. ولی باید با ساختار حافظه و page آشنا باشید که از قرار معلوم آشنا هستید.
                          3) آزمودن. ولی بهترین کار (کاری که خود سازنده چیپ هم توصیه میکنه) استفاده از همون بیت Busy تو رجیستر استتوسه. به راحتی دو تا انتقال SPI ساده و بررسی وضعیت بیت برگشتی از بایت دومه.
                          Si vis pacem, para bellum

                          دیدگاه


                            #14
                            پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                            نوشته اصلی توسط tiranoid نمایش پست ها
                            1) مدل میکروتون دقیقا چیه یکم بخونم در موردش ؟
                            2) نه سخت نیست. براحتی کار با همون eeprom هاس. ولی باید با ساختار حافظه و page آشنا باشید که از قرار معلوم آشنا هستید.
                            3) آزمودن. ولی بهترین کار (کاری که خود سازنده چیپ هم توصیه میکنه) استفاده از همون بیت Busy تو رجیستر استتوسه. به راحتی دو تا انتقال SPI ساده و بررسی وضعیت بیت برگشتی از بایت دومه.
                            اول اینکه تشکر کنم بابت راهنمایی هاتون. واقعا ممنون هستم.
                            من از بورد LAUNCHXL_F28379D با پردازنده TMS320F28379D که برای شرکت TI هست استفاده میکنم.
                            باز هم ممنون.

                            دیدگاه


                              #15
                              پاسخ : نمونه برداری از ADC با مدت زمان طولانی

                              من در خدمتم. این که بیش از 200 کیلوبایت فلش داره. و دو تا DMA مجزا. شما نیاز به بافر کردنش تو حافظه دیگه ای ندارید براحتی میتونید با کمک دو تا DMA اینا رو بفرستید.
                              یه کیلوبایت بافر هم کافیشه
                              Si vis pacem, para bellum

                              دیدگاه

                              لطفا صبر کنید...
                              X