เริ่มจาก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);
ปัญหาเล็กน้อยกับพารามิเตอร์ที่2ที่อยู่อุปกรณ์ทาส ที่อยู่อุปกรณ์ทาสคือ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 มาแล้ว แต่ฉันคิดว่ามันไม่น่าสนใจสำหรับฟังก์ชั่นดังนั้นมันจึงไม่ใช่ข้อผิดพลาดจริง ๆ ในรหัสของคุณ
3พารามิเตอร์ ( uint8_t *pData
) เป็นตัวชี้ไปยังบัฟเฟอร์ซึ่งมีข้อมูลที่จะส่ง ตอนนี้ในการโทรของคุณพารามิเตอร์ที่ 30x0C
คือข้อมูลจริงของคุณที่อยู่การลงทะเบียน ปัญหาคือมันจะถูกตีความว่าเป็นตัวชี้ (โดยHAL_I2C_Master_Transmit()
) ไปยังตำแหน่งหน่วยความจำซึ่งข้อมูลบางอย่างที่ไม่ได้กำหนดสามารถพบได้
4พารามิเตอร์คือขนาดของบัฟเฟอร์จำนวนไบต์ที่จะส่ง หากคุณต้องการส่งไบต์เดียวพารามิเตอร์นี้ควรเป็น1และไม่ใช่ 10
ผม2ค
เขียนทะเบียน
นี่คือแผนภาพที่เกี่ยวข้องจากแผ่นข้อมูล
ดังนั้นหลังจากที่ส่งที่อยู่ทาสให้กับรถบัสที่สามไบต์มากขึ้นควรจะส่ง: ตัวชี้ลงทะเบียน , MSB ไบต์ , LSB ไบต์ การใช้งานทั่วไปด้วยการลงทะเบียน HAL แบบ 16 บิต:
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
นอกจากนี้ยังมีฟังก์ชั่น register register ที่กำหนดไว้เช่นกันซึ่งมี
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 การเขียนโปรแกรมของแผ่นข้อมูลเพื่อดูรายละเอียดเพิ่มเติม