|
关于i2c硬件配置读取lsm6dsow传感器:
i2c3_scl :pg7
i2c3_sda:pg8
int I2CInit(int Index)
{
if (Index == I2C3_ID){
/*##-1- Configure the I2C peripheral ######################################*/
I2cHandle[Index].Instance = I2C3;
I2cHandle[Index].Init.Timing = 0x307075B1;
I2cHandle[Index].Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2cHandle[Index].Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2cHandle[Index].Init.OwnAddress1 = 0;
I2cHandle[Index].Init.OwnAddress2 = 0;
I2cHandle[Index].Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2cHandle[Index].Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if(HAL_I2C_Init(&I2cHandle[Index]) != HAL_OK){
printf("I2C3 init error \r\n");
while(1);
}
/* Enable the Analog I2C Filter使能模拟i2c过滤器 */
HAL_I2CEx_ConfigAnalogFilter(&I2cHandle[Index],I2C_ANALOGFILTER_ENABLE);
}
return 0;
}
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
static DMA_HandleTypeDef hdma_tx;
static DMA_HandleTypeDef hdma_rx;
if (hi2c->Instance == I2C3){
/*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C3;
RCC_PeriphCLKInitStruct.I2c3ClockSelection = RCC_I2C3CLKSOURCE_SYSCLK;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
/*##-2- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO TX/RX clock */
__HAL_RCC_GPIOG_CLK_ENABLE();
/* Enable I2Cx clock */
__HAL_RCC_I2C3_CLK_ENABLE();
/* Enable DMAx clock */
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMAMUX1_CLK_ENABLE();
//pg8是sda、pg7是sck
/*##-3- Configure peripheral GPIO ##########################################*/
/* I2C TX GPIO pin configuration 发送gpio芯片配置*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;//开漏
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//高速
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3; //引脚复用
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* I2C RX GPIO pin configuration 读gpio芯片配置*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/*##-4- Configure the DMA Channels #########################################*/
/* Configure the DMA handler for Transmission process */
hdma_tx.Instance = DMA1_Channel2;//通道2发送
hdma_tx.Init.Request = DMA_REQUEST_I2C3_TX;//i2c3发射
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;//内存到外设模式
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;//外设地址
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;//内存地址递增
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//外设数据以字节对齐
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;//内存数据以字节对齐
hdma_tx.Init.Mode = DMA_NORMAL;//正常模式传输
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;//低优先级
if(HAL_DMA_Init(&hdma_tx)!= HAL_OK){
printf("hdma_tx error\r\n");
}
/* Associate the initialized DMA handle to the the I2C handle */
__HAL_LINKDMA(hi2c, hdmatx, hdma_tx);
/* Configure the DMA handler for Transmission process */
hdma_rx.Instance = DMA1_Channel3;//接收
hdma_rx.Init.Request = DMA_REQUEST_I2C3_RX;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;//外设到内存
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
if(HAL_DMA_Init(&hdma_rx)!= HAL_OK){
printf("hdma_rx error\r\n");
}
/* Associate the initialized DMA handle to the the I2C handle */
__HAL_LINKDMA(hi2c, hdmarx, hdma_rx);
/*##-5- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt (I2Cx_TX) */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* NVIC configuration for DMA transfer complete interrupt (I2Cx_RX) */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
/*##-6- Configure the NVIC for I2C #########################################*/
/* NVIC for I2Cx */
HAL_NVIC_SetPriority(I2C3_ER_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(I2C3_ER_IRQn);
HAL_NVIC_SetPriority(I2C3_EV_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
{
static DMA_HandleTypeDef hdma_tx;
static DMA_HandleTypeDef hdma_rx;
if (hi2c->Instance == I2C3)
{
/* I2C3:SCL: PG7 SDA: PG8 */
/*##-1- Reset peripherals ##################################################*/
__HAL_RCC_I2C3_FORCE_RESET();
__HAL_RCC_I2C3_RELEASE_RESET();
/*##-2- Disable peripherals and GPIO Clocks #################################*/
/* Configure I2C Tx as alternate function */
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_7);
/* Configure I2C Rx as alternate function */
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_8);
/*##-3- Disable the DMA Channels ###########################################*/
/* De-Initialize the DMA Channel associated to transmission process */
HAL_DMA_DeInit(&hdma_tx);
/* De-Initialize the DMA Channel associated to reception process */
HAL_DMA_DeInit(&hdma_rx);
/*##-4- Disable the NVIC for DMA ###########################################*/
HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn);
HAL_NVIC_DisableIRQ(DMA1_Channel3_IRQn);
/*##-5- Disable the NVIC for I2C ###########################################*/
HAL_NVIC_DisableIRQ(I2C3_ER_IRQn);
HAL_NVIC_DisableIRQ(I2C3_EV_IRQn);
}
}
void I2C_Read(int Index,unsigned char DeviceAddress,int AddressStart,unsigned char *pReadBuf,int ReadNum)
{
/* LPS33K_I2C_ADD 0x5D --->0xBA LPS33K_ID 0xB1 */
/* NST118_I2C_ADD 0x48 --->0x90 */
/*lsdow_i2c_add 0xD5 */
if(Index == I2C3_ID){
uint8_t ret = HAL_I2C_Mem_Read_DMA(&I2cHandle[Index],(uint16_t)((DeviceAddress << 1)),
AddressStart, I2C_MEMADD_SIZE_8BIT, pReadBuf, ReadNum);
if(ret == 0)
printf("hal ok\r\n");
else if(ret == 1){
printf("hal error\r\n");
}
else if(ret == 2){
printf("hal busy\r\n");
}
else
printf("hal timeout\r\n");
/* Wait for the end of the transfer */
while (HAL_I2C_GetState(&I2cHandle[Index]) != HAL_I2C_STATE_READY){
};
}
}
void I2C_Write(int Index,unsigned char DeviceAddress,int AddressStart,unsigned char *pWriteBuf,int WriteNum)
{
/* Write EEPROM_PAGESIZE */
if(HAL_I2C_Mem_Write_DMA(&I2cHandle[Index] , (uint16_t)(DeviceAddress<<1), AddressStart,
I2C_MEMADD_SIZE_8BIT, (unsigned char*)pWriteBuf, WriteNum)!= HAL_OK)
{
/* Writing process Error */
// Error_Handler();
printf("HAL_I2C_Mem_Write_DMA error ! \r\n");
}
/* Wait for the end of the transfer */
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it抯 busy you need to wait for the end of current
transfer before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (HAL_I2C_GetState(&I2cHandle[Index]) != HAL_I2C_STATE_READY){
} ;
}
static int32_t platform_write1(void *handle, uint8_t reg,uint8_t *bufp, uint16_t len)
{
I2C_Write(I2C3_ID,LSM6DSO_I2C_ADD_L,reg,(uint8_t*)bufp,len);
return 0;
}
//i2c3读寄存器操作
static int32_t platform_read1(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
I2C_Read(I2C3_ID,LSM6DSO_I2C_ADD_L,reg,(uint8_t*)bufp,len);
printf("reg = 0x%x\r\n",reg);
return 0;
}
static void platform_delay(uint32_t ms)
{
HAL_Delay(ms);
}
void LSM6DSO_Init(void)
{
uint8_t whoamI,rst;
lsm6dso_dev_ctx.write_reg1 = platform_write1;
lsm6dso_dev_ctx.read_reg1 = platform_read1;
lsm6dso_dev_ctx.handle = NULL;
platform_delay(BOOT_TIME);
lsm6dso_device_id_get(&lsm6dso_dev_ctx, &whoamI);
printf("whoamI = 0x%x\r\n",whoamI);
}
|
-
|