你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F0 IIC slave mode  

[复制链接]
红玫瑰的偏爱 发布时间:2015-7-1 10:42
阅读主题, 点击返回1楼
1 收藏 4 评论37 发布时间:2015-7-1 10:42
37个回答
chhui000 回答时间:2016-12-26 12:03:22
好东西 赞
5265325 回答时间:2016-12-27 13:01:16
///.. 回答时间:2017-3-7 20:19:46
你好啊,我这几天也在看IIC的从机,我用的是STM32F030F4.我用原子的开发板的at24c02的软件模拟IIC作为主机,我自己写一个从机。能匹配到ADDCODE,但是接收不到数据,我在想是不是时序没有匹配或者是,主机等待ACK的时候由软件发送一个ack。
///.. 回答时间:2017-3-7 20:22:19
本帖最后由 ///.. 于 2017-3-7 20:23 编辑

我在网上找到你们的代码。我复制了一下。有些问题想了解一下
void I2C_GPIO_Configuration(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;

        /* Enable GPIOA clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);   
        /*!< sEE_I2C Periph clock enable */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
        /*!< GPIO configuration */
        /*!< Configure sEE_I2C pins: SCL */
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//GPIO_Mode_IN
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;//open-drain
        GPIO_Init(GPIOA , &GPIO_InitStruct);

        /*!< Configure sEE_I2C pins: SDA */
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
        GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* Connect PXx to I2C_SCL*/
        GPIO_PinAFConfig( GPIOA , GPIO_PinSource9, GPIO_AF_4);
        /* Connect PXx to I2C_SDA*/
        GPIO_PinAFConfig( GPIOA ,GPIO_PinSource10, GPIO_AF_4);
}

//IIC从模式配置,在配置时,需要设置地址,在这里设置为0XA0,而从设备的时钟属于被动模式,有IIC的主端确定。

void I2C_Configuration(void)
{
        I2C_InitTypeDef I2C_InitStruct;
         NVIC_InitTypeDef NVIC_InitStructure;
        
        /* I2C configuration */
        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
        I2C_InitStruct.I2C_DigitalFilter = 0x00;
        I2C_InitStruct.I2C_OwnAddress1 = ADDR;
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   
        I2C_InitStruct.I2C_Timing = 0xb0420f13;                //100Kbits
        /* I2C Peripheral Enable */
        I2C_Cmd(I2C1, ENABLE);
        /* Apply I2C configuration after enabling it */
        I2C_Init(I2C1, &I2C_InitStruct);
        
    I2C1->CR1 |= (I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_TXIE | I2C_CR1_RXIE);
    //---------------------------- Peripheral and DMA interrupts Initialization ------------------
    // Initialize I2C1 interrupts
    /* Enable the IRQ channel */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   
    /* Configure NVIC for I2C1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
    NVIC_Init(&NVIC_InitStructure);        
        
}

//下面是IIC中断函数的实现

void I2c_Init(void)
{
        I2C_GPIO_Configuration();
        I2C_Configuration();
}

void I2C1_IRQHandler(void)
{
        u32 AddCode;
//        I2C_ClearITPendingBit(I2C1, I2C_ISR_ADDR | I2C_ISR_STOPF |I2C_ISR_ADDCODE );
        __IO uint32_t I2CFlagStatus = 0x00000000;
        I2CFlagStatus = (uint32_t)(I2C1->ISR & (uint16_t)0x0000100FE);
        
//        printf("recv data\r\n");
        if ((I2CFlagStatus & I2C_ISR_ADDR) != 0)
          {
                AddCode = (I2C1->ISR & 0xfe0000);                        //读取ADDCODE   32:17位
                printf("匹配地址2 0x%x: \r\n",AddCode >> 17 );
               
            if(I2C1->ISR&I2C_ISR_DIR) //tx mode
        {
                        printf("发送模式 \r\n");
            Tx_count = 0;
                 I2C1->ISR |= I2C_ISR_TXE;
            I2C1->ICR |= I2C_ICR_ADDRCF;
                        
                        if(I2C_GetITStatus( I2C1, I2C_IT_RXNE) != 0)
                        {
                                Rx_buffer[Rx_count++]=I2C_ReceiveData(I2C1);
                                if(Rx_count>=Rx_MAX)
                                {
                                        Rx_count=0;
                                        //rx  ok
                                }
                                printf("Rx_buffer : %s\r\n",Rx_buffer);
                        }
        }
                if((I2C1->ISR&I2C_ISR_DIR)==0) //rx mode
        {
                        printf("接收模式 \r\n");
                        Rx_count= 0;
                        I2C1->ICR |= I2C_ICR_ADDRCF;
        }
    }
        else if(I2C_GetITStatus( I2C1, I2C_IT_RXNE) != 0)
        {
                Rx_buffer[Rx_count++]=I2C_ReceiveData(I2C1);
                if(Rx_count>=Rx_MAX)
        {
            Rx_count=0;
                        //rx  ok
        }
                printf("Rx_buffer : %s\r\n",Rx_buffer);
        }
        else if ((I2CFlagStatus & I2C_ISR_TXIS) != 0)
        {
                I2C_SendData(I2C1,Tx_buffer[Tx_count++]);
                if(Tx_count >= Tx_MAX)
                {
                        Tx_count = 0;
                        //tx ok
                }
        }
        else if ((I2CFlagStatus & I2C_ISR_STOPF) != 0)
        {
                printf("停止检查标志位 \r\n");
                I2C1->ICR |= I2C_ICR_STOPCF;
                Rx_count = 0;
                Tx_count = 0;
        }
}

这个是可以匹配到ADDCODE ,但是没有接收到数据的,我没仔细看这个时序寄存器的配置。不知道是不是由于时序不匹配造成没有接收到数据,还是因为ack没有给出造成读不到数据的。
///.. 回答时间:2017-3-7 20:25:31
我在网上找到你们的代码。我复制了一下。有些问题想了解一下
void I2C_GPIO_Configuration(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;

        /* Enable GPIOA clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);   
        /*!< sEE_I2C Periph clock enable */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
        /*!< GPIO configuration */
        /*!< Configure sEE_I2C pins: SCL */
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//GPIO_Mode_IN
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;//open-drain
        GPIO_Init(GPIOA , &GPIO_InitStruct);

        /*!< Configure sEE_I2C pins: SDA */
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
        GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* Connect PXx to I2C_SCL*/
        GPIO_PinAFConfig( GPIOA , GPIO_PinSource9, GPIO_AF_4);
        /* Connect PXx to I2C_SDA*/
        GPIO_PinAFConfig( GPIOA ,GPIO_PinSource10, GPIO_AF_4);
}

