最近我一直在嘗試使用STM32F030F4P6 MCU工作的I2C總線,但運氣不大。如何在STM32F0上初始化I2C?
我正在使用一個STM32F0模塊,並已經找到了大量用於STM32F1模塊I2C初始化的資源,但沒有具體說明STM32F0初始化/傳輸過程。
這裏是我的初始化代碼:
void i2c_init(uint8_t ownAddress)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// Enable GPIOA clocks
RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
// Configure I2C1 clock and GPIO
GPIO_StructInit(&GPIO_InitStructure);
/* I2C1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* I2C1 SDA and SCL configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
/* Configure I2C1 */
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
//I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
爲了測試,看看我的設置是正確的,我設計了一些I2C傳輸代碼,將在永無止境的循環傳輸數據。下面是該代碼:
while(1)
{
I2C_SlaveAddressConfig(I2C1, RegName);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_NumberOfBytesConfig(I2C1, 8);
I2C_SendData(I2C1,0b00000000);
I2C_GenerateSTOP(I2C1, ENABLE);
}
其中:
寄存器名= 0x75
SDA = GPIO_PIN_10上GPIOA
SCL = GPIO_PIN_9上GPIOA
I2C = I2C1
ownAdrress = 0x68
當我在啓動此代碼後對I2C線進行範圍調整時,我會獲得大約160mV的浮動電壓。當我逐步完成代碼時,每一個I2C函數調用都會發生並完成,所以這就是爲什麼我認爲它更像是我自己初始化引腳的原因。
我的問題是非常相似,這個線程,但從未回答:
編輯1:這是我最新的代碼;仍然沒有工作(編輯2:更新什麼,我現在有;感動的事情到更正確的位置):
void i2c_init(uint8_t ownAddress)
{
/* TypeDefs for GPIOA and I2C1 */
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
/* Enable GPIOA clocks and I2C1 clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/* Configure I2C1 clock and GPIO */
GPIO_StructInit(&GPIO_InitStructure);
/* I2C1 SDA and SCL configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //UP
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
/* GPIO AF Configuration -> GPIO_AF_1: USART2, CEC, Tim3, USART1, USART2,EVENTOUT, I2C1, I2C2, TIM15 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* I2C1 Reset */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
//I2C_DeInit(I2C1);
/* Configure I2C1 */
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
//I2C_AcknowledgeConfig(I2C1, ENABLE);
}
正如你可以看到我添加了兩行GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
和GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
在那裏我發現GPIO_AF_1有I2C1的備用功能從the STM32F0 Standard Peripheral bibliotheek。
還有其他想法嗎?我一直在玩弄時鐘,看看是否改變了任何內容,並且已經添加了其他人的代碼片斷,只是爲了看看它是否對我的設備輸出有任何影響。
編輯3:我曾嘗試用1kΩ的電阻上拉SDA和SCL線至VCC通過本指南的指示:https://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations
- >(3.3V-0.4)/3毫安〜=1kΩ的
編輯4:經過我的代碼行,我試着輸出各種標誌位寄存器。特別是這些寄存器:isr = I2C1->ISR;
,cr1 = I2C1->CR1;
,並且cr2 = I2C1->CR2;
發起I2C傳輸與I2C_TransferHandling(I2C1, 0x02, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);
處理後,我得到的標誌是0x8001
可以破譯到兩個錯誤:
#define I2C_ISR_BUSY ((uint32_t)0x00008000) /*!< Bus busy */
和
#define I2C_ISR_TXE ((uint32_t)0x00000001) /*!< Transmit data register empty */
我找到了一些解決辦法在這裏的鏈接(刪除https後的空間:去鏈接 - >由於某種原因,堆棧溢出不會讓我發佈超過1個鏈接):https://my.st.com/public/STe2ecommunities/mcu /Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FSTM32L151RB%20I2C%20Busy%20flag%20always%20set & FolderCTID = 0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B & currentviews = 690,我正在尋找實施和將只要我嘗試一下就回報。
可能是一個愚蠢的問題。你有SDA和SDL上的pullups嗎?你運行這段代碼之前它們高嗎? – DoxyLover 2014-11-04 20:18:32
嘿有DoxyLover, 試過這個,並沒有工作。在我運行此代碼之前,不要相信它們被設置得很高。 – Stroodlemuffin 2014-11-04 22:15:44
你有什麼精確連接到I2C線?什麼是從屬設備?您是否知道每條I2C線和Vcc之間必須連接上拉電阻? – DoxyLover 2014-11-04 22:37:46