我想实现了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;
}
}
|