如何在STM32F0初始化I2C? [英] How to initialize I2C on STM32F0?

查看:1723
本文介绍了如何在STM32F0初始化I2C?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我一直在试图让I2C总线上的ST​​M32F030F4P6 MCU的工作,但有一点运气。

Recently I've been trying to get the I2C bus working on the STM32F030F4P6 MCU, but with little luck.

我使用的是STM32F0模块,并发现大量的资源,为STM32F1 I2C模块的初始化,但没有具体介绍一下STM32F0初始化/转移过程。

I'm using an STM32F0 module and have found plenty of resources for the STM32F1 module I2C initialization, but nothing specific about the STM32F0 initialization/transfer process.

下面是我的初始code:

Here's my initialization code:

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传输code,将在一个永无止境的循环传送数据。这里的code为:

In order to test to see if my setup was correct I designed some I2C transmission code that would transfer data in a never ending loop. Here's the code for that:

while(1)
{
I2C_SlaveAddressConfig(I2C1, RegName);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_NumberOfBytesConfig(I2C1, 8);
I2C_SendData(I2C1,0b00000000);
I2C_GenerateSTOP(I2C1, ENABLE);
}

其中:

寄存器名= 0x75

RegName = 0x75

SDA = GPIO_PIN_10上GPIOA

SDA = GPIO_PIN_10 on GPIOA

SCL = GPIO_PIN_9上GPIOA

SCL = GPIO_PIN_9 on GPIOA

I2C I2C1 =

I2C = I2C1

ownAdrress =为0x68

ownAdrress = 0x68

在我的范围后,我的I2C线启动该code我避开160mV的电压浮动。当我通过code步骤的I2C函数调用中的每一个发生的,完整的,所以这就是为什么我在想,它有更多的东西,以便与我的引脚上的初始化。

When I scope the I2C lines after I start this code I get a floating voltage around 160mV. When I step through the code every one of the I2C function calls happen and complete, so that's why I was thinking that it had something more so to do with my initialization of the pins themselves.

我的问题是非常相似,这个线程,但从未回答:

My problem is very similar to this thread, but was never answered:

<一个href=\"https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F0%20I2C%20$c$c%20doesn%27t%20work&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=1342\" rel=\"nofollow\">https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F0%20I2C%20$c$c%20doesn%27t%20work&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=1342

编辑1:这是我最新的code;仍然没有工作(修改2:更新,以我目前有;感动的东西变成更正确的位置):

Edit 1: Here's my latest code; still not working (Edit 2: Updated to what I currently have; moved things into more correct locations):

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从<一个复用功能href=\"http://www.han-ese.nl/STM32/stm32f0stdlibrary/html/group___g_p_i_o.html#ga0a77617a322562ae84f8d72486032c5d\"相对=nofollow>的STM32F0标准外设bibliotheek 。

As you can see I added the two lines GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); and GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); where I found that GPIO_AF_1 had the alternate function of I2C1 from the STM32F0 Standard Peripheral bibliotheek.

任何其他的想法?我一直在玩与周围的时钟,看看是否改变任何东西,并已加入其他人的code的片段只是为了看看是否有我的设备的输出没有任何影响。

Any other ideas? I've been playing around with the clocks to see if that changed anything and have been adding snippets of other people's code just to see if that has any effect on the output of my device.

修改3:我试图用的指示本指南一个1kΩ的电阻上拉SDA和SCL线至VCC:<一href=\"http://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations\">http://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations

Edit 3: I have tried pulling both the SDA and SCL lines up to VCC with a 1kohm resistor as instructed by this guide: http://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations

- >(3.3V-0.4)/3毫安〜=1kΩ的

->(3.3V-0.4)/3mA ~= 1kohm

修改4:按行我试图输出各种标志位寄存器,通过我的code线去后。特别是这些寄存器: ISR = I2C1-&GT; ISR; CR1 = I2C1-&GT; CR1; CR2 = I2C1-&GT; CR2;

Edit 4: After going through my code line by line I tried outputting various flag bit registers. Specifically these registers: isr = I2C1->ISR;, cr1 = I2C1->CR1;, and cr2 = I2C1->CR2;

标志启动I2C传输与 I2C_TransferHandling(I2C1,0X02,1,I2C_AutoEnd_Mode,I2C_Generate_Start_Write)处理后,我得到; 在0x8001 可破译到两个错误:

The flag I get after initiating the I2C transfer handling with I2C_TransferHandling(I2C1, 0x02, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); was 0x8001 which can be deciphered down to two errors:

的#define I2C_ISR_BUSY((uint32_t的)0x00008000)/ * LT!;总线忙* /

的#define I2C_ISR_TXE((uint32_t的)00000001)/ * LT!;发送数据寄存器空* /

我已经发现了一些变通在此间此链接(删除空格后的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我要找来实现,并会尽快为我尝试出来报到。

I've found some work arounds at this link here (remove the space after https: to go to the link -> stack overflow won't let me post more than 1 link for some reason): 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 that I'm looking to implement and will report back as soon as I try them out.

推荐答案

我注意到你正在映射的引脚 AF_1 那是 UART 功能。

I notice that you are mapping the pins to AF_1 and that is for the UART function.

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

您需要将它们映射到 AF_4 使用 I2C 功能。

You need to map them to AF_4 to use the I2C function.

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_4);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_4);

这篇关于如何在STM32F0初始化I2C?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