NOTICE توجه: این یک موضوع قدیمی است که آخرین پست ارسالی آن مربوط به 3711 روز قبل است . لطفا فقط پاسخ ها ، سوالات و درخواست های 100 درصد مرتبط را به آن ارسال کنید و برای درخواست ها و سوالات جدید موضوع جدیدی را ایجاد کنید
نمایش نتایج: از 1 به 1 از 1

موضوع: تجربیات عملی میکروکنترلری ...

  1. #1
    کاربر ارشد 1nafar آواتار ها
    تاریخ عضویت
    Jul 2007
    نوشته ها
    2,745
    تشکر
    1,266
    تشکر شده 4,874 بار در 1,377 پست

    پیش فرض تجربیات عملی میکروکنترلری ...

    TIMEOUT در میکروکنترلر ها ( پورت سریال )
    بعضی وقت ها نیاز داریم تا از پورت سریال میکروکنترلر ها استفاده کنیم و برای این پورت برنامه بنویسیم .
    معمولا ما در هنگام برنامه نویسی ، از دستورات استاندارد برنامه نویسی ( کتابخانه stdio.h ) یا به صورت مستقیم از رجیستر ها برای تبادل داده بر مبنای این پروتکل استفاده کنیم . در این رابطه بحث های زیادی در سطح انجمن و کتب برنامه نویسی انجام شده و کلیه دستورات مذکور قبلا معرفی شدن .
    دستورات زیر از جمله دستورات استاندارد برنامه نویسی پروتکل uart یا rs232 در زبان سی هستند :
    [PHP]printf(string)
    putchar()

    fputc()

    putc (cdata)

    value = getc()

    value = fgetc(stream)

    value=getch()

    value=getchar()
    [/PHP]

    برای ارسال داده به دستگاه جانبی مشکلی وجود نداره ، ما با یکی از دستورات printf یا putchar یا fputc یا putc رشته ، متغیر یا کاراکتر مورد نظرمون رو با یک نرخ انتقال داده ثابت به دستگاه جانبی ارسال میکنیم .
    برای دریافت داده از دستگاه جانبی از دستورات getc و fgetc و getch و getchar و... استفاده میشه . معمولا با اجرا شدن این دستورات ،در درون کتابخانه ها حلقه زیر اجرا میشه :
    کد:
      while (!(RXRDY));   // Wait for new char
      return (*Rx Buffer );
    مثلا برای میکروکنترلر arm اتمل ، کلیه هدر های ارائه شده ، در نهایت دستور زیر رو برای دریافت یک کاراکتر از پورت سریال اجرا میکنن :
    کد:
    while (!((*AT91C_US0_CSR) & AT91C_US_RXRDY));   // Wait for Empty Rx Buffer
      return (*AT91C_US0_RHR );
    یا در کامپایلر mplab دستور زیر در هنگام دریافت داده از پورت سریال اجرا میشود :
    کد:
        while (! U1STAbits.URXDA);  // wait until data is available
       return U1RXREG;             // return received character over UART
    همون طور که مشاهده میکنید در تمامی حلقه های بالا اگر بعد از اجرای دستورات getc و fgetc و getch و getchar و.. داده ای به بافر پورت سریال وارد نشه ، میکروکنترلر در حلقه while موجود برای همیشه گیر میکنه .
    این حالت ممکنه در هنگام ارتباط با یک کامپیوتر و به دلیل هنگ کردن نرم افزار کامپیوتری ، در هنگام دریافت داده از یک ماژول و به دلیل قطع شدن تغذیه ماژول ، در هنگام دریافت داده از یک میکروکنترلر و ایجاد خطا در داده دریافتی و و در هنگام ارتباط با هر نوع وسیله جانبی دیگر و به دلیل بروز مشکلاتی مانند قطع شدن سیم ها ، عدم اتصال صحیح سیم ها و... میکروکنترلر ما هنگ کنه و نتونه سایر دستورات رو اجرا کنه .
    مثال:
    http://www.iranmicro.ir/forum/showthread.php?t=8752
    http://www.iranmicro.ir/forum/showthread.php?t=5389
    http://www.iranmicro.ir/forum/showthread.php?t=10582
    http://www.iranmicro.ir/forum/showthread.php?t=9626
    و... نمونه برنامه های نوشته برای پورت سریال هستند که در آنها بروز اختلال در پروتکل سریال پیشبینی نشده است ، میکروکنترلر های موجود در این پروژه ممکنه در آینده به دلیل بروز اختلال در پروتکل rs232 عملکردی غیر قابل پیشبینی داشته باشن .
    برای رفع این مشکل باید از TIMEOUT استفاده کنیم . TIMEOUT رو میشه هم به صورت سخت افزاری و هم به صورت نرم افزاری برای میکروکنترلر اجرا کرد (مثلا میکروکنترلر های arm از TIMEOUT سخت افزاری پشتیبانی میکنن . اما میکروکنترلر pic و avr فاقد TIMEOUT سخت افزاری هستند و ما باید TIMEOUT رو به صورت نرم افزاری برای اونا اجرا کنیم ).
    چند تا نکته :

    • TIMEOUT نرم افزاری فقط در کامپایلر های قابل اجرا هست که به کاربران امکان ویرایش کتابخونه ها رو دادن .
    • برای برخی از کامپایلر مثل bascom avr یا ccs pic c جهت TIMEOUT دستوراتی در نظر گرفته شده ، برای کسب اطلاعات بیشتر دستور TIMEOUT رو در راهنمای اونا جستوجو کنید ، مثال برای بسکام :http://avrhelp.mcselec.com/_timeout.htm
    • استفاده از دستورات TIMEOUT ، قابلیت جدیدی رو به برنامه اضافه نمیکنه و بدون لحاظ کردن این ویژگی ،برنامه بدون هیچ مشکلی کار میکنه . این اموزش صرف برای افرادی هست که میخوان به صورت حرفه ای برنامه نویسی کنند .

    در ادامه با یک مثل ، نحوهی استفاده از قابلیت TIMEOUT برای میکروکنترلر های PIC و ATM اتمل توضیح داده شده است :
    اجرای دستور TIMEOUT در کامپایلر CCS PIC C :
    برای استفاده از TIMEOUT در این کامپایلر باید در هنگام راه اندازی واحد UART دو دستور ERRORS و TIMEOUT=X رو در پیکربندی پروتکل وارد کنید ، مثال :
    کد:
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,TIMEOUT=70)
    در پیکربندی بالا TIMEOUT برابر با 70 میلی ثانیه تنظیم شده
    برای استفاده از TIMEOUT باید بعد از دستورات getc و fgetc و getch و getchar و.. ، دستور زیر رو قرار بدید :
    کد:
     if (c==0 && RS232_ERRORS==0) break;

    در این حالت اگه تا 70 میلی ثانیه ، داده ای توسط پورت سریال دریافت نشه ، میکروکنترلر از کلیه دستورات getc و fgetc و getch و getchar و.. عبور میکنه ( از داخل حلقه مربوط به دریافت داده خارج میشه ) .

    مثال عملی :
    در برنامه زیر اگر بعد از گذشت 2 ثانیه داده ای از دستگاه جانبی دریافت نشود ، رشته "TIMEOUT , type faster" به دستگاه جانبی ارسال میگردد .
    [PHP]#include <16F877A.h>
    #device adc=16
    #FUSES NOWDT //No Watch Dog Timer
    #FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
    #FUSES PUT //Power Up Timer
    #use delay(clock=20000000)
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,TIMEOUT=2000)
    void main()
    {
    char c;
    while(true){
    printf("Perss any key...\r");
    c=getc();
    if (c==0 && RS232_ERRORS==0)
    printf("TIMEOUT , type faster\r" );
    else
    printf("Enter key is:%c\r",c );
    }
    }
    [/PHP]
    مثال عملی
    در برنامه ای ، باید یک رشته از پورت سریال دریافت شود ،در این حالت باید از کتابخانه input.c استفاده کنیم ، این کتابخونه فاقد دستورات لازم جهت timeout هست و ما باید دستور شرطی زیر رو در کتابخانه input.c و بعد از دستور c=getc(); قرار بدیم .
    کد:
     if (c==0 && RS232_ERRORS==0) break;
    برنامه :
    [PHP]#include <16F877A.h>
    #device adc=16
    #FUSES NOWDT //No Watch Dog Timer
    #FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
    #FUSES PUT //Power Up Timer
    #use delay(clock=20000000)
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,TIMEOUT=2000)
    #INCLUDE <INPUT.C>
    void main()
    {
    char c[10];
    while(true){
    printf("Enter string..\r");
    get_string(c, 10);
    printf("Enter sting is:%s\r",c);
    }
    }[/PHP]

    تابع جدید get_string :
    [PHP]void get_string(char* s, unsigned int8 max) {
    unsigned int8 len;
    char c;

    --max;
    len=0;
    do {
    c=getc();
    if (c==0 && RS232_ERRORS==0){
    printf("TIMEOUT , type faster\r" );
    break;
    }
    if(c==8) { // Backspace
    if(len>0) {
    len--;
    putc(c);
    putc(' ');
    putc(c);
    }
    } else if ((c>=' ')&&(c<='~'))
    if(len<=max) {
    s[len++]=c;
    putc(c);
    }
    } while(c!=13);
    s[len]=0;
    }
    [/PHP]
    به زودی نحوه ی استفاده از TIMEOUT برای میکروکنترلر های avr و arm رو توضیح میدم .

  2. کاربران : 7 تشکر کرده اند از شما 1nafar برای ارسال این پست سودمند:


  3. # ADS
    Circuit advertisement
    تاریخ عضویت
    Always
    نوشته ها
    Many
     

مجوز های ارسال و ویرایش

  • شما نمیتوانید موضوع جدیدی ارسال کنید
  • شما امکان ارسال پاسخ را ندارید
  • شما نمیتوانید فایل پیوست کنید.
  • شما نمیتوانید پست های خود را ویرایش کنید
  •