前言
在參考Cube軟件包中I2C例程后, 根據(jù)應(yīng)用需要新增了一路I2C接口,結(jié)果新增I2C無法收發(fā)數(shù)據(jù)。本文主要對問題進(jìn)行描述,分析產(chǎn)生原因,提供解決方法。
問題描述
如前言所述,現(xiàn)象表現(xiàn)為I2C無法收發(fā)數(shù)據(jù)。得無法理解之處,在于之前已經(jīng)完成了I2C的移植工作,并且運行正?!,F(xiàn)在遵照正確的方式,新添一路I2C接口,只是更改了對應(yīng)的I2C接口及引腳,為什么無法收發(fā)數(shù)據(jù)。簡化測試程序如下。
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable GPIOTX/RX clock */
I2Cx_SCL_GPIO_CLK_ENABLE();
I2Cx_SDA_GPIO_CLK_ENABLE();
/* Enable I2Cxclock */
I2Cx_CLK_ENABLE();
/*##-2- Configureperipheral GPIO ###########*/
/* I2C TX GPIOpin configuration */
GPIO_InitStruct.Pin= I2Cx_SDA_PIN;
GPIO_InitStruct.Mode= GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull= GPIO_PULLUP;
GPIO_InitStruct.Speed= GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate= I2Cx_SCL_SDA_AF;
HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT,&GPIO_InitStruct);
GPIO_InitStruct.Pin= I2Cx_SCL_PIN;
HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT,&GPIO_InitStruct);
I2cHandle.Instance= I2Cx;
I2cHandle.Init.ClockSpeed= 100000;
I2cHandle.Init.DutyCycle= I2C_DUTYCYCLE;
I2cHandle.Init.OwnAddress1= 0;
I2cHandle.Init.AddressingMode= I2C_ADDRESSINGMODE_7BIT;
I2cHandle.Init.DualAddressMode= I2C_DUALADDRESS_DISABLE;
I2cHandle.Init.OwnAddress2= 0;
I2cHandle.Init.GeneralCallMode= I2C_GENERALCALL_DISABLE;
I2cHandle.Init.NoStretchMode= I2C_NOSTRETCH_DISABLE;
if(HAL_I2C_Init(&I2cHandle)!= HAL_OK)
{
/* InitializationError */
Error_Handler();
}
while(1)
{
HAL_I2C_Master_Transmit(&I2cHandle,(uint16_t)I2C_ADDRESS,
(uint8_t*)aTxBuffer, TXBUFFERSIZE, 10000);
}
二 現(xiàn)象分析
將上述程序在STM32F469i-Disco板上實現(xiàn),復(fù)現(xiàn)現(xiàn)象并尋找規(guī)律。發(fā)現(xiàn)規(guī)律如下:
分析上表可以發(fā)現(xiàn)問題的產(chǎn)生與硬件設(shè)計有一定關(guān)系。觀察發(fā)現(xiàn),如果I2C沒有外部上拉時,會導(dǎo)致問題產(chǎn)生。
通過單步調(diào)試,定位于HAL_I2C_Master_Transmit(),在這個函數(shù)中調(diào)用的I2C_WaitOnFlagUntilTimeout()無法執(zhí)行異常,返回HAL_BUSY,導(dǎo)致了I2C寫功能失敗。在I2C_WaitOnFlagUntilTimeout函數(shù)內(nèi)部,是對忙標(biāo)志位BUSY@I2Cx_SR2的檢測。通過對參考手冊的閱讀(如下截圖所述),如果在未占用I2C總線時,SDA或SCL引腳存在低電平,則意味著總線處于忙狀態(tài)。這種檢測機制在I2C接口失能時依然工作。
結(jié)合程序中調(diào)用順序,在I2C3時鐘使能時,雖然I2C3沒有使能,但是忙狀態(tài)檢測已經(jīng)開始。由于對應(yīng)的SCL引腳上無上拉電阻,并且由于還未對I2C3的SCL引腳進(jìn)行配置。此時SCL引腳為浮空輸入狀態(tài),實際測量發(fā)現(xiàn)為低電平,BUSY標(biāo)志被置位。
三 解決方法
通過現(xiàn)象及分析,可了解到問題可通過硬件或者軟件解決。
硬件方面,為SDA、SCL引腳提供外部的I2C上拉電阻,問題不在出現(xiàn)。
軟件方面,發(fā)現(xiàn)在對SCL、SDA引腳配置時會啟用內(nèi)部上拉。通過將I2C時鐘使能代碼放于I2C引腳配置語句后面,問題也不再出現(xiàn)。
需要注意, I2C的SDA、SCL引腳內(nèi)部上拉電阻,為弱上拉。使用者可以通過對應(yīng)型號STM32的數(shù)據(jù)手冊,查看對應(yīng)引腳的上拉電阻,以便判斷是否能夠滿足應(yīng)用需要。如下為STM32F469上拉電阻信息截圖。
==================================
-
I2C
+關(guān)注
關(guān)注
28文章
1484瀏覽量
123619 -
數(shù)據(jù)收發(fā)
+關(guān)注
關(guān)注
0文章
8瀏覽量
7750
原文標(biāo)題:I2C配置順序引發(fā)的異常案例
文章出處:【微信號:STM32_STM8_MCU,微信公眾號:STM32單片機】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論