大不列颠呆毛狼184 2023-04-20 10:31 采纳率: 66.7%
浏览 45
已结题

使用stm32进行主从机通信

STM32的IIC主从机通信,主机发送时序如下图,发送启动信号,发送地址(0x03)等待应答,发送数据(0x02)等待应答,发送停止信号。

img

从机配置中断如下,但无法产生中断,主机未检测到应答信号

//初始化IIC
void IIC_Init(void)
{            
  GPIO_InitTypeDef  GPIO_InitStructure;
  I2C_InitTypeDef     I2C_InitStructure;
    NVIC_InitTypeDef     NVIC_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟

  //GPIOB8,B9初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
    IIC_SCL=1;
    IIC_SDA=1;
    
    //    
    I2C_DeInit(I2C1);
    I2C_InitStructure.I2C_Mode             = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle     = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1     = 0x03;     //从机地址,一定要设置正确
    I2C_InitStructure.I2C_Ack             = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress= I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed     = 100000;
    I2C_Init(I2C1, &I2C_InitStructure);
 
    NVIC_InitStructure.NVIC_IRQChannel                         = I2C1_EV_IRQn;//事件中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority     = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority             = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                    = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    NVIC_InitStructure.NVIC_IRQChannel                         = I2C1_ER_IRQn;//错误中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority     = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority             = 1;                   
    NVIC_InitStructure.NVIC_IRQChannelCmd                    = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT |I2C_IT_ERR, ENABLE);   
    I2C_Cmd(I2C1, ENABLE);     
    /*允许1字节1应答模式*/
    I2C_AcknowledgeConfig(I2C1, ENABLE);    
    
}

不知道什么原因,中断函数如下


void I2C1_EV_IRQHandler(void)
{
    uint8_t ch = 0;
 
    switch(I2C_GetLastEvent(I2C1))
    {
        // 收到匹配的地址数据
        case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
        {
            I2C_Status = 1;
            //I2C_GenerateSTOP(I2C1, DISABLE);
            break;
        }
        // 收到一个字节数据
        case I2C_EVENT_SLAVE_BYTE_RECEIVED:
        {
            I2C_Status = 2;
            
            //I2C_ClearITPendingBit(I2C1, I2C_IT_RXNE);          
            ch = I2C_ReceiveData(I2C1);
            I2C1_Buffer_Rx[2] = ch;
            break;
        }
        case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: //发送数据
        {
            I2C_Status = 3;
            
            I2C_SendData(I2C1, 0x77);
            //I2C_ClearITPendingBit(I2C1, I2C_IT_TXE);          
            break;
        }
        //发送数据,要发送,不然锁死,不过 master 没收到
        case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
        {
            I2C_Status = 4;
 
            I2C_SendData(I2C1, 0x66);
            //I2C_ClearITPendingBit(I2C1, I2C_IT_TXE);          
 
            break;
        }
        case I2C_EVENT_SLAVE_STOP_DETECTED: //收到结束条件
        {
            I2C_Status = 5;
            //I2C_GenerateSTOP(I2C1, ENABLE);            
            I2C_Cmd(I2C1, ENABLE); 
            break;
        }
        default: 
            break;
    }
 
    
}
  • 写回答

3条回答 默认 最新

  • 少林and叔叔 2023-04-20 11:28
    关注

    这是STM32配置为硬件I2C的从机吗?
    I2C的SCL和SDA引脚应该做复用模式,配置成GPIO模式肯定是不行的。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月28日
  • 已采纳回答 4月20日
  • 修改了问题 4月20日
  • 修改了问题 4月20日
  • 展开全部

悬赏问题

  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥15 C++行情软件的tick数据如何高效的合成K线
  • ¥15 vba使用jmail发送邮件正文里面怎么加图片
  • ¥15 vb6.0如何向数据库中添加自动生成的字段数据。
  • ¥20 在easyX库下编写C语言扑克游戏跑的快,能实现简单的人机对战
  • ¥15 svpwm波形异常求解答
  • ¥15 STM32——硬件IIC从机通信代码实现