ما هو الخطأ في هذا الحساب عند استخدام برنامج التحويل البرمجي SDCC (Little Endian)؟

StackOverflow https://stackoverflow.com/questions/2374367

سؤال

أنا جديد جدًا في C Programming وأعمل على طلب البرامج الثابتة لـ MY MCU. كانت هذه الطريقة تعمل بشكل جيد عندما كنت أستخدم برنامج التحويل البرمجي Keil (Big Endian) ولكن عندما تحولت إلى برنامج التحويل البرمجي SDCC (Little Endian) ، فإنه لا يعمل بشكل صحيح. هل يمكن لأحد أن يشرح ما أفعله خطأ ؟؟؟

الجهاز المستهدف هو Silicon Labs C8051F320 والذي يعتمد على بنية 8051.

unsigned **int** MotorSteps  = 0;     //"Global" variables
unsigned **int** MotorSpeed  = 0;
bit RampUp()
{
    float t = 0;
    t = MotorSteps;
    if ( t < 51 )
    {
        t = (1-((50 - t)/50))*15;   
        t = (t * t);        
        MotorSpeed = 100 + t;           
        return 0;
    }
    else return 1;
}

تمت إضافة: أولاً ، لقد قمت الآن بتغيير خطوات السيارات و Motorspeed ليكون ints غير موقعة.في مصحح أخطاء ، لسبب ما ، إذا قمت بتعيين نقطة استراحة في خط IF-Statement ، في المدخل الأول من هذه الوظيفة الموسيقية = 00 ، لذلك يجب أن يتم تعيين T إلى 0 أيضًا ولكن يوضح تصحيح الأخطاء أن t = 0.031497 (عشري (عشري ). إذا قمت بتبديل مصحح الأخطاء لعرضه في Hex ، t = 0x3d010300. إنه مثل T لا يتم تعيينه أبدًا ...

هل كانت مفيدة؟

المحلول

إذا كانت Motorsteps = 49 ثم

(50 - 49) / 50 = 0.02

التالي

(1 - 0.02) = 0.98

و

0.98 * 15 = 14.7

تربيع هذه القيمة سيعين t

t = 14.7 * 14.7 = 216.09

أخيرًا ، يفيض التحويل الضمني من العوام إلى Char غير الموقّع على متغير Motorspeed:

MotorSpeed = 100 + 216.09...// Implicitly converts the float t to an unsigned char of 216

مجموع 100 + 216 = 316 ، بالطبع ، يفيض شار غير موقّع وينتهي بك الأمر بـ 316-256 = 60.

ربما يكون هذا سلوكًا غير مرغوب فيه بغض النظر عن المترجم.

نصائح أخرى

إنه مثل T لا يتم تعيينه أبدًا ...

لا يوجد سبب لخصم المترجم

float t = 0;

نظرًا لأنه يتم تعيينه على الفور إلى Motorsteps على السطر التالي. أظن أن المحسن هو تجاهل المهمة للصفر في الإعلان ، ويعرض تصحيح الأخطاء ببساطة القيمة غير المخصصة للذاكرة حيث توجد T على المكدس.

قد ترغب في التفكير في التخلص من الصيغة تمامًا واستخدام جدول البحث لقيم المنحدر. يبدو أن هناك 51 قيمة فقط ، لذا فإن الجدول سيكون صغيرًا نسبيًا. الرمز للبحث عن القيمة سيكون كثيراً أسرع من استخدام مكتبات النقطة العائمة على 8051.

#define NUM_RAMP_STEPS 51
unsigned char MotorSteps = 0;     //"Global" variables
unsigned char MotorSpeed = 0;
const unsigned char RampTable[NUM_RAMP_STEPS] = {...appropriate values...};
bit RampUp()
{
    if ( MotorSteps < NUM_RAMP_STEPS )
    {
        MotorSpeed = RampTable[MotorSteps];           
        return 0;
    }
    else return 1;
}

على الأقل ، يمكنك اختبار عدد صحيحك بدلاً من التعويم لتجنب مكتبات النقطة العائمة إلا إذا كنت في حاجة إليها ...

unsigned **int** MotorSteps  = 0;     //"Global" variables
unsigned **int** MotorSpeed  = 0;
bit RampUp()
{
    if ( MotorSteps < 51 )
    {
        float t = MotorSteps;
        t = (1-((50 - t)/50))*15;   
        t = (t * t);        
        MotorSpeed = 100 + t;           
        return 0;
    }
    else return 1;
}

لماذا انتقلت من Be إلى Le؟ ما هي بنية الجهاز المستهدف؟ وبالمناسبة ما هو؟

على أي حال ، للتساؤل. أنا متأكد من أن المشكلة تأتي عندما تحدث التحويل. حاول تتبع خط الرمز الخاص بك سطرًا باستخدام الآلة الحاسبة وحاول العثور على عندما تصبح الأرقام غير متوقعة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top