打印
[PIC®/AVR®/dsPIC®产品]

STM32与PIC间的IIC通信

[复制链接]
2105|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
石小亮|  楼主 | 2017-10-11 17:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想实现了stm32与PIC间通信。现在两个我都是用中断函数写的,程序基本也是借鉴网上的例子。问题是PIC内像SSPIF寄存器不置位的,STM32F103发完起始信号和地址,等待pic的应答,可是pic内感觉没反应。测试发现SCL和SDA都被拉低了。
一下是我的程序。
//stm32程序测试过可以用,使用stm32和stm32间IIC通信测试的。
void IIC_Init(void)
{                               
        u8 i= 0;
        GPIO_InitTypeDef GPIO_InitStructure;
        I2C_InitTypeDef I2C_InitStructure;
       
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);  //ʹÄÜI2cÏà¹ØʱÖÓ
       
//        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;    //PB6 -SCL,PB7-SDA
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ;   //ÐÞ¸ÄΪ¿ªÂ©Êä³  ÍÆÍìÊä³öGPIO_Mode_Out_PP
//        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_Init(GPIOB, &GPIO_InitStructure);
//        for(i=0;i<1;i++)
//        {
//                GPIO_SetBits(GPIOB,GPIO_Pin_6);
//                delay_us(100);
//                GPIO_ResetBits(GPIOB,GPIO_Pin_6);
//                delay_us(100);
//               
//        }
//       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;    //PB6 -SCL,PB7-SDA             GPIO_AF_I2C1
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ;   //ÐÞ¸ÄΪ¿ªÂ©Êä³  ÍÆÍìÊä³öGPIO_Mode_Out_PP
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;    //PB6 -SCL,PB7-SDA             GPIO_AF_I2C1
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ;   //ÐÞ¸ÄΪ¿ªÂ©Êä³  ÍÆÍìÊä³öGPIO_Mode_Out_PP
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);         //PB10,PB11 Êä³ö¸ß
       
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//¸Ã²ÎÊý½öÔÚ100KÒÔÉϲÅÓÐÒâÒå
        I2C_InitStructure.I2C_OwnAddress1 = 0xA6; //ÉèÖÃ×ÔÉíµØÖ·
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //ʹÄÜÓ¦´ð
        I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //Ñ°Ö·¶ÔÏó 7λ
        I2C_InitStructure.I2C_ClockSpeed = 100000; // arm×î¸ß400K,pic×î¸ß100k
        I2C_ITConfig(I2C1,I2C_IT_EVT | I2C_IT_BUF,ENABLE);
       
        I2C_Cmd(I2C1, ENABLE); //ʹÄÜI2c1
        I2C_Init(I2C1, &I2C_InitStructure); //°´ÕÕÒÔÉÏÅäÖóõʼ»¯
        I2C_AcknowledgeConfig( I2C1, ENABLE );//ÔÊÐíÒ»×Ö½ÚÒ»Ó¦´ðģʽ      
}

void I2C1_EV_IRQHandler(void)
{
        u32 show_counter1;
  show_counter1++;
  if(show_counter1 > 1000000)
  {
    show_counter1 = 0;
    printf("\r\n The I2C1 LastEvent is %x \r\n", I2C_GetLastEvent(I2C1));
  }
  switch(I2C_GetLastEvent(I2C1))
  {
    case I2C_EVENT_MASTER_MODE_SELECT: // ·¢ËÍÍêÆô¶¯Ðźţ¬Ñ¡ÔñΪÖ÷»úģʽ
    {
      I2C_Send7bitAddress(I2C1, 0xB7, I2C_Direction_Receiver);
      printf("\r\n The I2C1 is ready \r\n");
      break;
    }
    case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: //
    {
                        I2C_AcknowledgeConfig( I2C1, ENABLE );
      printf("\r\n The slave address is %x \r\n", I2C_ReceiveData(I2C1));
      break;
    }
    case (I2C_EVENT_MASTER_BYTE_RECEIVED | (I2C_FLAG_BTF & 0x0f)): //
    {
                        I2C_AcknowledgeConfig( I2C1, DISABLE );
      I2C_GenerateSTOP(I2C1,ENABLE);  //½ÓÊÜ×îºóÒ»¸ö×Ö½ÚÇ°ÏȹØ×ÜÏߣ¬²»È»×ÜÏßËøËÀ
      printf("\r\n The I2C1 has received data2 %x \r\n", I2C_ReceiveData(I2C1));
      printf("\r\n The I2C1 is finish \r\n");
                       
      break;
    }
    case 0x40:
    {
      I2C_ReceiveData(I2C1);
                        break;
    }
default: {break;}
  }
}

//PIC 程序
void interrupt ISR(void)
{
        if(SSPIE && SSPIF)
        {
               
                i2c_slave_interrupt_tx();
                i2c_slave_interrupt_rx();
                SSPIF = 0;
        }       
}

