打印

硬件IIC从机无应答

[复制链接]
738|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
菊江先生|  楼主 | 2020-4-22 13:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人现在正在做两片STM32的IIC通讯主机选用的是IO模拟IIC而从机是通过硬件IIC中断来做的,直接上从机程序:

static void I2C_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//scl
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
        GPIO_InitStructure.GPIO_Pin = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//sda
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
        GPIO_InitStructure.GPIO_Pin = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
}

static void I2C_Mode_Config(void)
{
        
        I2C_InitTypeDef I2C_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
        I2C_DeInit(I2C1);
        
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStructure.I2C_OwnAddress1 = 0X30;
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStructure.I2C_ClockSpeed = 100000;
        I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
        I2C_Init(I2C1,&I2C_InitStructure);

        I2C_ITConfig(I2C1,(I2C_IT_ERR |I2C_IT_EVT |I2C_IT_BUF),ENABLE);   
        I2C_Cmd(I2C1,ENABLE);
}
void I2C_clear_ADDR(I2C_TypeDef* I2Cx)
{
        I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR);
        ((void)(I2Cx->SR2));
}
void I2C_clear_STOPF(I2C_TypeDef* I2Cx) {
        I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF);
        I2C_Cmd(I2Cx, ENABLE);
}



void I2C_SLAVE_Init(void)
{
        I2C_GPIO_Config();
        I2C_Mode_Config();
}



/**
  * @brief  This function handles I2C1_EV_IRQHandler
  * @param  None
  * @retval None
  */
void I2C1_EV_IRQHandler()
{
        /*
        if(I2C_GetITStatus(I2C1,I2C_IT_AF))
        {
                I2C_ClearITPendingBit(I2C1,I2C_IT_AF);
        }
        switch(I2C_GetLastEvent(I2C1))
        {
                case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
                        I2C_clear_ADDR(I2C1);
                break;
                case I2C_EVENT_SLAVE_BYTE_RECEIVED:
                        iic_flag.Buffer_Rx_IIC1[iic_flag.Rx_Idx_IIC1++] = I2C_ReceiveData(I2C1);
                        if(iic_flag.Rx_Idx_IIC1 >= 2) iic_flag.Rx_Idx_IIC1 =0;
                        switch(iic_flag.Buffer_Rx_IIC1[0])
                        {
                                case 0x10:
                                        iic_flag.Buffer_Tx_IIC1[0] = 0x21;
                                break;
                                case 0x12:
                                        iic_flag.Buffer_Tx_IIC1[0] = 0x44;
                                break;
                                case 0x23:
                                        iic_flag.Buffer_Tx_IIC1[0] = 0x76;
                                break;
                                case 0x34:
                                        iic_flag.Buffer_Tx_IIC1[0] = 0x67;
                                break;
                                default: break;
                        }
                        if(I2C_GetFlagStatus(I2C1,I2C_FLAG_DUALF))
                        {}
                        else if(I2C_GetFlagStatus(I2C1,I2C_FLAG_GENCALL))
                        {}
                        else
                        {}
                break;
                case I2C_EVENT_SLAVE_STOP_DETECTED:
                        I2C_clear_STOPF(I2C1);
                break;
                case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
                        I2C_clear_ADDR(I2C1);
                        I2C_SendData(I2C1,0X00);
                break;
                case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
                        if(I2C_GetFlagStatus(I2C1,I2C_FLAG_DUALF))
                        {
                        }
                        else if(I2C_GetFlagStatus(I2C1,I2C_FLAG_GENCALL))
                        {
                        }
                        else
                        {
                        }
                        I2C_GetFlagStatus(I2C1,I2C_FLAG_BTF);
                        I2C_SendData(I2C1,iic_flag.Buffer_Tx_IIC1[iic_flag.Tx_Idx_IIC1++]);
                        if(iic_flag.Tx_Idx_IIC1>2) iic_flag.Tx_Idx_IIC1=0;
                break;
                case I2C_EVENT_SLAVE_ACK_FAILURE:
                        I2C_ClearITPendingBit(I2C1,I2C_IT_AF);
                break;
                case I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED:
                break;
                case I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED:
                break;
               
                default:
                        break;
        }
        //I2C1->CR1 |= 0X0001;
        
        
        */
        __IO u16 SR1Register =0;
        __IO u16 SR2Register =0;
        SR1Register = I2C1->SR1;
        SR2Register = I2C1->SR2;
        //判断I2C是从机模式-最低位(MSL=0)
        if((SR2Register&0x0001)!=0x0001)
        {
                //ADDR:根据状态判断获取从机IIC地址成功
                if((SR1Register&0X0002) == 0X0002)
                {
                SR1Register =0;
                SR2Register =0;
                I2C_clear_ADDR(I2C1);
                iic_flag.Rx_Idx_IIC1 =0;
                iic_flag.Tx_Idx_IIC1 =0;
                        
                }
                //接收数据(RXNE=1:EV2)
                if((SR1Register& 0X0040) == 0X0040)
                {
                        iic_flag.Buffer_Rx_IIC1[iic_flag.Rx_Idx_IIC1++] = I2C1->DR;
                        SR1Register = 0;
                        SR2Register = 0;
                switch(iic_flag.Buffer_Rx_IIC1[0])
                {
                        case 0x10:
                                iic_flag.Buffer_Tx_IIC1[0] = 0x21;
                        break;
                        case 0x12:
                                iic_flag.Buffer_Tx_IIC1[0] = 0x44;
                        break;
                        case 0x23:
                                iic_flag.Buffer_Tx_IIC1[0] = 0x76;
                        break;
                        case 0x34:
                                iic_flag.Buffer_Tx_IIC1[0] = 0x67;
                        break;
                        default: break;
                }
                }
                //检测到停止条件(STOP=1:EV4)
                if((SR1Register&0X0010) == 0X0010)
                {
                        I2C1->CR1 |= 0x0001;
                        SR1Register =0;
                        SR2Register =0;
                        iic_flag.Flag_RcvOK_IIC1 =1;
                }
               
                //发送数据(TxE = 1:EV3,EV3-1)
                if((SR1Register&0X0080) == 0X0080)
                {
                        SR1Register = 0;
                        SR2Register = 0;
                        I2C1->DR = 0X21;//iic_flag.Buffer_Tx_IIC1[iic_flag.Tx_Idx_IIC1++];
                }
                //检测到非应答
                if((SR1Register&0X0400) == 0X0400)
                {
                        I2C1->SR1 &= 0XFDFF;
                        SR1Register =0;
                        SR2Register =0;
                }
        }
        
}



