2010-03-03 11 views
0

저는 C 프로그래밍을 처음 접했을 때 MCU 용 펌웨어 응용 프로그램을 만들고 있습니다. 이 방법은 KEIL 컴파일러 (Big Endian)를 사용할 때 제대로 작동했지만 SDCC 컴파일러 (Little Endian)로 전환하면 제대로 작동하지 않습니다. 누군가 내가 뭘 잘못하고 있는지 설명해 주시겠습니까 ???SDCC (Little Endian) 컴파일러를 사용할 때이 산술에 어떤 문제가 있습니까?

대상 장치는 8051 아키텍처를 기반으로하는 Silicon Labs C8051F320입니다.

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; 
} 

ADDED : 첫째, 나는 지금 MotorSteps을 변경하고 MotorSpeed는 부호의 int로. 내 디버거에서 어떤 이유로 if-statement 줄에이 함수의 첫 번째 입구에 중단 점을 설정하면 MotorSteps = 00이므로 t도 0에 할당되어야하지만 디버거는 t = 0.031497을 표시합니다. (소수). 디버거가 16 진수로 표시되도록 전환하면 t = 0x3d010300이됩니다. 그것은 절대 할당되지 않는 것처럼 ...

+1

MotorSteps와 SetSpeedHz가 어떻게 생겼는지 알 수 있습니다. –

+0

MotorSpeed에 대한 선언을 보는 것도 도움이됩니다. – semaj

+3

엔디안 종속적 인 코드에는 아무 것도 없습니다. 문제는 무엇입니까? – AnT

답변

3

MotorSteps = 49은 다음

(50 - 49)/50 = 0.02 

다음

(1 - 0.02) = 0.98 

0.98 * 15 = 14.7 

이 값을 제곱하면

t = 14.7 * 14.7 = 216.09 
,745 t로 설정한다면 1,515,

마지막으로 다시 서명 숯불에 플로트로부터 암시 적 변환이 MotorSpeed ​​변수 오버플 :

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

100 + 216 = 316의 합은 물론, 부호 문자 오버플 및 316- 끝낼 256 = 60.

이것은 아마도 컴파일러와 상관없이 원치 않는 동작입니다.

+3

실제로 부동 소수점 값이 정수 유형의 범위를 벗어나는 경우 정수형에 부동 소수점 (또는 이중)을 할당하면 부호없는 정수에서 예상하는대로 잘 정의 된 모듈 오버플로가 아니라 정의되지 않은 동작이 발생합니다. 따라서 결과는 60이 아닐 수 있으며, 이것이 다른 컴파일러에서 다르게 작동하는 이유를 설명 할 수 있습니다. –

0

왜 BE에서 LE로 전환 했습니까? 대상 장치의 아키텍처 란 무엇입니까? 그런데 그것은 무엇입니까?

어쨌든, 질문하는 중입니다. 나는 전환이 일어날 때 문제가 올 것이라고 확신한다. 코드를 한 줄씩 계산기로 추적하고 예상치 못한 숫자가되었을 때 찾아보십시오.

+2

원래 KEIL 컴파일러를 사용했지만 무료 버전의 제한에 도달하여 라이센스 비용을 지불하지 않으므로 무료이고 무제한 SDCC로 전환되었지만 Endian-ness와 반대입니다. – PICyourBrain

2

그것은 컴파일러가 있기 때문에 선언

float t = 0; 

에 t 0의 값을 할당 할 이유가 없다

... 가 지정되지지고 결코 t처럼 즉시 다음 라인의 MotorSteps에 지정됩니다. 내 생각에 옵티마이 저는 선언에서 0으로 지정을 무시하고 디버거는 단순히 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; 
}