void init_i2c_slave()
{
        TRISA = 0;TRISC = 0;
    TRISB6 = input;  // scl
    TRISB4 = input; //sda
    SSPCONbits.SSPM0 = 0;
    SSPCONbits.SSPM1 = 1;
    SSPCONbits.SSPM2 = 1;
    SSPCONbits.SSPM3 = 1;// I2C slave mode ,7bit address
    SSPCONbits.CKP = 1;              // enable clock
    SSPADD =0xb6 ;        //slave address is 0xa0

    SSPCONbits.SSPEN=1;   //enable I2c
        SSPEN = 1;
    SSPSTAT=0x00;         //清除状态标志

    PIE1bits.SSPIE = 1;//Enabe interrupt MSSP
    INTCONbits.PEIE = 1;
    INTCONbits.GIE =  1;
}



                       
void main()
{
//    init_fosc();
        init_i2c_slave();
        TRISB7 = 0;RB7 = 1;       

        unsigned char Temp;
        unsigned int timercounter;
        Temp = SSPSTAT;
        Temp = Temp & 0x2d ;
        if(SSPSTATbits.R_nW ==1)
        {
                A_readflag = 0;
                SSPIF = 0;
                i2c_address = SSPBUF;

                SSPBUF = 0x66; //send data
                SSPCONbits.CKP = 1; //enbale clock
            SSPIF = 0;

               

        }               
}


/*I2C SALVE mode interrupt */
void i2c_slave_interrupt_tx()  // master read / slave send
{
        unsigned char Temp;
        unsigned int timercounter;
        Temp = SSPSTAT;
        Temp = Temp & 0x2d ;
        if(SSPSTATbits.R_nW ==1)
        {
                A_readflag = 0;
                SSPIF = 0;
                i2c_address = SSPBUF;
                if(S==1 && BF==1)
                {
                        SSPBUF = 0x66; //send data
                        SSPCONbits.CKP = 1; //enbale clock
                    SSPIF = 0;

                }

        }
}

void i2c_slave_interrupt_rx()  //master write / slave read
{
        unsigned char Temp;
        Temp = SSPSTAT;
        Temp &= 0x2d ;
        if(Temp = 0x09) // write opration, last byte was an address,buffer is full
        {
                SSPIF = 0;
                i2c_address = SSPBUF;

        }
        if(Temp == 0x29)
        {
                SSPIF = 0;
                Register[word_address] = SSPBUF;
                word_address++;
                if(word_address >= RX_BUF_LEN)
                        word_address = 0;
        }
}

沙发
石小亮|  楼主 | 2017-10-11 17:16 | 只看该作者
急急急,如果有大神帮忙解决这个问题,愿意100元大红包送上啊。

使用特权

评论回复
板凳
Cjy_JDxy| | 2017-10-11 18:49 | 只看该作者
我做过PIC和dsPICI2C通讯,不过是单向通讯,一个只管发,一个只管收

使用特权

评论回复
地板
kingkits| | 2017-10-12 10:02 | 只看该作者
如果有IIS,其实用半双工同步串行通讯会更快

使用特权

评论回复
5
kingkits| | 2017-10-12 10:02 | 只看该作者
你甚至可以实现DMA

使用特权

评论回复
6
石小亮|  楼主 | 2017-10-12 10:11 | 只看该作者
kingkits 发表于 2017-10-12 10:02
你甚至可以实现DMA

嗯,想在实现两者通信后,再在stm32上加上DMA

使用特权

评论回复
7
石小亮|  楼主 | 2017-10-12 10:15 | 只看该作者
Cjy_JDxy 发表于 2017-10-11 18:49
我做过PIC和dsPICI2C通讯,不过是单向通讯,一个只管发,一个只管收

我这个stm32上挂的IIC设备不止一个,所以需要验证

使用特权

评论回复
8
兰天白云| | 2017-10-12 16:06 | 只看该作者
两个都是单片机,单片机IO口与EEPROM储存芯片IO口不一样,你查查是那个单片机强行控制IO口了

使用特权

评论回复
9
daijun20803| | 2017-10-12 18:26 | 只看该作者
先看看两个单片机的io结构

使用特权

评论回复
10
石小亮|  楼主 | 2017-10-13 16:29 | 只看该作者
daijun20803 发表于 2017-10-12 18:26
先看看两个单片机的io结构

我用的是pic16F690

使用特权

评论回复
11
山东电子小菜鸟| | 2017-10-13 22:49 | 只看该作者
石小亮 发表于 2017-10-11 17:16
急急急,如果有大神帮忙解决这个问题,愿意100元大红包送上啊。

中断方式比较好

使用特权

评论回复
12
caijie001| | 2017-10-21 15:22 | 只看该作者
你那边的单片机也要写通信协议啊,iic还有主从之分吧

使用特权

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

本版积分规则

2

主题

7

帖子

0

粉丝