历史上的今天
今天是:2024年11月26日(星期二)
2018年11月26日 | STM32L151 I2C从机实现
2018-11-26 来源:eefocus
网上很多STM32的I2C都是基于F系列去实现的,其他的系列的芯片实现很少。
而对于STM32L151系列的I2C从机设计,用STM32CubeMX生成的简单DEMO里,就会有提供库接口实现,比如:
HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
但其实,如果是调用库接口,只能实现从机接收或者是只实现从机发送实现,调用现成接口貌似很难做到既接收有发送(至少个人没有试验出来)。
不过如果使用中断,实现起来就非常简单了。
首先使用STM32CubeMX生成一个简单的I2C demo,设置在MX_I2C1_Init接口里面设置好从机的一些基本信息(从机地址,使用几位从机地址等);
/* I2C1 init function */
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0x90;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
然后重写I2C1_EV_IRQHandler中断函数,并使能中断;
void I2C1_EV_IRQHandler(void)
{
if (hi2c1.Instance->SR1 & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {
HAL_I2C_ER_IRQHandler(&hi2c1);
} else {
HAL_I2C_EV_IRQHandler(&hi2c1);
}
}
至于中断函数就直接使用工具生成的就可以了。
值得注意的是:
STM32L151芯片在工具生成的DEMO里面,从机模式无论是接收还是发送都是一个字节一个字节进行的,如果你需要接收或者是发送多个字节,需要稍微更改一下接收和发送的函数。
static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c)
{
while(hi2c->XferSize > 0U)
{
/* Wait until TXE flag is set */
if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, 0xffffffff, 0) != HAL_OK)
{
/* Disable Address Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
return HAL_ERROR;
}
else
{
return HAL_TIMEOUT;
}
}
/* Write data to DR */
hi2c->Instance->DR = (*hi2c->pBuffPtr++);
hi2c->XferCount--;
hi2c->XferSize--;
}
if((hi2c->XferCount == 0U) && (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN))
{
/* Last Byte is received, disable Interrupt */
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
/* Set state at HAL_I2C_STATE_LISTEN */
hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
hi2c->State = HAL_I2C_STATE_LISTEN;
/* Call the Tx complete callback to inform upper layer of the end of receive process */
HAL_I2C_SlaveTxCpltCallback(hi2c);
}
return HAL_OK;
}
static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c)
{
while(hi2c->XferCount != 0U)
{
/* Wait until RXNE flag is set */
if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, 0xffffffff, 0) != HAL_OK)
{
/* Disable Address Acknowledge */
CLEAR_BIT(hi2c->Instance->CR1, I2C_CR1_ACK);
if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT)
{
return HAL_TIMEOUT;
}
else
{
return HAL_ERROR;
}
}
/* Read data from DR */
(*hi2c->pBuffPtr++) = hi2c->Instance->DR;
hi2c->XferCount--;
if((hi2c->XferCount == 0U) && (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN))
{
/* Last Byte is received, disable Interrupt */
__HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);
/* Set state at HAL_I2C_STATE_LISTEN */
hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
hi2c->State = HAL_I2C_STATE_LISTEN;
/* Call the Rx complete callback to inform upper layer of the end of receive process */
HAL_I2C_SlaveRxCpltCallback(hi2c);
}
}
return HAL_OK;
}
改造了之后,就可以直接接收/发送多个字节的数据啦啦啦~
史海拾趣
|
射频(RF)电路的电路板布局应在理解电路板结构、电源布线和接地的基本原则的基 础上进行。本文探讨了相关的基本原则,并提供了一些实用的、经过验证的电源布 线、电源旁路和接地技术,可有效提高RF 设计的性能指标。考虑到实际设计中 PLL 杂散信 ...… 查看全部问答> |
|
在使用:ARM926EJ-S MP2530F方案的机器上,运行程序报非法应用程序错误 在使用ARM926EJ-S MP2530F方案的导航仪上,程序运行报非法应用程序错误,请问怎么办?怎样做与系统无关的程序?… 查看全部问答> |
|
在arm上有7种模式:user fiq irq 。。。。 为什么要作这样的划分?作用是什么? 每一种模式的限制在哪里? 有没有什么书,会比较详细的介绍这些问题的? 谢谢。… 查看全部问答> |
|
如题,还有我准备用asp.net来做这个网页,怎么控制这个网页的长宽比呢??就是说大小问题.本机是800*600的大小.怎么适应pda的屏幕呢??… 查看全部问答> |
|
如果你采用的硅版本是A1或者A2的话,有些时候程序出现莫名奇妙的问题,有可能不是你的错,看看勘误文档能不能帮你迅速找到出错的地方,以及在使用的时候去避免这些芯片本身的小问题,应该是有点帮助的。 [ 本帖最后由 academic 于 2010-11-16 09: ...… 查看全部问答> |
|
我做的双电源设计 锂电池3.6V---二极管-------MSP430 ××CC DVCC 纽扣电池3V------二极管------msp430 ××CC 用作外部电池断电以后 RAM 数据保持 不知是否可行,还有就是不知道二极管再导通后的功耗多大 请教楼住 有没有成 ...… 查看全部问答> |
|
比亚迪汽车车载导航用的是winc5.0的系统ARM9+64MB内存的一体机,我们研究发现只有用他原厂的导航软件才有声音出来,如果换了导航软件就不出声了。具体分析了原厂导航软件的启动过程,发现他是调用了coredll、dll文件的函数了?我想问问一体机的注册 ...… 查看全部问答> |




