HAL_I2C_Master_Transmit()
기능 부터 시작하겠습니다 . 선언을 확인하면 :
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
슬레이브 장치 주소 인 두 번째 매개 변수에 사소한 문제가 있습니다. 슬레이브 장치 주소는 b1010000
8 비트 형식으로 완성 0xA0
하면 말한 것처럼입니다. 이제 이것을 전달할 때 HAL_I2C_Master_Transmit()
R / W 비트를 수동으로 설정할 필요가 없습니다. HAL이 대신 해줍니다. 따라서 HAL_I2C_Master_Transmit()
전송 된 R / W 비트 를 호출 하면 쓰기 작업을 나타내는 자동으로 0이HAL_I2C_Master_Receive()
되고, 전송 된 R / W 비트 를 호출 하면 쓰기 작업을 나타내는 자동으로 1 이됩니다 . R / W 값을 혼합했지만 함수에 신경 쓰지 않는 비트라고 생각하므로 코드의 실제 오류는 아닙니다.
세 번째 매개 변수 ( uint8_t *pData
)는 전송할 데이터가 들어 있는 버퍼에 대한 포인터 입니다. 이제 호출에서 3 번째 매개 변수는 실제 데이터 인 레지스터 주소입니다. 문제는 정의되지 않은 데이터를 찾을 수있는 메모리 위치에 대한 포인터로 해석 된다는 것입니다.0x0C
HAL_I2C_Master_Transmit()
넷째 매개 변수 인 버퍼의 크기 (바이트 단위)의 개수가 전송된다. 단일 바이트 를 보내려면 이 매개 변수는 10이 아닌 1 이어야합니다 .
나는2씨
레지스터 쓰기
데이터 시트의 해당 다이어그램은 다음과 같습니다.
따라서 슬레이브 주소를 버스로 보낸 후 register pointer , MSB byte , LSB byte 등 3 바이트를 더 전송해야합니다 . 16 비트 레지스터를 작성하는 HAL을 사용한 일반적인 구현 :
void write_register(uint8_t register_pointer, uint16_t register_value)
{
uint8_t data[3];
data[0] = register_pointer; // 0x0C in your example
data[1] = register_value>>8; // MSB byte of 16bit data
data[2] = register_value; // LSB byte of 16bit data
HAL_I2C_Master_Transmit(&hi2c1, 0xA0, data, 3, 100); // data is the start pointer of our array
}
당신의 가치를 가진 예 : write_register(0x0C, 0x0054);
또는 레지스터 주소 및 주소 크기를 전달하기위한 추가 매개 변수가있는 HAL 정의 레지스터 쓰기 기능도 사용할 수 있습니다.
void write_register(uint8_t register_pointer, uint16_t register_value)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&hi2c1, 0xA0, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(®ister_value), 2, 100);
/* Check the communication status */
if(status != HAL_OK)
{
// Error handling, for example re-initialization of the I2C peripheral
}
}
이제 HAL_I2C_Master_Receive()
기능은 다른 것과 거의 동일합니다.
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
차이점은 3 번째 파라미터는 수신 된 데이터 가 저장 될 버퍼에 대한 포인터라는 것입니다. 그것은 0x02
당신의 코드에 있으며 당신의 목적이 무엇인지 알지 못하지만 (불행히도 임의의 메모리 위치에 대한) 포인터로 해석됩니다.
레지스터 읽기
나는2씨나는2씨
void read_register(uint8_t register_pointer, uint8_t* receive_buffer)
{
// first set the register pointer to the register wanted to be read
HAL_I2C_Master_Transmit(&hi2c1, 0xA0, ®ister_pointer, 1, 100); // note the & operator which gives us the address of the register_pointer variable
// receive the 2 x 8bit data into the receive buffer
HAL_I2C_Master_Receive(&hi2c1, 0xA0, receive_buffer, 2, 100);
}
예:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
HAL 정의 레지스터 읽기 기능도 있습니다.
uint16_t read_register(uint8_t register_pointer)
{
HAL_StatusTypeDef status = HAL_OK;
uint16_t return_value = 0;
status = HAL_I2C_Mem_Read(&hi2c1, 0xA0, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 100);
/* Check the communication status */
if(status != HAL_OK)
{
}
return return_value;
}
을 통해 읽기 8.5 프로그래밍 의 섹션 데이터 시트 자세한 내용은.