我正在STM32F74系列处理器上开发一个STM32F74驱动程序。我使用的是STM32CubeMX低级驱动程序,我无法理解为I2C启动和停止寄存器值(CR2)生成的定义。
代码在stm32f7xx_ll_i2c.h中生成,如下所示。
/** @defgroup I2C_LL_EC_GENERATE Start And Stop Generation
* @{
*/
#define LL_I2C_GENERATE_NOSTARTSTOP 0x00000000U
/*!< Don't Generate Stop and Start condition. */
#define LL_I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP)
/*!< Generate Stop condition (Size should be set to 0). */
#define LL_I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN)
/*!< Generate Start for read request. */我的问题是,为什么这些定义中包含了第31位呢?(0x80000000U).参考手册(RM0385)声明"Bits 31:27保留,必须保持在重置值“。我无法决定是修改生成的代码还是保留31位。我很乐意接受一些建议,不管这更有可能是必要的,还是我将通过写到保留位来打破一些事情。

提前感谢!
发布于 2022-06-23 21:04:26
我在这里猜测是因为谁知道图书馆作者的想法是什么?(如果您查看源代码,就不会太多了!)但我想,在调用LL函数时,检查是否使用指定的宏是一个“脏把戏”。
然而,它有严重的缺陷,因为“技巧”仅适用于Cortex-M3/4 STM32变体(例如F1xx、F2xx、F4xx),在这些变体中,I2C外围设备非常不同,而像I2C_CR2这样的寄存器只有15位宽。
诀窍是库函数具有参数检查断言,如:
assert_param(IS_TRANSFER_REQUEST(Request));其中定义了IS_TRANSFER_REQUEST:
#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \
((REQUEST) == I2C_GENERATE_START_READ) || \
((REQUEST) == I2C_GENERATE_START_WRITE) || \
((REQUEST) == I2C_NO_STARTSTOP))这迫使您使用LL定义的宏作为参数,而不是一些自定义或计算的掩码,因为它们都有“未使用”的检查位。
如果这是真正的原因,这是一种不明智的做法,没有设想新的I2C外围。您可能会认为,在写入寄存器之前,从参数中删除了位。我查过了,没有。如果你在每一次通话中都要支付这个开销,这也是不可取的。
作为一种错误检测技术,如果是这样的话,它甚至没有得到一致的应用;例如,所有的GPIO_PIN_xx宏都有16位宽,而且由于它们是掩码而不是引脚号,所以使用bit 31可以防止传递一个实际需要掩码1<<10的文字引脚号10。传递10指的是引脚3和1,而不是10。老实说,这个错误比传递错误的I2C传输请求类型的可能性大得多。
最后,“保留”通常意味着“未使用但可能在未来的实现中使用”,要求您使用“重置值”是确保前向二进制兼容性的一种方法。如果您有这样的设备,无疑会有相应的库更新来支持它,但是它需要重新编译代码。风险很低,如果尝试在使用此位的较新的不兼容部分上运行此二进制文件,则可能会出现问题。
发布于 2022-10-27 09:13:05
我同意Clifford的观点,ST CubeMC / HAL / LL库代码在某些地方是最糟糕的代码。我对诸如"TIMx->CCER &= ~TIM_CCER_CC1E“这样的行有一个特殊的问题,其中TIM_CCER_CC1e被定义为0x0001,CCER寄存器包含应该保持在0的保留位。在整个库代码中都有数百个这样的例子。ST对我的咨询请求保持沉默。
https://stackoverflow.com/questions/72706720
复制相似问题