void NVIC_Config_Init(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1 ;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        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);
        */
        
}
void Handware_Init(void)
{
        //SysTick_Init();
        
        I2C_SLAVE_Init();
        NVIC_Config_Init();
        //USB_USART_Config();
}

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{        

        Handware_Init();
        while(1)
        {        
                /*
                if(timflag.Timing500msFlag==1)
                {
                        timflag.Timing500msFlag=0;
                        
                        //printf("rxdata[0]=%d\r\n",iic_flag.Buffer_Rx_IIC1[0]);
                        //printf("rxdata[1]=%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
                }
                if(iic_flag.Flag_RcvOK_IIC1 ==1)
                {
                        switch(iic_flag.Buffer_Rx_IIC1[0])
                        {
                                case 0x10:
                                        printf("电压值volt:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
                                break;
                                case 0x12:
                                        printf("电流值cur:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
                                break;
                                case 0x23:
                                        printf("额定功率:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
                                break;
                                case 0x34:
                                        printf("时间time:%d\r\n",iic_flag.Buffer_Rx_IIC1[1]);
                                break;
                                
                                default: break;
                                       
                        }
                        
                        //memset(iic_flag.Buffer_Rx_IIC1,0,20);
                        //memset(iic_flag.Buffer_Tx_IIC1,0,20);
                        iic_flag.Flag_RcvOK_IIC1=0;
                }
               
                */
               
        }        
}

总体程序大致如此,主循环里面都屏蔽了,主要就是IIC配置和中断函数了
但是我通过示波器并没有发现有应答,而且SR1寄存器总是出现0X0110,代表总线错误和检测到停止信号,有时候会进入地址匹配SR1 = 0x0112;现在真的是黔驴技穷了
希望大佬帮忙

使用特权

评论回复

相关帖子

沙发
tianye907| | 2020-4-22 13:48 | 只看该作者
初始化对不对,时许对不对,硬件对不对,不要慌,一个个排查

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

446

主题

447

帖子

0

粉丝