اطلاعیه

Collapse
No announcement yet.

مشکل در اندازه گیری زمان وظیفه ئر میکرو مگا 16 با کاپچر

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

    مشکل در اندازه گیری زمان وظیفه ئر میکرو مگا 16 با کاپچر


    سلام علیکم
    مشکلی که من با ان مواجه شده مربوط به تمرین کتاب آموزش AVR آقای الوندی فصل 6 تمرین 9 می باشد. من این کتاب را برای یادگیری می خوانم و لذا در صورت پاسخ به من، جنبه تمرین برای استاد و نمره و .... ندارد.
    صورت مسئله: می خواهیم در ATmega16 برای یک موج با فرکانس ثابت و دوره وظیفه متغییر که به ورودی capture(PIND.6) اعمال می شود دوره وظیفه را با استفاده از کانتر 1 و capture اندازه گیری کرده و روی lcd نمایش دهیم. من برای شروع و تست فرکانس را 10khz و duty cycle(d.c.)=50% گرفتم(شکل موج در اسیلوسکوپ در شماتیک پروتئوس)
    روش حل من: در حالت بالا رونده زمان را خوانده ودر متغییر K1 ذخیره شود و در لبه پایین رونده، زمان در متغییر K2 ذخیره شود و با توجه به رابطه d.c. ، مقدار آن را محاسبه کنم. من برای این حداقل 5 روز وقت گذاشتم (یک روز دیگرهم بدلیل یک مشکل در دیباگ در پروتئوس و جستجو برای راه حل ان در اینترنت تلف شد) لذا در صورت مساعدت ، بسیار ممنون می شوم.
    من کد کدویژن را با پروتئوس دیباگ کردم چیزی که من مشاهده کردم این بود که در جاهایی که من انتظار دارم مقدار سیگنال صفر باشد یهو یک می شود و یا بالعکس. مثلا با شروع از یک حالت صفر پس از 3 یا 4 پالس ساعت یهو به وقفه کپچر(capcher) می رود در حالیکه نباید چنین باشد . می خواستم در سایت eca.ir پیام و پست بگذارم ولی نمی دانستم آنجا چگونه کدها و شماتیک پروتئوس را قرار دهم( چند وقت قبل یک میل به مدیر سایت زدم و از ایشان برای روش پلود عکس و کدو.. راهنمایی خواستم ولی جوابی نیامد.یک قسمت برای راهنمایی و یا یک میل برای پشتیبانی به غیر از میل مدیر سایت پیدا نکرم)
    مسئله ای که من دربرنامه هم خواستم به ان توجه کنم این است که فرض کنیم PIND.6 مقدارش تغییرکند ولی باید مدنظر قرار داد که این می تواند بدلیل نویز باشدحال برای این مشکل مثلا در ابتدای برنامه 5 بارپشت سرهم PIND.6 را می خوانم اگر 5 بار ثابت بود دلیل تغییرنویز نیست. ایا شما روش بهتری سراغ دارید؟
    خیلی طولانی شد . خلاصه دمار من در امده و اعصاب خط خطی شده. اگر کمک کنید ممنون وتشکر.
    کد :

    #include <mega16.h>
    #asm
    .equ __lcd_port=0x1B; // port a connected to lcd
    #endasm
    #include <lcd.h>
    #include <stdio.h>
    #include <delay.h>
    typedef unsigned long int unli;
    typedef unsigned char unch;
    unli oldtemp=0,freq=10000; // freq=10khz , wave frequency
    unli clk =8000000; // clock frequency
    volatile unli k1=0,k2=0;
    volatile unch flag=1; // when flag=1, in rising edge capturing occured and
    // when flag=0, in falling edge capturing occured.

    void lcd_display(unli k1,unli k2){
    float number=0.0;
    char buff[20];
    lcd_clear();
    lcd_gotoxy(2,0);
    lcd_putsf("duty cycle %= "
    lcd_gotoxy(2,1);
    number=100*(float)(k2-k1+1)/(0XFFFF-0XFCE0+1);
    sprintf(buff,"%3.1f",number);
    lcd_puts(buff);
    //delay_ms(1000);
    }
    interrupt [TIM1_OVF] void timer1_ovf_isr(void){
    unsigned char temp=0;
    temp=TCCR1B;
    TCCR1B=0X00;
    TCNT1H=0XFC;
    TCNT1L=0XE0; // OR TCNT1=0XFCE0;
    TCCR1B=temp;
    }
    interrupt [TIM1_CAPT] void timer1_capt_isr(void){
    unli newtemp=0;
    TCCR1B=0X00;
    #asm("cli&quot
    if (flag==1) {
    k1=ICR1L+ ((long)(ICR1H)*256) ;
    TCCR1B=0X81;
    }
    else {
    k2=ICR1L+(long)ICR1H*256;
    TCCR1B=0XC1;
    newtemp=k2-k1;
    if (newtemp != oldtemp) lcd_display(k1,k2);
    oldtemp=newtemp;
    };
    flag= ! flag;
    //TIFR |= 0b00100000;
    #asm("sei&quot

    }



    void main(void)
    {
    unch i1=0,i2=0,i3=0,i4=0,i5=0;
    lcd_init(16);
    lcd_clear();
    lcd_gotoxy(2,0);
    lcd_putsf("lcd ready ok "
    delay_ms(250);
    DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
    // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
    PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

    DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
    // State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
    PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
    ICR1H=0X00;
    ICR1L=0X00;
    TCCR1A=0X00;
    TCNT1H=0XFC;
    TCNT1L=0XE0;
    TIMSK= 0X24;
    TIFR=0X24;
    while(1){
    while (PIND.6==1);
    i1=PIND.6; // i1 to i5 is used for PIND.6 --
    // --changing to zero is not beacause of noise,
    // namely for 5 clock cycle PIND.6 must be zero.
    i2=PIND.6;
    i3=PIND.6;
    i4=PIND.6;
    i5=PIND.6;
    if( (i1==0)&(i2==0)&(i3==0)&(i4==0)&(i 5==0)) break;
    };
    TCCR1B=0XC1;
    #asm("sei&quot
    while (1) {} ;

    }

    #2
    پاسخ : مشکل در اندازه گیری زمان وظیفه ئر میکرو مگا 16 با کاپچر

    در حالتی که میکروکنترلر لبه های بالا رونده یا پایین رونده را می خواند حساسیت به مراتب بیشتری دارد نسبت به زمانی که توسط یک پین سطح منطقی 0 یا یک را می خواند ، به همین علت روش آزمایش شما در تشخیص نبودن نویز اشتباه است . بهتر است از یک فیلتر RC در ورودی پایه ی کاپچر میکروکنترلر استفاده کنید ، مثلا با مقادیر خازنی 10 نانوفاراد و مقاومت 100 اهم ، البته تعیین مقادیر فیلتر بستگی به فرکانس طراحی آن دارد.

    دیدگاه

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