dimon_rub 0 26 февраля, 2017 Опубликовано 26 февраля, 2017 (изменено) · Жалоба Здравствуйте. Прошу помощи, бьюсь уже 3 день немого понять где проблема. Опрашиваю память M24C16 по I2C. Нет прерывания ДАЖЕ по старту. Код инициализации: I2C_InitTypeDef I2C_InitStructure; NVIC_InitTypeDef NVIC_InitStruct; I2C_DeInit(I2C2); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //I2C_DutyCycle_16_9; I2C_InitStructure.I2C_OwnAddress1 = 0x04; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 100000; /* 100kHz */ I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE); I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE); I2C_Init(I2C2, &I2C_InitStructure); I2C_Cmd(I2C2, ENABLE); NVIC_InitStruct.NVIC_IRQChannel = I2C2_EV_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); NVIC_EnableIRQ(I2C2_EV_IRQn); NVIC_SetPriority(I2C2_EV_IRQn, 0); // NVIC_InitStruct.NVIC_IRQChannel = I2C2_ER_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); NVIC_EnableIRQ(I2C2_ER_IRQn); NVIC_SetPriority(I2C2_ER_IRQn, 1); // Обработчик: volatile uint16_t sr1 = I2C2->SR1; volatile uint16_t sr2 = I2C2->SR2; if (!(sr2 & I2C_SR2_MSL)) return; if( sr1 & I2C_SR1_SB) //принят ответ ACK, отправка адресса { i2c_state = I2C_SEND_ADR_DEV; I2C2->DR = (uint16_t) i2c_buffer.device_adr; } if(sr1 & I2C_SR1_TXE) //принят ответ ACK, данных и стоп { switch (i2c_state) { case I2C_SEND_ADR_DEV: i2c_state = I2C_SEND_ADR_MEM; I2C2->DR = (uint16_t) i2c_buffer.start_adr; break; case I2C_SEND_ADR_MEM: if( i2c_buffer.pos_head < i2c_buffer.pos_tail && i2c_buffer.pos_head < i2c_buffer.len) { i2c_state = I2C_SEND_DATA; I2C1->DR = i2c_buffer.buffer[i2c_buffer.pos_head]; i2c_buffer.pos_head++; } else { i2c_buffer.pos_tail = 0; i2c_buffer.pos_head = 0; i2c_state = I2C_EMPTY; I2C1->CR1 |= I2C_CR1_STOP; //если закончилась то стоп } break; case I2C_SEND_DATA: i2c_state = I2C_SEND_ADR_MEM; I2C2->DR = (uint16_t) i2c_buffer.start_adr; i2c_buffer.start_adr++; break; default: break; } } if( sr1 & I2C_SR1_RXNE ) //прерывание по чтению { switch (i2c_state) { case I2C_SEND_ADR_DEV: i2c_state = I2C_SEND_ADR_MEM; I2C2->DR = (uint16_t) i2c_buffer.start_adr; break; case I2C_SEND_ADR_MEM: i2c_state = I2C_SEND_ADR_DEV2; I2C2->DR = (uint16_t) i2c_buffer.device_adr; break; case I2C_SEND_ADR_DEV2: if(i2c_buffer.pos_tail < i2c_buffer.len) { i2c_state = I2C_RECEIVE_DATA; i2c_buffer.buffer[i2c_buffer.pos_tail] = I2C2->DR; i2c_buffer.pos_tail++; } else { i2c_state = I2C_EMPTY; I2C1->CR1 |= I2C_CR1_STOP; //если закончилась то стоп } break; case I2C_RECEIVE_DATA: if(i2c_buffer.pos_tail < i2c_buffer.len) { i2c_state = I2C_RECEIVE_DATA; i2c_buffer.buffer[i2c_buffer.pos_tail] = I2C2->DR; i2c_buffer.pos_tail++; } else { i2c_state = I2C_EMPTY; I2C1->CR1 |= I2C_CR1_STOP; //если закончилась то стоп } break; default: break; } } ПОМОГИТЕ!!!!!!!! Изменено 28 февраля, 2017 пользователем IgorKossak [codebox] для длинного кода. [code]-для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 26 февраля, 2017 Опубликовано 26 февраля, 2017 · Жалоба Здравствуйте. Прошу помощи, бьюсь уже 3 день немого понять где проблема. Опрашиваю память M24C16 по I2C. Нет прерывания ДАЖЕ по старту. 1. Не включено тактирование I2C2. Может где в другом месте включается, но между строк я читать не умею. I2C_Init() это не делает, AFAIK. 2. I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE) надо бы делать после I2C_Init(). Это навскидку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimon_rub 0 26 февраля, 2017 Опубликовано 26 февраля, 2017 · Жалоба 1. Не включено тактирование I2C2. Может где в другом месте включается, но между строк я читать не умею. I2C_Init() это не делает, AFAIK. 2. I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE) надо бы делать после I2C_Init(). Это навскидку. Тактирование есть. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); А вот за это спасибо. попробую. Может еще что то. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimon_rub 0 26 февраля, 2017 Опубликовано 26 февраля, 2017 · Жалоба 1. Не включено тактирование I2C2. Может где в другом месте включается, но между строк я читать не умею. I2C_Init() это не делает, AFAIK. 2. I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE) надо бы делать после I2C_Init(). Это навскидку. I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE) надо бы делать после I2C_Init(). НЕПОМОГАЕТ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksandr Baranov 1 27 февраля, 2017 Опубликовано 27 февраля, 2017 · Жалоба А выводы где-то сконфигурированы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 27 февраля, 2017 Опубликовано 27 февраля, 2017 · Жалоба подтяжки линий к 1 на плате есть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimon_rub 0 28 февраля, 2017 Опубликовано 28 февраля, 2017 (изменено) · Жалоба Да есть решили с помощью осцелографа и такой то матери. ВСЕМ СПАСИБО. Появилясь другая. Работа осщуствляется с памятью M24C16 в посылках при чтении появляется, Это видно и на осцелографе и в трасировке. Невного переделал код прерывания. void I2C2_EV_IRQHandler(void) { volatile uint16_t sr1 = I2C2->SR1; volatile uint16_t sr2 = I2C2->SR2; if (!(sr2 & I2C_SR2_MSL)) return; if( sr1 & I2C_SR1_SB) //принят ответ ACK, отправка адресса { if (i2c_state == I2C_SEND_START) i2c_state = I2C_SEND_ADR_DEV; else i2c_state = I2C_SEND_ADR_DEV2; I2C2->DR = (uint16_t) i2c_buffer.device_adr; } if(sr1 & I2C_SR1_TXE) //принят ответ ACK, данных и стоп { switch (i2c_state) { case I2C_SEND_ADR_DEV: i2c_state = I2C_SEND_ADR_MEM; I2C2->DR = (uint16_t) i2c_buffer.start_adr; break; case I2C_SEND_ADR_MEM: if( i2c_buffer.pos_head < i2c_buffer.pos_tail && i2c_buffer.pos_head < i2c_buffer.len) { i2c_state = I2C_SEND_ADR_MEM; //I2C_SEND_DATA I2C2->DR = i2c_buffer.buffer[i2c_buffer.pos_head]; i2c_buffer.pos_head++; } else { i2c_buffer.pos_tail = 0; i2c_buffer.pos_head = 0; i2c_state = I2C_EMPTY; I2C2->CR1 |= I2C_CR1_STOP; //если закончилась то стоп } break; //case I2C_SEND_DATA: // i2c_state = I2C_SEND_ADR_MEM; // I2C2->DR = (uint16_t) i2c_buffer.start_adr; // i2c_buffer.start_adr++; // break; default: break; } } if( sr1 & I2C_SR1_RXNE ) //прерывание по чтению { switch (i2c_state) { case I2C_SEND_ADR_DEV: i2c_state = I2C_SEND_ADR_MEM; I2C2->DR = (uint16_t) i2c_buffer.start_adr; break; case I2C_SEND_ADR_MEM: i2c_state = I2C_SEND_START_SECOND; //i2c_state = I2C_SEND_ADR_DEV2; //I2C2->DR = (uint16_t) i2c_buffer.device_adr; I2C_GenerateSTART(I2C2, ENABLE); break; case I2C_SEND_ADR_DEV2: if(i2c_buffer.pos_tail < i2c_buffer.len) { i2c_state = I2C_RECEIVE_DATA; i2c_buffer.buffer[i2c_buffer.pos_tail] = I2C2->DR; i2c_buffer.pos_tail++; } else { i2c_state = I2C_EMPTY; I2C2->CR1 |= I2C_CR1_STOP; //если закончилась то стоп } break; case I2C_RECEIVE_DATA: if(i2c_buffer.pos_tail < i2c_buffer.len) { i2c_state = I2C_RECEIVE_DATA; i2c_buffer.buffer[i2c_buffer.pos_tail] = I2C2->DR; i2c_buffer.pos_tail++; } else { i2c_state = I2C_EMPTY; I2C2->CR1 |= I2C_CR1_STOP; //если закончилась то стоп } break; default: break; } } } Извиняюсь появляется значение DR=255 + ACK Есть подозрение что это из-за того что работаем на 100kHz а не на 400. Проверить небыло времени. Кто что думает. Спасибо. Как проверю - отпишусь Извиняюсь за плохое форматирование текста Изменено 3 марта, 2017 пользователем IgorKossak бездумное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 1 марта, 2017 Опубликовано 1 марта, 2017 (изменено) · Жалоба Хоть и ничего не понял, но вы не поверите: I2C на частотах меньших предельной хуже работать не станет (; "DR=255 + ACK" - это сколько? 256? в байте? Изменено 1 марта, 2017 пользователем Obam Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 1 марта, 2017 Опубликовано 1 марта, 2017 · Жалоба Хоть и ничего не понял, но вы не поверите: I2C на частотах меньших предельной хуже работать не станет (; О-о, я бы не зарекался, когда дело касается I2C на F1xx... Я из своего опыта об этом писал уже. Кстати, как сейчас заметил, писал в аналогичной теме нынешнего ТС. Уважаемый dimon_rub, почему Вы не продолжили в Вашей же более ранней теме? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 1 марта, 2017 Опубликовано 1 марта, 2017 · Жалоба О-о, я бы не зарекался, когда дело касается I2C на F1xx... Я из своего опыта об этом писал уже. Кстати, как сейчас заметил, писал в аналогичной теме нынешнего ТС. Уважаемый dimon_rub, почему Вы не продолжили в Вашей же более ранней теме? T.e. для F103 существует фиксированная частота SCL и при том близкая к предельной (да, рассматриваем стандартную 400 кГц)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 1 марта, 2017 Опубликовано 1 марта, 2017 · Жалоба T.e. для F103 существует фиксированная частота SCL и при том близкая к предельной (да, рассматриваем стандартную 400 кГц)? Нет. Дело в другом: при переходе на 100kHz выползают состояния автомата I2C, а именно - комбинации битов флагов, - которые не описаны в документации и не предусмотрены STL, не ручаюсь за Cube. В результате обработчик прерывания, беспроблемно обслуживающий на 400kHz, вдруг затыкается на 100kHz. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 1 марта, 2017 Опубликовано 1 марта, 2017 · Жалоба Нет. Дело в другом: при переходе на 100kHz выползают состояния автомата I2C, а именно - комбинации битов флагов, - которые не описаны в документации и не предусмотрены STL, не ручаюсь за Cube. В результате обработчик прерывания, беспроблемно обслуживающий на 400kHz, вдруг затыкается на 100kHz. А на 66 кГц, к примеру? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 1 марта, 2017 Опубликовано 1 марта, 2017 · Жалоба А на 66 кГц, к примеру? - Вы умеете играть на скрипке? - Не знаю: не пробовал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 1 марта, 2017 Опубликовано 1 марта, 2017 (изменено) · Жалоба - Вы умеете играть на скрипке? - Не знаю: не пробовал. Мы поняли друг-друга (: Но разве I2C_CCR[11..0] (делитель частоты) может влиять на логику I2C-автомата Изменено 1 марта, 2017 пользователем Obam Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 1 марта, 2017 Опубликовано 1 марта, 2017 · Жалоба Но разве I2C_CCR[11..0] (делитель частоты) может влиять на логику I2C-автоматаТам, помнится, одним из битов выбирается режим - быстро или медленно. И в зависимости от режима формируются разные временнЫе диаграммы при одних и тех же уставках в регистрах времянок. Т.е. если не работет на 100 кГц, то точно также, только чуть медленнее не будет работать и на 66. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться