2017-12-10 18 views
3

16 비트 SPI 메시지를 사용하는 DAC 칩용 SPI 드라이버를 작성하고 있습니다 ... 출력을 나타내는 값은 비트 11에서 비트 4까지입니다 8 비트 DAC). 나는이 마스크를 썼다 그러나 나는 다른 비트에 영향을주지 않고 데이터를 업데이트 달성하는 방법을 모르고에게이 없다 :다른 비트에 영향을 미치지 않고 uint16_t를 uint16_t에 넣는 방법

#define MCP4901_SPI_MASK_DATA    0x0FF0 
//So data mask in binary is 0000 1111 1111 0000 

extern uint16_t mcpA; 

static inline void mcpSetData(uint16_t* mcp, uint8_t value) { 
    //???? 
    *mcp =| value & MCP4901_SPI_MASK_DATA; //NOT WORKING 
} 
+0

왜 당신이 SPI 데이터 레지스터의 일부가 아니라 그것 모두를 쓸 것인가? 그건 말이 안되요. 복잡한 "데이지 체인"하드웨어가 있습니까? – Lundin

+0

@Lundin 다른 설정 비트도 있습니다 (비트 15-12), 단일 비트 일 때 설정할 수 있습니다. 문제는 8 비트 DAC 값을 11에서 4로 변경하는 것입니다. – DEKKER

답변

3

당신은 두 가지 작업 |&의 사용에 대한 정확하지만, 당신이 그들을 사용하지 않는 올바른 순서를 지정하고 피연산자 중 하나를 올바르게 배치하지 않았습니다.

*mcp &= ~MCP4901_SPI_MASK_DATA; // Clear out the middle bits 
*mcp |= ((uint16_t)value) << 4; // Put in the value in the middle 

당신이 하드웨어 레지스터에 기록되어 있기 때문에, 하나의 쓰기가 가능한 부작용을 방지하기 위해 사용되어야한다 :

*mcp = (*mcp & ~MCP4901_SPI_MASK_DATA) | (((uint16_t)value) << 4); 

MCP4901_SPI_MASK_DATA가 여기에

그 일을 올바른 방법입니다 0x0FF0 외부 비트를 지우기 위해 반전 됨. 또는 마스크를 0xF00F으로 정의하고 ~ 연산자를 삭제할 수 있습니다.

8 비트 값을 4로 왼쪽으로 시프트하여 16 비트 가운데에 배치하여 "OR"- 숫자로 만듭니다.

Demo.

+2

매우주의해야합니다. 한 번에 여러 번 SPI 데이터 레지스터에 쓰기 쓰기 또는 읽기에는 플래그가 지워지거나 데이터가 전송되는 것과 같은 부작용이있을 수 있습니다. 특정 하드웨어에 따라 다릅니다. – Lundin

+0

@Lundin 네 말이 맞아, 나는 OP가 하드웨어 레지스터에 쓰고 있다는 사실을 완전히 놓쳤다. 고맙습니다! – dasblinkenlight

+0

@Lundin 토론을 가져 주셔서 감사합니다. 나는'mcpSetData()'함수를 사용하여 U16 변수의 내용을 업데이트했습니다 ... 다른 비트와 설정은 다른 함수로 수행됩니다. 원하는 데이터가 준비되면 단일 명령 (STM32의 HAL_SpiTransmit)을 사용하여 SPI로 푸시합니다. 그것은 지금 잘 작동합니다 :) – DEKKER