I2C 与 stm32f4 使用 HMC5883l
I2C with stm32f4 using HMC5883l
我一直在尝试将我的 HMC5883l 板连接到 stm32f4,但是有些东西无法正常工作。我启动了 i2c,将配置位发送到 REGA、REGB 和 REGMR(模式寄存器),然后通过 USB 连接与 HAL_I2C_MEM_READ 将其发回。
结果是:
- xaxis 和 zaxis 具有相同的值
- 主循环只工作一次,要获得另一个值我需要拔掉 STM
- 我一直在尝试使用示波器检查值(x 轴)是否有变化,但它显示根本没有变化(旋转电路板)
我在这里错过了什么?有没有可能是板子坏了?
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_I2C3_Init();
/* USER CODE BEGIN 2 */
// HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0b00000000 , 1, HMC5883l_Enable_A , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0b00000001 , 1, HMC5883l_Enable_B , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0b00000010 , 1, HMC5883l_MR , 1, 100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_I2C_Mem_Read(&hi2c3, HMC5883l_ADDRESS, HMC5883l_ADD_DATAX_MSB_LSB, 1, DataX, 2, 100);
Xaxis = ((DataX[1] << 8) | DataX[0]);
magn_x_gs = ((float)Zaxis*MAX_RESOLUTION)/(float)INT16_MAX; // conversion
HAL_I2C_Mem_Read(&hi2c3, HMC5883l_ADDRESS, HMC5883l_ADD_DATAY_MSB_LSB , 1, DataY, 2, 100);
Yaxis = ((DataY[1] << 8) | DataY[0]);
magn_y_gs = ((float)Yaxis*MAX_RESOLUTION)/(float)INT16_MAX;
HAL_I2C_Mem_Read(&hi2c3, HMC5883l_ADDRESS, HMC5883l_ADD_DATAZ_MSB_LSB , 1, DataZ, 2, 100);
Zaxis = ((DataZ[1] << 8) | DataZ[0]);
magn_z_gs = ((float)Zaxis*MAX_RESOLUTION)/(float)INT16_MAX;
}
好的,我已经创建了正确的连接版本:)
// variables for receiving DATA
uint8_t DataX[2];
uint16_t Xaxis = 0;
uint8_t DataY[2];
uint16_t Yaxis = 0;
uint8_t DataZ[2];
uint16_t Zaxis = 0;
// adresses
// HMC5883l - ADDRESS
#define HMC5883l_ADDRESS (0x1E << 1)
// CONTROL REG A
#define HMC5883l_Enable_A (0x78)
// CONTROL REG B
#define HMC5883l_Enable_B (0xA0)
// MODE REGISTER
#define HMC5883l_MR (0x00)
// HMC5883l - MSB / LSB ADDRESSES
#define HMC5883l_ADD_DATAX_MSB (0x03)
#define HMC5883l_ADD_DATAX_LSB (0x04)
#define HMC5883l_ADD_DATAZ_MSB (0x05)
#define HMC5883l_ADD_DATAZ_LSB (0x06)
#define HMC5883l_ADD_DATAY_MSB (0x07)
#define HMC5883l_ADD_DATAY_LSB (0x08)
// SUM (MSB + LSB) DEFINE
#define HMC5883l_ADD_DATAX_MSB_MULTI (HMC5883l_ADD_DATAX_MSB | 0x80)
#define HMC5883l_ADD_DATAY_MSB_MULTI (HMC5883l_ADD_DATAY_MSB | 0x80)
#define HMC5883l_ADD_DATAZ_MSB_MULTI (HMC5883l_ADD_DATAZ_MSB | 0x80)
在 main() 内部,我必须创建变量以实际使用 RegSetting 等
uint8_t RegSettingA = HMC5883l_Enable_A;
uint8_t RegSettingB = HMC5883l_Enable_B;
uint8_t RegSettingMR = HMC5883l_MR;
并清除变量:
Xaxis = 0;
Yaxis = 0;
Zaxis = 0;
初始化连接:
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0x00 , 1, &RegSettingA , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0x01 , 1, &RegSettingB , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0x02 , 1, &RegSettingMR , 1, 100);
在 while(1) 循环内部:
// RECEIVE X_axis
HAL_I2C_Mem_Read(&hi2c3,HMC5883l_ADDRESS,HMC5883l_ADD_DATAX_MSB_MULTI,1,DataX,2,100);
Xaxis = ((DataX[1]<<8) | DataX[0])/660.f;
// RECEIVE Y_axis
HAL_I2C_Mem_Read(&hi2c3,HMC5883l_ADDRESS,HMC5883l_ADD_DATAY_MSB_MULTI,1,DataY,2,100);
Yaxis = ((DataY[1]<<8) | DataY[0])/660.f;
// RECEIVE Z_axis
HAL_I2C_Mem_Read(&hi2c3,HMC5883l_ADDRESS,HMC5883l_ADD_DATAZ_MSB_MULTI,1,DataZ,2,100);
Zaxis = ((DataZ[1]<<8) | DataZ[0])/660.f;
由于输出数据是我们得到的 MSB 和 LSB 的连接(LSB 是 0x00),我们必须将数据 [1] 向前移动 8 位。
以下是 STM Studio 的结果:
link
最好的问候:)
我一直在尝试将我的 HMC5883l 板连接到 stm32f4,但是有些东西无法正常工作。我启动了 i2c,将配置位发送到 REGA、REGB 和 REGMR(模式寄存器),然后通过 USB 连接与 HAL_I2C_MEM_READ 将其发回。
结果是:
- xaxis 和 zaxis 具有相同的值
- 主循环只工作一次,要获得另一个值我需要拔掉 STM
- 我一直在尝试使用示波器检查值(x 轴)是否有变化,但它显示根本没有变化(旋转电路板)
我在这里错过了什么?有没有可能是板子坏了?
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USB_DEVICE_Init();
MX_I2C3_Init();
/* USER CODE BEGIN 2 */
// HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0b00000000 , 1, HMC5883l_Enable_A , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0b00000001 , 1, HMC5883l_Enable_B , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0b00000010 , 1, HMC5883l_MR , 1, 100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_I2C_Mem_Read(&hi2c3, HMC5883l_ADDRESS, HMC5883l_ADD_DATAX_MSB_LSB, 1, DataX, 2, 100);
Xaxis = ((DataX[1] << 8) | DataX[0]);
magn_x_gs = ((float)Zaxis*MAX_RESOLUTION)/(float)INT16_MAX; // conversion
HAL_I2C_Mem_Read(&hi2c3, HMC5883l_ADDRESS, HMC5883l_ADD_DATAY_MSB_LSB , 1, DataY, 2, 100);
Yaxis = ((DataY[1] << 8) | DataY[0]);
magn_y_gs = ((float)Yaxis*MAX_RESOLUTION)/(float)INT16_MAX;
HAL_I2C_Mem_Read(&hi2c3, HMC5883l_ADDRESS, HMC5883l_ADD_DATAZ_MSB_LSB , 1, DataZ, 2, 100);
Zaxis = ((DataZ[1] << 8) | DataZ[0]);
magn_z_gs = ((float)Zaxis*MAX_RESOLUTION)/(float)INT16_MAX;
}
好的,我已经创建了正确的连接版本:)
// variables for receiving DATA
uint8_t DataX[2];
uint16_t Xaxis = 0;
uint8_t DataY[2];
uint16_t Yaxis = 0;
uint8_t DataZ[2];
uint16_t Zaxis = 0;
// adresses
// HMC5883l - ADDRESS
#define HMC5883l_ADDRESS (0x1E << 1)
// CONTROL REG A
#define HMC5883l_Enable_A (0x78)
// CONTROL REG B
#define HMC5883l_Enable_B (0xA0)
// MODE REGISTER
#define HMC5883l_MR (0x00)
// HMC5883l - MSB / LSB ADDRESSES
#define HMC5883l_ADD_DATAX_MSB (0x03)
#define HMC5883l_ADD_DATAX_LSB (0x04)
#define HMC5883l_ADD_DATAZ_MSB (0x05)
#define HMC5883l_ADD_DATAZ_LSB (0x06)
#define HMC5883l_ADD_DATAY_MSB (0x07)
#define HMC5883l_ADD_DATAY_LSB (0x08)
// SUM (MSB + LSB) DEFINE
#define HMC5883l_ADD_DATAX_MSB_MULTI (HMC5883l_ADD_DATAX_MSB | 0x80)
#define HMC5883l_ADD_DATAY_MSB_MULTI (HMC5883l_ADD_DATAY_MSB | 0x80)
#define HMC5883l_ADD_DATAZ_MSB_MULTI (HMC5883l_ADD_DATAZ_MSB | 0x80)
在 main() 内部,我必须创建变量以实际使用 RegSetting 等
uint8_t RegSettingA = HMC5883l_Enable_A;
uint8_t RegSettingB = HMC5883l_Enable_B;
uint8_t RegSettingMR = HMC5883l_MR;
并清除变量:
Xaxis = 0;
Yaxis = 0;
Zaxis = 0;
初始化连接:
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0x00 , 1, &RegSettingA , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0x01 , 1, &RegSettingB , 1, 100);
HAL_I2C_Mem_Write(&hi2c3, HMC5883l_ADDRESS, 0x02 , 1, &RegSettingMR , 1, 100);
在 while(1) 循环内部:
// RECEIVE X_axis
HAL_I2C_Mem_Read(&hi2c3,HMC5883l_ADDRESS,HMC5883l_ADD_DATAX_MSB_MULTI,1,DataX,2,100);
Xaxis = ((DataX[1]<<8) | DataX[0])/660.f;
// RECEIVE Y_axis
HAL_I2C_Mem_Read(&hi2c3,HMC5883l_ADDRESS,HMC5883l_ADD_DATAY_MSB_MULTI,1,DataY,2,100);
Yaxis = ((DataY[1]<<8) | DataY[0])/660.f;
// RECEIVE Z_axis
HAL_I2C_Mem_Read(&hi2c3,HMC5883l_ADDRESS,HMC5883l_ADD_DATAZ_MSB_MULTI,1,DataZ,2,100);
Zaxis = ((DataZ[1]<<8) | DataZ[0])/660.f;
由于输出数据是我们得到的 MSB 和 LSB 的连接(LSB 是 0x00),我们必须将数据 [1] 向前移动 8 位。
以下是 STM Studio 的结果: link
最好的问候:)