Сил уже нету с i2c разбираться, ни в какую он не хочет стабильно работать.
Уже весь проект перелопатил все сторонние воздействия от кода исключил, осталась только одна функция отправки данных по i2c которая крутится в цикле. Проблема в следующем программа всё так же зависает на строчке
Код
while (!(I2C2->SR1 & I2C_SR1_ADDR)){};
Причём это происходит совсем неявно т.е может спокойно передаться 1000 посылок, потом зависнуть, а в следующий раз (после рестарта) штук 50 передаться. Так же выявил, что стабильность передачи зависит от задержки между пакетами, и вот тут начинается самое весёлое. без задержки всё работает(отправляется пакетов больше 10000) потом при какой-то магической задержки перестаёт работать(количество отправленных пакетов <100 в основном 15-60), а при увеличения её продолжает работать. Так эти задержки относятся и коду т.е если за комментировал какое-то условие(для строба синхронизации) то работает обратно вернул не работает :shock:
CODE
int main(void){
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
//==============================================================================
//I2C_Setup_fsm(&ModeDisplayUpdate);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO , ENABLE);//
/* I2C2 SDA and SCL configuration */
GPIO_StructInit(&GPIO_InitStructure);
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_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*SCL is pin06 and SDA is pin 07 for I2C2*/
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//I2C_DeInit(I2C2);
// I2C_Cmd(I2C2,DISABLE);
// GPIO_DeInit(GPIOB);
// GPIO_AFIODeInit();
/* I2C2 configuration */
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED ;
I2C_Init(I2C2, &I2C_InitStructure);
// I2C2->CR1&=~I2C_CR1_SMBUS; // I2C MODE enable
// I2C2->CR2|=I2C_CR2_FREQ_2; // Peripheral clock frequency 36MHz
// I2C2->CR2|=I2C_CR2_FREQ_4; // Peripheral clock frequency 36MHz
// I2C2->CCR&=~I2C_CCR_CCR; // Clear CCR bit field
// I2C2->CCR|=0x64; // CCR=I2C_freq_clock/(2*I2C_freq_speed) = 36000000/(2*100000) - just for standart MODE (not fast) {see Ref.M. p.752}
// I2C2->CCR&=~I2C_CCR_FS; //Standart Mode I2C
// I2C2->TRISE|=20; // rise_time = 1000ns, T_pclk1=28ns (1/36000000) => TRISE=rise_time/T_pclk1 {see Ref.M. p.753}
// I2C2->CR1|=I2C_CR1_PE;// peripheral enable
// I2C_AcknowledgeConfig(I2C2, ENABLE);
//------------------------------------------------------------------------------
/*enable I2C*/
//I2C_Cmd(I2C2,ENABLE);
//==============================================================================
//==============================Главный цикл====================================
//==============================================================================
while(1){
//---------------------------------------------------------------------------
//I2C2->CR1|=I2C_CR1_PE;// peripheral enable
//--------------Cтроб для синхронизации с осциллографом(поиска места обрыва)--
if(TEST_delay123>=CounterPascet-1){
TEST_DELAY_OFF
}
//---------------------------------------------------------------------------
I2C2->CR1 |= I2C_CR1_START;
//---------------------------------------------------------------------------
while (!(I2C2->SR1 & I2C_SR1_SB)){};
//EV5: SB=1, cleared by reading SR1 register followed by writing DR register with Address.
(void) I2C2->SR1;
I2C2->DR = I2C_ADDR_LCD_KEY_LED;
//----------------------------------------------------------------------------------------------
while (!(I2C2->SR1 & I2C_SR1_ADDR)){};
//EV6:ADDR=1, cleared by reading SR1 register followed by reading SR2.
(void)I2C2->SR1;
(void)I2C2->SR2;
while (!(I2C2->SR1 & I2C_SR1_TXE)){};
//EV8_1:TxE=1, shift register empty, data register empty, write Data1 in DR.
I2C2->DR = 0xAA;
//----------------------------------------------------------------------------------------------
while (!(I2C2->SR1 & I2C_SR1_TXE)){};
//EV8:TxE=1, shift register not empty, dataregister empty, cleared by writing DR register
I2C2->DR = 0xff;
//----------------------------------------------------------------------------------------------
while (!(I2C2->SR1 & I2C_SR1_TXE)){};
while (!(I2C2->SR1 & I2C_SR1_BTF)){}
//EV8_2:TxE=1, BTF = 1, Program Stop request. TxE and BTF are cleared by hardware by the Stop condition
I2C2->CR1 |= I2C_CR1_STOP;
//----------------------------------------------------------------------------------------------
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF));
//--------------Cтроб для синхронизации с осциллографом(поиска места обрыва)--------------------
if(TEST_delay123>=CounterPascet-1){
TEST_DELAY_ON
}
//I2C2->CR1&=~I2C_CR1_PE;// peripheral disable
//----------МАГИЧЕСКИЕ ЗАДЕРЖКИ-------------------------------------------------------------
//----------Сделал увеличение что бы было сразу было понятно работает или нет---------------
delay123=TEST_delay123;
//delay123=27;
//delay1=1;
//delay123=60;
//delay123=11;
while(delay123--);
TEST_delay123++;
if(TEST_delay123>=0xFFFF){TEST_delay123=0xFFFF;}
////------------------------------------------------------------------------------------------------
}
}
PS: В момент зависания на осциллограмме видно, что стартовый бит выставился, а вот адрес даже не начал передаваться.
Сообщение отредактировал pokk - Nov 13 2015, 06:35