当前位置:首页 > 编程笔记 > 正文
已解决

LL库实现I2C硬件从机

来自网友在路上 170870提问 提问时间:2023-09-28 10:53:01阅读次数: 70

最佳答案 问答题库708位专家为你答疑解惑

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

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"LL库实现I2C硬件从机":http://eshow365.cn/6-15155-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!