Добрый день, не как не могу понять почему виснет I2C в stm32f103, запускается работает работает потом бац зависло.
CODE
//==============================================================================
PT_THREAD(Send_data_fsm(struct pt *pt,unsigned char data1,unsigned char data2)){
static unsigned char data[2];
//---------------------------------------------------------------------------
if(pt->lc!=0){ //Не первый запуск
if(GetTimers(I2C_TimeOut)>TIMEOUT_I2C){
Send_MSG(MSG_I2C_REBOOT);
ResetTimers(I2C_TimeOut);
}
}
//---------------------------------------------------------------------------
PT_BEGIN(pt);
ResetTimers(I2C_TimeOut);
data[0]=data1;
data[1]=data2;
/* initiate start sequence */
while(TakeMutex(I2C_MUTEX)){PT_YIELD(pt);}
I2C_GenerateSTART(I2C2, ENABLE);
/* check start bit flag */
while(!I2C_GetFlagStatus(I2C2, I2C_FLAG_SB)){PT_YIELD(pt);};
/*send write command to chip*/
I2C_Send7bitAddress(I2C2, I2C_ADDR_LCD_KEY_LED, I2C_Direction_Transmitter);
/*check master is now in Tx mode*/
//--------------------------------------------------------------------------
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}; //Spead=400KHz delay=1000 clock Spead=1KHz delay=65000 clock
/*mode register address*/
I2C_SendData(I2C2, data[0]);
//--------------------------------------------------------------------------
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){PT_YIELD(pt);}; //3600 Speed=100Khz
/*clear bits*/
I2C_SendData(I2C2, data[1]);
//--------------------------------------------------------------------------
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){PT_YIELD(pt);};
//--------------------------------------------------------------------------
/*generate stop*/
I2C_GenerateSTOP(I2C2, ENABLE);
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)){PT_YIELD(pt);};
GiveMutex(I2C_MUTEX);
PT_END(pt);
}
//==============================================================================
Виснет на проверке:
Код
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){}; //Spead=400KHz delay=1000 clock
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED содержит флаги( BUSY, MSL, ADDR, TXE, TRA)
Более глубокое копание показало что всё дело в флаге ADDR.
Изменение куска кода на
Код
I2C2->CR1 |= I2C_CR1_START;
while (!(I2C2->SR1 & I2C_SR1_SB)){};
(void) I2C2->SR1;
I2C2->CR1|=I2C_CR1_ACK;
I2C2->DR = I2C_ADDR_LCD_KEY_LED;
while (!(I2C2->SR1 & I2C_SR1_ADDR)){};
(void) I2C2->SR1;
(void) I2C2->SR2;
Нечего не дало всё так же может пару тысяч раз отправить байт потом повиснуть на проверке I2C_SR1_ADDR.
Код
while (!(I2C2->SR1 & I2C_SR1_ADDR)){};
При пошаговой отладке в IAR заметил что до while (!(I2C2->SR1 & I2C_SR1_ADDR)){}; флаг ADDR взводится, но как только начинаешь проверку он сбрасывается и соответственно там всё виснет.