初级会员

- 积分
- 57
- 金钱
- 57
- 注册时间
- 2018-4-26
- 在线时间
- 7 小时
|
15金钱
我的I2C从机中断在从机发送过程中,丢失字节很严重,我这边收到的数据应该是没问题的,但可能发送这边出了点问题,上网查了下,可能是我这边在发最后以一个数据前必须给一个NACK和STOP,然后再发最后一位数据,但是这个NACK不是主机那边发给我的吗?求助大神 我这边I2C接收到数据后是放到一个全局数组里,然后再在主函数判断这个数组,并发送相应的数据过去,这个为(SendBuf[8])全局的
void App_I2C1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//I2C_DeInit(I2C1) ;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
// I2C1 SDA and SCL configuration
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* I2C1 configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //选择为I2C模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //该参数只有在I2C 工作在快速模式(时钟工作频率高于 100KHz)下才有意义。
I2C_InitStructure.I2C_OwnAddress1 = 0x70;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //收到数据后通过硬件自动发出应答信号
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 300000; //该参数用来设置时钟频率,这个值不能高于400KHz
I2C_Init(I2C1, &I2C_InitStructure);
/* Configure and enable I2Cx event interrupt -------------------------------*/
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//中断分组
NVIC_Init(&NVIC_InitStructure);
/* Configure and enable I2C1 error interrupt -------------------------------*/
NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1 ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//中断分组
NVIC_Init(&NVIC_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_ERR| I2C_IT_BUF , ENABLE); //开启缓存器中断和事件中断
I2C_Cmd(I2C1, ENABLE);
}
/*
函数名: void I2C1_EV_IRQHandler(void)
* 功能;I2C接收和发送中断
* 输入:无
* 输出:无
* 返回值:无
*/
u8 data = 0;
u8 S_data=0;
u8 RecevieBufA[8]; //从机接收操作
u8 RecevieBufB[8];
u8 SendBuf[8];
void I2C1_EV_IRQHandler(void)
{
static u8 i;
//Clear AF from slave-transmission end
if(I2C_GetITStatus(I2C1, I2C_IT_AF))
{
I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
}
switch(I2C_GetLastEvent(I2C1))
{
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //EV1 start
I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR);
((void)(I2C1->SR1));
((void)(I2C1->SR2));
break;
case I2C_EVENT_SLAVE_BYTE_RECEIVED: //EV2 receive
RecevieBufA[data] = I2C_ReceiveData(I2C1);
data++;
break;
case I2C_EVENT_SLAVE_STOP_DETECTED: //End of receive, EV4
if((data==8)||(data==1))
{
if((RecevieBufA[0]>=Button)&&(RecevieBufA[0]<=Wdg))
{
for(i=0;i<=7;i++)
{
RecevieBufB[i]=RecevieBufA[i];
RecevieBufA[i]=0;
}
data=0;
}
else
{
for(i=0;i<=7;i++)
{
RecevieBufA[i]=0;
}
data=0;
}
}
else
{
for(i=0;i<=7;i++)
{
RecevieBufA[i]=0;
}
data=0;
}
I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF);
I2C_Cmd(I2C1, ENABLE);
break;
//send
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: //EV1 start
I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR);
((void)(I2C1->SR2));
//Send first byte
I2C_SendData(I2C1, SendBuf[S_data]);
SendBuf[S_data]=0;
S_data++;
break;
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: //EV3.1
break;
case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: //EV3 send
I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF);
I2C_SendData(I2C1, SendBuf[S_data]);
SendBuf[S_data]=0;
S_data++;
if(S_data>7)
{S_data=0;}
break;
case I2C_EVENT_SLAVE_ACK_FAILURE://End of send EV3_2
I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
break;
default:
break;
}
}
I2C_AcknowledgeConfig(I2C1,DISABLE);
/*
函数名:void I2C1_ER_IRQHandler(void)
* 功能;I2C错误中断
* 输入:无
* 输出:无
* 返回值:无
*/
void I2C1_ER_IRQHandler(void)
{
/* Check on I2C1 AF flag and clear it */
if (I2C_GetITStatus(I2C1, I2C_IT_AF)) //no ACK
{
I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
//data = 0;
//S_data=0;
}
/* Check on I2C1 AF flag and clear it */
if (I2C_GetITStatus(I2C1, I2C_IT_BERR)) // start and stop error
{
I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
}
}
|
|