手头在做毕业设计,使用的主控是Artpi,传感器是LSM6DSL。但是由于需要采集高频振动信号,超过了软件IIC的采样速率,于是在各路大佬的帮助下开始了对硬件IIC的移植之路:
首先使用cubemx配制I2C3(SCL->PA8,SDA->PH8)
之后,将生成的main.c和msp.c里的I2C3代码分别移植到新建的HWI2C中:
static void MX_GPIO_Init(void);
static void MX_I2C3_Init(void);
static struct rt_i2c_bus_device i2c3_bus;
I2C_HandleTypeDef hi2c3;
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable /
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
}
static void MX_I2C3_Init(void)
{
/ USER CODE BEGIN I2C3_Init 0 /
/ USER CODE END I2C3_Init 0 /
/ USER CODE BEGIN I2C3_Init 1 /
/ USER CODE END I2C3_Init 1 /
hi2c3.Instance = I2C3;
hi2c3.Init.Timing = 0x00B03FDB;
hi2c3.Init.OwnAddress1 = 0;
hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c3.Init.OwnAddress2 = 0;
hi2c3.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c3) != HAL_OK)
{
Error_Handler();
}
/* Configure Analogue filter
/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/* Configure Digital filter
/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK)
{
Error_Handler();
}
/ USER CODE BEGIN I2C3_Init 2 /
/ USER CODE END I2C3_Init 2 /
}
void HAL_I2C_MspInit(I2C_HandleTypeDef hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C3)
{
/* USER CODE BEGIN I2C3_MspInit 0 /
/ USER CODE END I2C3_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/**I2C3 GPIO Configuration
PA8 ------> I2C3_SCL
PH8 ------> I2C3_SDA
/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/ Peripheral clock enable /
__HAL_RCC_I2C3_CLK_ENABLE();
/ USER CODE BEGIN I2C3_MspInit 1 /
/ USER CODE END I2C3_MspInit 1 */
}
}
之后,请教了大佬,编辑了一段硬件IIC的代码,并添加了
LSM6DSL的包,并根据readme进行了传感器的注册:
static rt_size_t i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
{
struct rt_i2c_msg *msg;
rt_int32_t i, ret;
for(i = 0; i< num; i++)
{
msg = &msgs[i];
if(msg->flags & RT_I2C_RD)
{
//HAL_I2C_Master_Receive(&hi2c3, msg->addr, msg->buf, msg->len, 100);
HAL_I2C_Master_Receive(&hi2c3, msg->addr, msg->buf, msg->len, 100);
}
else
{
HAL_I2C_Master_Transmit(&hi2c3, msg->addr, msg->buf, msg->len, 100);
}
}
ret = i;
return ret;
}
static const struct rt_i2c_bus_device_ops i2c_bus_ops =
{
i2c_xfer,
RT_NULL,
RT_NULL
};
int rt_i2c_hw_init(void)
{
MX_GPIO_Init();
MX_I2C3_Init();
i2c3_bus.ops = &i2c_bus_ops;
rt_i2c_bus_device_register(&i2c3_bus, "hw_i2c");
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_i2c_hw_init);
#include "sensor_st_lsm6dsl.h"
int lsm6dsl_port(void)
{
struct rt_sensor_config cfg;
cfg.intf.dev_name = "hw_i2c";
cfg.intf.user_data = (void *)LSM6DSL_ADDR_DEFAULT;
cfg.irq_pin.pin = RT_PIN_NONE;
rt_hw_lsm6dsl_init("lsm6dsl", &cfg);
return 0;
}
INIT_APP_EXPORT(lsm6dsl_port);
但是现在遇到的问题有两个:
1、没有接上传感器时,仍显示注册成功
2、接上传感器时,使用sensor_polling acce_lsm ,读出数值全为0
请问是否有大佬做过相关的工作,能否提供一些帮助,可以有偿,感激不尽