EDIT 이 동작은 바이트 주소가 홀수 메모리 위치에 저장되어 발생합니다. MSP430 마이크로 컨트롤러는 홀수 번지의 워드 값을 반환 할 수 없으며 대상 변수에 0xFFFF를 할당합니다. 구조체 멤버가 짝수 주소에 있기 때문에 예제/테스트 사례 중 일부가 작동합니다.
uint8_t myconfig_rw.current_l은 워드로 정렬되지 않은 메모리 주소 0x04563에 있습니다 (현재 컴파일 된 코드에 있음). 현재 = (USHORT *) & myconfig_rw.current_l; 라인이 생성 I 워드 변수 이것을 복종 때
MOVX.A #0x04563,0x0000a(SP)
,이 라인 0x000e 대신 프로세서에서 워드를 판독 할 수없는 것처럼 어드레스 0x04563에 무엇이든 0xFFFF가 수신
MOVA 0x000a(SP),R15
MOV.W @R15,0x000e(SP)
생성 홀수 번지.
이제 코드 작성기 디버거은 홀수 주소에서 단어 값을 표시하는 데 문제가 없으며 포인터 주소에 예상 값 (0x140)을 행복하게 표시합니다.
문제를 해결하려면 2 바이트 값을 수동으로 배열하여 짝수 주소에서 시작하거나 단어와 바이트 사이를 수동으로 변환해야합니다. 레지스트리를 외부에서 버스트 읽기/쓰기 주소 지정이 가능하기 때문에 유니온을 사용하는 것은 해결책이 아닙니다. 패딩이 필요한지 아닌지에 따라 레지스터 주소가 1 바이트 씩 이동합니다.
일부 해결 방법은 단어 정렬 주소에서 시작하고 "다음 사람"이 혼란에 빠지기를 바라는 코드를 문서화하도록 레지스트리 구조를 정의하는 것입니다. 단어를 2 바이트로 또는 그 반대로 변환하는 것이 훨씬 안전한 접근 방법입니다.
OLD 이 MSP430FR5969 16 비트 마이크로 컨트롤러 텍사스 TLV 17.x 컴파일러 생성 코드로 코드 컴포저 스튜디오 (Code Composer Studio)에 특정 행동 것으로 보인다. 질문에있는 코드 스 니펫이 매우 좋지 않은 경우 "유효한"것으로 나타납니다. 실제 응용 프로그램에서 사용하면 결과를 예측할 수 없습니다. 이 조각을 고려 : 사실
struct myconfig_rw_{
uint8_t current_l;
uint8_t current_h;
} myconfig_rw;
void PWM_Decode_Init(){
USHORT * volatile current;
current = (USHORT *) &myconfig_rw.current_l;
PWM_status.current_constant=Calculate_Current_Constant(*current, false);
}
* 현재의 의지가 myconfig_rw.current_l 및 .current_h에서 올바른 16 비트 값을 포함합니다. 그러나 Calculate_Current_Constant 함수에 전달 된 값이 올바르지 않으면 함수는 값 0xFFFF를받습니다.
결론적으로 포인터를 사용하여 자신의 이익을 위해 너무 영리하게하려고해서는 안됩니다. 예상되는 결과를 제공 할 것입니다
급식 작은 예 :
#include <msp430.h>
#include <stdint.h>
#include <stdio.h>
struct foo_{
uint8_t low;
uint8_t high;
}foo;
/**
* main.c
*/
void foobar(uint16_t test);
int main(void)
{
uint16_t * volatile bar;
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
foo.low=0x10;
foo.high=0xBB;
bar = (uint16_t *) &foo.low;
printf("address %p, value %x\n", bar, *bar);
foobar(bar);
__no_operation();
return 0;
}
void foobar(uint16_t test){
printf("value %x\n", test);
}
과 2 –
당신이 그것을 * 완전히 * 다른 확실하지 있는지? 예상 값과 실제 값을 16 진수로 보면 * any * relationship이 표시됩니까? 그리고 창 밖으로 이동성을 던져 잘못된 결과를 초래했기 때문에 어쩌면 당신은 결국 영리하지 못했습니다. –
'* bar'는 포인터가 아닙니다. MCVE ([MCVE])로 질문하는 것이 좋습니다. –