2017-03-25 3 views
-1

SPI 링크를 플로트 (float)로 보내려면 약간의 코드가 필요했습니다. 이해하기가 힘듭니다.float을 SPI 링크로 보내기위한 코드

혼란

먼저 점 : * (uint32_t의 *) (F &)

혼란

번째 점 : uint8_t * 바이트 = (uint8_t *) (& DWORD);

는 혼란의

세 번째 점 : 가 (INT는 전 = 0; 나는 <를 sizeof (uint32_t); 내가 ++, 바이트 ++) 사람이 더 좋은 방법을 알고 있다면 또한

void spi_send_dword(SPI_TypeDef *spi, uint32_t dword) { 
    uint8_t *byte = (uint8_t *)(&dword); 

    for(int i = 0 ; i < sizeof(uint32_t) ; i++, byte++) 
    spi_transfer_byte(spi, *byte); 
} // spi_send_float() 

void spi_send_float(SPI_TypeDef *spi, float f) { 
    spi_send_dword(spi, *(uint32_t *)(&f)); 
} // spi_send_float() 

는이 작업을 수행하는 나는 그것을 듣고 싶다. 주변에서 아무 것도 찾을 수 없습니다.

+0

코드가 정의되지 않은 동작을 호출합니다. 'union '을 사용하십시오. 또한이 코드는 구현에 매우 특정적일 것이다. 다른 플랫폼으로 데이터를 읽어야하는 경우 적절한 교환 형식을 정의하십시오. ASCII 표현. – Olaf

답변

-1

코드에 많은 문제가 있습니다.

1) 플로트는 거의 32 비트가 아닙니다.

2) "DWORD"도 32 비트가 아닙니다.

3)에 플로트를 보내는 대상이

되지만, 당신의 '혼란의 포인트'(대답하는 현실에서 같은 내부 표현 (바이트 순서, 비트 순서)가 보장이 없다 , C 질문) :

첫 번째 : float에 대한 포인터를 가져 와서 uint32_t에 대한 포인터로 캐스팅 한 다음 해당 주소에서 uint32_t 값을 가져옵니다. 이것은 이론적으로 단지 부동 소수점 숫자의 원시 비트 표현을 얻는 것입니다. 수레는 대개 32 비트가 아니기 때문에 제대로 작동하지 않습니다.

두 번째 : 배열에 전달 된 uint32_t 값의 바이트 포인터를 가져옵니다.

세 번째 : uint32_t의 각 바이트에 대해 카운터와 바이트 포인터를 각각 반복합니다.

아마로 void spi_send_float(SPI_TypeDef *spi, float f)을 변경 훨씬 더 "정확한"다음과 같습니다

void spi_send_float(SPI_TypeDef *spi, float myfloat) { 
    uint8_t *byte = (uint8_t *)(&myfloat); 

    for(int i = 0 ; i < sizeof(float) ; i++, byte++) 
    spi_transfer_byte(spi, *byte); 
} // spi_send_float() 

당신이 uint32_t로 같은 크기의 여부에 관계없이 부동의 모든 바이트를 전송하고 적어도이 방법 아닙니다. 당신은 여전히 ​​전선의 다른 쪽 끝에있는 비트/바이트 순서의 문제에 얽매이지 않고 있습니다.

+0

수레와 DWORD는 내가 작업 한 대부분의 프로젝트에서 32 비트가되었습니다. 그들이 어떤 크기로 있어야한다고 생각하니? – kkrambo

+0

@kkrambo 당신은'float' 타입에 대해 옳습니다 (그러나 ** floats **는 일반적이지 않습니다). 그러나'DWORD는 일반적인 용어가 아닙니다. 그것은 platfor에 의존하는 무엇이든을 의미 할 수 있습니다. 예를 들어 ARM은 64 비트 (2 워드)를 의미합니다. – Olaf

+0

"float에 대한 포인터를 가져 와서 uint32_t에 대한 포인터로 캐스팅 한 다음 uint32_t 값"- et voila : undefined behavior를 얻습니다. – Olaf

0

SPI는 바이트 지향 직렬 통신 프로토콜입니다. float 및 uint32_t와 같은 데이터 유형은 여러 바이트로 구성됩니다. 그렇다면 바이트 기반 직렬 통신 프로토콜을 통해 멀티 바이트 변수를 어떻게 보냅니 까? 한 번에 한 바이트 씩.

이 코드는 멀티 바이트 변수의 주소를 가져 와서 uint8_t에 대한 포인터로 변환합니다. 그런 다음 바이트 포인터를 사용하여 멀티 바이트 변수의 모든 바이트를 반복하여 한 번에 하나씩 전송합니다.

여기서의 일반적인 프로세스는 serialization입니다. 수신 측에서는 원래의 멀티 바이트 값을 복원하기 위해 비 직렬화를 수행합니다.

uint8_t *로 캐스팅하는이 특정 기술과 반복은 제 경험에서 흔히 볼 수 있습니다. 왜 더 나은 방법을 찾고 있는지 명확하지 않습니다.

+0

부동 소수점 및 정수 유형은 다중 바이트를 사용할 필요가 없습니다. 그것도 단일 바이트로 구성 될 수 있습니다. 옥텟을 염두에두고 있다면 : 많은 SPI 모듈은 더 넓은 전송을 지원합니다. 16 비트. SPI의 표준은 없습니다. 그것은 모두 장치에 따라 다릅니다. – Olaf