1,我这里是还是使用CubeMX直接生成代码,其实也没啥好说的,直接看配置。
然后在ProjectManager里面设置为LL库即可。
2,添加中断使能函数,因为我这里是用中断收发的,所以需要使能,后续所有的操做都在中断里面,主函数while里面啥也不用写。
中断函数:
int ubReceiveIndex=0;
int ubSendIndex=0;
uint8_t aReceiveBuffer[10] = {0};
void I2C1_IRQHandler(void)
{
/* USER CODE BEGIN I2C1_IRQn 0 */
int addr = 0;
if(LL_I2C_IsActiveFlag_ADDR(I2C1))
{
/* Verify the Address Match with the OWN Slave address */
addr = LL_I2C_GetAddressMatchCode(I2C1);
printf("addr:%x\r\n",addr);
if(addr == SLAVE_ADDR)
{
/* Verify the transfer direction, a write direction, Slave enters receiver mode */
if(LL_I2C_GetTransferDirection(I2C1) == LL_I2C_DIRECTION_WRITE)
{
/* Clear ADDR flag value in ISR register */
LL_I2C_ClearFlag_ADDR(I2C1);
/* Enable Receive Interrupt */
LL_I2C_EnableIT_RX(I2C1);
}
else
{
/* Clear ADDR flag value in ISR register */
LL_I2C_ClearFlag_ADDR(I2C1);
LL_I2C_ClearFlag_TXE(I2C1);
LL_I2C_EnableIT_TX(I2C1);
}
}
else
{
/* Clear ADDR flag value in ISR register */
LL_I2C_ClearFlag_ADDR(I2C1);
/* Call Error function */
goto iic_bus_error;
}
}
/* Check TXIS flag value in ISR register */
else if(LL_I2C_IsActiveFlag_TXIS(I2C1))
{
LL_I2C_TransmitData8(I2C1, aReceiveBuffer[ubSendIndex++]);
printf("TXIS:%x\t%x\r\n",aReceiveBuffer[ubSendIndex],aReceiveBuffer[ubSendIndex]);
}
/* Check TXE flag value in ISR register */
else if(LL_I2C_IsActiveFlag_TXE(I2C1))
{
LL_I2C_TransmitData8(I2C1, aReceiveBuffer[ubSendIndex++]);
printf("TXE:%x\t%x\r\n",aReceiveBuffer[ubSendIndex],aReceiveBuffer[ubSendIndex]);
}
/* Check NACK flag value in ISR register */
else if(LL_I2C_IsActiveFlag_NACK(I2C1))
{
LL_I2C_ClearFlag_NACK(I2C1);
printf("NACK\r\n");
}
/* Check RXNE flag value in ISR register */
else if(LL_I2C_IsActiveFlag_RXNE(I2C1))
{
/* Call function Slave Reception Callback */
uint8_t recvData = LL_I2C_ReceiveData8(I2C1);
printf("ubReceiveIndex:%x,LL_I2C_ReceiveData8:%x\r\n",ubReceiveIndex,recvData);
/* Read character in Receive Data register. RXNE flag is cleared by reading data in RXDR register */
aReceiveBuffer[ubReceiveIndex++] = recvData;
}
/* Check STOP flag value in ISR register */
else if(LL_I2C_IsActiveFlag_STOP(I2C1))
{
/* End of Transfer */
LL_I2C_ClearFlag_STOP(I2C1);
/* Call function Slave Complete Callback */
ubReceiveIndex =0;
ubSendIndex = 0;
}
else
{
/* Call Error function */
iic_bus_error:
printf("Error_Callback:");
LL_I2C_DeInit(I2C1);
MX_I2C1_Init();
LL_I2C_EnableIT_RX(I2C1);
LL_I2C_EnableIT_TX(I2C1);
LL_I2C_EnableIT_ADDR(I2C1);
LL_I2C_EnableIT_STOP(I2C1);
LL_I2C_EnableIT_ERR(I2C1);
}
/* USER CODE END I2C1_IRQn 0 */
/* USER CODE BEGIN I2C1_IRQn 1 */
/* USER CODE END I2C1_IRQn 1 */
}
3,然后我们同样生成一个主机测试程序,为了简单这里我直接使用hal库,然后在while里面调用发送以及接受即可。
uint8_t reg_addr = 0;
uint8_t buf[10] = {0};
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(HAL_I2C_Master_Transmit(&hi2c1, 0x55, buf, sizeof(buf), 1000) != HAL_OK)
{
HAL_Delay(2000);
}
HAL_Delay(1000);
if(HAL_I2C_Master_Receive(&hi2c1, 0x55, buf, sizeof(buf), 1000) != HAL_OK)
{
HAL_Delay(2000);
}
HAL_Delay(1000);
// if(HAL_I2C_Mem_Write(&hi2c1, 0x55, reg_addr, I2C_MEMADD_SIZE_8BIT, buf, 5, 1000) != HAL_OK)
// {
// HAL_Delay(2000);
// }
// HAL_Delay(1000);
//
// if(HAL_I2C_Mem_Read(&hi2c1, 0x55, reg_addr, I2C_MEMADD_SIZE_8BIT, buf, 5, 1000) != HAL_OK)
// {
// HAL_Delay(2000);
// }
// HAL_Delay(1000);
}
这里简单说下
HAL_I2C_Master_Transmit
HAL_I2C_Master_Receive
这两个函数相当于是直接发一包数据过去,如果想要单独读取某一个寄存器的数据的话得在填入得buf第一个字节写上寄存器地址,或者直接使用下面的函数
HAL_I2C_Mem_Write
HAL_I2C_Mem_Read
参考了以下代码:STM32L031F6 LL库硬件I2C使用,中断模式_51CTO博客_stm32硬件i2c