本帖最后由 stevendaoyun 于 2013-9-12 21:15 编辑
系统中,一片STM32做主机,两片STM32作为从机,主机和一个从机通讯成功,能够发送数据给从机也能读取从机数据,与两个从机通讯时,与从机1通讯结束后,接着与从机2通讯,但程序卡在从机2地址发送处,屏蔽从机1通讯程序后从机2又能够正常通讯。我试了在和从机2通讯之前重置I2C和清除主机接收缓存器,但是依然没能成功,是不是在主机在和从机通讯时,与从机1通讯结束后,需要对I2C进行处理才能发送从机2地址与从机2通讯吗?
主机通讯代码:因为注释在这里显示乱了,所以以下代码都没有备注
//主机发送字节
void I2C_WriteBytes(unsigned char SlaveAddress)
{
I2C_GenerateSTART(I2C2,ENABLE);
while(!((uint16_t)(I2C2->SR1)&(uint16_t)(0x0001)));//SB=1
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);//BUSY=1+MSL=1
I2C_Send7bitAddres(I2C2,SlaveAddress,I2C_Direction_Transmitter);
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//ADDR=1
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0007))!=0x0007);
while(g_I2Tx_Counter!=BUFFER_SIZE)
{
I2C_SendData(I2C2, g_I2TxBuffer[g_I2Tx_Counter++]);
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0080))!=0x0080);//TXE
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0007))!=0x0007);//MSL+BUSY+TRA
}
g_I2Tx_Counter=0;
I2C_GenerateSTOP(I2C2, ENABLE);
}
//主机接收字节
void I2C_ReadBytes(unsigned char SlaveAddress)
{
I2C_GenerateSTART(I2C2, ENABLE);
while(!((uint16_t)(I2C2->SR1)&(uint16_t)(0x0001)));//SB=1
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);//BUSY=1
I2C_Send7bitAddress(I2C2, SlaveAddress, I2C_Direction_Receiver);
//操作从机2时卡在这里,发送从机2地址之后程序就停在了这里
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//确认地址是否发送完成
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);
while(g_I2Rx_Counter!=BUFFER_SIZE)
{
if(g_I2Rx_Counter==(BUFFER_SIZE-1))
{
if(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE)==1)
{
I2C_AcknowledgeConfig(I2C2, DISABLE);
I2C_GenerateSTOP(I2C2, ENABLE);
}
}
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0040))!=0x0040);
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);
g_I2RxBuffer[g_I2Rx_Counter++] = I2C_ReceiveData(I2C2);
}
I2C_GenerateSTOP(I2C2, ENABLE);
I2C_AcknowledgeConfig(I2C2, ENABLE);
g_I2Rx_Counter=0;
}
//主函数
int main(void)
{
unsigned char i;
RCC_Configuration();
// LED_Configuration();
NVIC_Configuration();
I2C_Configuration();
USART_Configuration();
// LEDG_ALL_ON;
// while(g_USART1Received!=0xD1);
//从机1地址0x54,操作从机1
I2C_WriteBytes(0x54);
Sleep(100);
I2C_ReadBytes(0x54);
for(i=0;i<BUFFER_SIZE;i++)
{
g_I2RxBuffer[i]=0;
}
Sleep(100);
//操作从机2,从机2地址0x53
I2C_WriteBytes(0x53);
Sleep(100);
I2C_ReadBytes(0x53);
for(i=0;i<BUFFER_SIZE;i++)//清除接收缓存器
{
g_I2RxBuffer[i]=0;
}
while(1)
{
}
}
从机代码:[code]从机1和从机2代码一样只是初始化是定义的从机地址不一样
void I2C_Configuration(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*PB10=SCL,PB11=SDA*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
GPIO_Init(GPIOB,&GPIO_InitStructure);
I2C_DeInit(I2C2);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x53;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress =I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 40000;
I2C_Init(I2C2, &I2C_InitStructure);
I2C_ITConfig(I2C2,I2C_IT_ERR,ENABLE);
I2C_Cmd(I2C2,ENABLE);
I2C_AcknowledgeConfig(I2C2,ENABLE);
}
//主机发送从机接收
void SlaveRxBytes()
{
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0002))!=0x0002);
while(g_I2Rx_Counter!=BUFFER_SIZE)
{
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0040))!=0x0040);//RxNE=1
g_I2RxBuffer[g_I2Rx_Counter++]=I2C_ReceiveData(I2C2);
}
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0010))!=0x0010);
g_I2Rx_Counter=0;
}
//主机接收从机发送
void SlaveTxBytes()
{
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//ADDR=1 receive address matched
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0006))!=0x0006);//BUSY=1+MSL=0+TRA=1
I2C_SendData(I2C2,g_I2TxBuffer[g_I2Tx_Counter++]);
while(g_I2Tx_Counter!=BUFFER_SIZE)
{
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0080))!=0x0080);
I2C_SendData(I2C2,g_I2TxBuffer[g_I2Tx_Counter++]);
}
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0010))!=0x0010);
g_I2Tx_Counter=0;
}
//从机主函数
int main(void)
{
RCC_Configuration();
I2C_Configuration();
NVIC_Configuration();
SlaveRxBytes();
SlaveTxBytes();
} |