最近我一直在尝试使用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