//IIC从模式配置,在配置时,需要设置地址,在这里设置为0XA0,而从设备的时钟属于被动模式,有IIC的主端确定。

void I2C_Configuration(void)
{
        I2C_InitTypeDef I2C_InitStruct;
         NVIC_InitTypeDef NVIC_InitStructure;
        
        /* I2C configuration */
        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
        I2C_InitStruct.I2C_DigitalFilter = 0x00;
        I2C_InitStruct.I2C_OwnAddress1 = ADDR;
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   
        I2C_InitStruct.I2C_Timing = 0xb0420f13;                //100Kbits
        /* I2C Peripheral Enable */
        I2C_Cmd(I2C1, ENABLE);
        /* Apply I2C configuration after enabling it */
        I2C_Init(I2C1, &I2C_InitStruct);
        
    I2C1->CR1 |= (I2C_CR1_ADDRIE | I2C_CR1_STOPIE | I2C_CR1_TXIE | I2C_CR1_RXIE);
    //---------------------------- Peripheral and DMA interrupts Initialization ------------------
    // Initialize I2C1 interrupts
    /* Enable the IRQ channel */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   
    /* Configure NVIC for I2C1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
    NVIC_Init(&NVIC_InitStructure);        
        
}

//下面是IIC中断函数的实现

void I2c_Init(void)
{
        I2C_GPIO_Configuration();
        I2C_Configuration();
}

void I2C1_IRQHandler(void)
{
        u32 AddCode;
//        I2C_ClearITPendingBit(I2C1, I2C_ISR_ADDR | I2C_ISR_STOPF |I2C_ISR_ADDCODE );
        __IO uint32_t I2CFlagStatus = 0x00000000;
        I2CFlagStatus = (uint32_t)(I2C1->ISR & (uint16_t)0x0000100FE);
        
//        printf("recv data\r\n");
        if ((I2CFlagStatus & I2C_ISR_ADDR) != 0)
          {
                AddCode = (I2C1->ISR & 0xfe0000);                        //读取ADDCODE   32:17位
                printf("匹配地址2 0x%x: \r\n",AddCode >> 17 );
               
            if(I2C1->ISR&I2C_ISR_DIR) //tx mode
        {
                        printf("发送模式 \r\n");
            Tx_count = 0;
                 I2C1->ISR |= I2C_ISR_TXE;
            I2C1->ICR |= I2C_ICR_ADDRCF;
                        
                        if(I2C_GetITStatus( I2C1, I2C_IT_RXNE) != 0)
                        {
                                Rx_buffer[Rx_count++]=I2C_ReceiveData(I2C1);
                                if(Rx_count>=Rx_MAX)
                                {
                                        Rx_count=0;
                                        //rx  ok
                                }
                                printf("Rx_buffer : %s\r\n",Rx_buffer);
                        }
        }
                if((I2C1->ISR&I2C_ISR_DIR)==0) //rx mode
        {
                        printf("接收模式 \r\n");
                        Rx_count= 0;
                        I2C1->ICR |= I2C_ICR_ADDRCF;
        }
    }
        else if(I2C_GetITStatus( I2C1, I2C_IT_RXNE) != 0)
        {
                Rx_buffer[Rx_count++]=I2C_ReceiveData(I2C1);
                if(Rx_count>=Rx_MAX)
        {
            Rx_count=0;
                        //rx  ok
        }
                printf("Rx_buffer : %s\r\n",Rx_buffer);
        }
        else if ((I2CFlagStatus & I2C_ISR_TXIS) != 0)
        {
                I2C_SendData(I2C1,Tx_buffer[Tx_count++]);
                if(Tx_count >= Tx_MAX)
                {
                        Tx_count = 0;
                        //tx ok
                }
        }
        else if ((I2CFlagStatus & I2C_ISR_STOPF) != 0)
        {
                printf("停止检查标志位 \r\n");
                I2C1->ICR |= I2C_ICR_STOPCF;
                Rx_count = 0;
                Tx_count = 0;
        }
}
huailao120 回答时间:2017-12-18 19:25:53
谢谢分享`
盘古遗族-2040628 回答时间:2018-1-3 13:17:53
谢谢大神分享
fangtianfei 回答时间:2018-4-19 16:24:33
谢谢分享
小溪嘻嘻 回答时间:2018-4-19 16:43:28
好东西
telenlang 回答时间:2018-5-24 21:21:17
谢谢分享

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版