اطلاعیه

Collapse
No announcement yet.

تعبیر4 بایت داده دریافتی از پورت سریال بعنوان long int یا float

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

    تعبیر4 بایت داده دریافتی از پورت سریال بعنوان long int یا float

    سلام. 4 بایت داده یه متغیر float رو به ترتیب از کم ارزشترین بایتش با AVR فرستادم برای کامپیوتر از طریق usart. تو کامپیوتر هم این داده ها رو گرفتم و شیفتشون دادم تا 4 بایت کامل بشه و با مکافات (روش من درآوردی) تبدیل کردم به متغیر float . از اساتید میخواستم روش صحیح انجام این کار رو نشون بدن . روشهایی که خودم بدست آوردم :
    1- استفاده از اشاره گر *float وقتی 4 بایت رو چیدم پشت سر هم (که بنظر میرسه کامپایلر بطور پیش فرض متغیر موقتی حاصل رو بصورت longi int در نظر میگیره) و استفاده از اون مثل

    float fvar;
    float* fptr;
    fptr=(float*)&(ch[3]<<24 | ch[2]<<16 | ch[2]<< 8 | ch[0 ]);
    fvar=*f;

    2- استفاده از ساختار union که یه long int و یه دونه هم float توش باشه و کار کردن با اونا

    #2
    پاسخ : تعبیر4 بایت داده دریافتی از پورت سریال بعنوان long int یا float

    با سلام
    با ساختار union از متغیر float و آرایه 4 تایی از char می توانید 4 بایت مجزا داشته باشید.
    هر بایت را به دو نصفه 4 بیتی تبدیل نموده و ascii آنها را ( که از 0و1و2و...8و9,A,B,C,D,E,F تشکیل شده)
    در تعداد 8 کد اسکی ارسال کنید و در کامپیوتر مجددا آنها را به طریق معکوس بازسازی کنید.
    به این ترتیب کدها در محدوده قابل نمایش کاراکتر ست اسکی قرار می گیرند و کدهای کنترلی را می توانید به ابتدا و انتهای رشته ارسالی اضافه کنید.
    مثل:CR, LF , STX , ETX...
    با سپاس
    گشتی در لاله زار
    http://www.eca.ir/forum2/index.php?topic=76138.0

    http://www.eca.ir/forum2/index.php?topic=76141

    دیدگاه


      #3
      پاسخ : تعبیر4 بایت داده دریافتی از پورت سریال بعنوان long int یا float

      با سلام وسپاس از پاسختون
      من این 4 بایت رو که یه متغیر floart داخل حافظه میکرو AVR هست رو از کم ارزشترین بایت ارسال میکنم (فکر میکنم این جور ارسال کردن یه فرم استاندارد باشه) و توی کامپیوتر هم بعد از دریافت وشیفت اونها، حالا یه 4 بایتی دارم که کامپایلر بطور پیش فرض اونو long int تصور میکنه . اگه با type cast بخوام تبدیل به float کنم فقط قسمت اعشار به اون long int موقتی اضافه میشه که این خواسته من نیست. من باید به کامپایلر بفهمونم که بابا این چهر بایت یه عدد float هست. البته این کار رو هم انجام دادم . خواسته من اینه که میخوام بدونم آیا این روشی که استفاده کردم یه روش خوب (از نظر برنامه نویسی) هست یا نه؟

      دیدگاه


        #4
        پاسخ : تعبیر4 بایت داده دریافتی از پورت سریال بعنوان long int یا float

        اگر صرفا منظور گرفتن جواب باشه اونهم روی یک پلاتفرم از پیش مشخص شده و ثابت روش union روش خوبی هست. فقط باید حواستون جمع باشه که از فرم packing مناسب برای اون union استفاده بشه. مثلا در کامپایلر visual studio باید از دستوری مثل این استفاده کنین:

        #pragma pack(push,1)
        union
        {
        float f;
        unsigned char b[sizeof(float)];
        }u;
        #pragma pack(pop)


        در همچین مواقعی راههایی مثل این یکی هم براحتی جواب میده:

        char c[4];

        ....
        f = *((float *)c);


        اما متاسفانه اینها راههای درستی نیستن چون در یک فرم عام باعث دردسر هایی ممکنه بشن. مخصوصا روش آخری. برای راه کلی بهتره از memcpy استفاده کنین:


        char c[4];
        float f;

        memcpy( &f, c, sizeof(f) );


        علت هم اینجاست که در بعضی پلاتفرم ها (خصوصا RISC ها) دسترسی چهار بایتی به آدرسی که قابل تقسیم به چهار نباشه باعث بروز خطای دسترسی میشه.

        دیدگاه


          #5
          پاسخ : تعبیر4 بایت داده دریافتی از پورت سریال بعنوان long int یا float

          نوشته اصلی توسط reza_agha
          اگر صرفا منظور گرفتن جواب باشه
          ممنون از جوابتون. من از برنامه جواب گرفتم . انگیزم از ایجاد تاپیک این بود که اگه روش استانداردی برای این کار هست رو پیدا کنم تا با اون روش کار کنم. خودم از روش تبدیل آدرس به آدرس float استفاده کردم.

          دیدگاه

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