Например TDA7294

Форум РадиоКот • Просмотр темы - i2c на прерываниях не отправляется адрес.
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 17, 2024 02:09:59

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 11 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:05:16 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Чт июн 08, 2017 17:52:33
Сообщений: 39
Рейтинг сообщения: 0
Здравствуйте, хочу написать функцию на прерываниях для i2c. Формирую условие старта . в прерываниях ловлю код 0х08 ,далее в регистр данных посылаю адрес , но в этом месте все зависает в прерывании ... что не так? Контроллер ATMEGA 328 AVRStudio 7. все по даташиту дела.


void i2c_transmit(void) // функция передачи инициирует условие старта далее все должно происходить в прерывани.
{
TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTA)|(1<<TWIE);

}


вектор прерывания

ISR (TWI_vect) // прерывание по i2c
{
switch((TWSR & 0xF8))
{
case 8: // если старт прошел зависает на этом кейсе
{
TWDR = i2c_SlaveAddress; // в дата регистр пишем адрес подчиненного (он уже сдвинут на 1 в лево!)
TWCR = 1<<TWINT|0<<TWSTA|0<<TWSTO|1<<TWEN|1<<TWIE; // команда напередачу
break;
}

case 0x18: // если аск от ведомого получен
{
TWDR=200; // передаем например 200
TWCR = (1<<TWINT)|(1<<TWEN);
}
}

}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:16:47 
Друг Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 1320
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 10429
Рейтинг сообщения: 0
vdv22 писал(а):
TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTA)|(1<<TWIE);


vdv22 писал(а):
TWCR = 1<<TWINT|0<<TWSTA|0<<TWSTO|1<<TWEN|1<<TWIE; // команда напередачу


какой разный стиль... а вот я бы везде ставил скобки, потому что, к стыду своему, приоритетность плохо помню.
а зачем при команде на передачу ещё раз включать и интерфейс, и прерывание, это действительно по даташиту так у атмелов?

Добавлено after 4 minutes 49 seconds:
а, TWCR-у всё заново присваивается... ну. так некрасиво. Это портит логику работы.

_________________
добавь radiokot.ru##.tablebg > tbody > tr:has(td>a[href*="?f=17"]) в адблок, сделай форум чище!
"Э-э-э-хей... растёт правосознание!"


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:19:57 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Чт июн 08, 2017 17:52:33
Сообщений: 39
Рейтинг сообщения: 0
по даташиту TWCR = (1<<TWINT) | (1<<TWEN); так тоже не работает

А разность написания это все результат экспериментов- целый день убил на это . Без прерываний все отлично работает.


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:26:01 
Друг Кота
Аватар пользователя

Карма: 46
Рейтинг сообщений: 1368
Зарегистрирован: Пт авг 28, 2009 21:34:30
Сообщений: 7214
Откуда: 845-й км.
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
В AVR-ах ни бум-бум, но так делать, пожалуй, не стоит:
Код:
switch((TWSR & 0xF8))
Вы уверены, что в регистре будет стоять только один этот бит
Код:
case 8:
А то что не выходите из прерывания - какой-то флаг обработки его не сбрасываете.


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:44:06 
Это не хвост, это антенна

Карма: 15
Рейтинг сообщений: 177
Зарегистрирован: Пт дек 10, 2021 12:48:46
Сообщений: 1326
Откуда: Тюмень
Рейтинг сообщения: 0
Здравствуйте, хочу написать функцию на прерываниях для i2c. Формирую условие старта . в прерываниях ловлю код 0х08

Я в Си не понимаю, но вот что бросилось в глаза... пишете что ловите 0х08 а в коде пишете 0хF8... :dont_know:
Цитата:
switch((TWSR & 0xF8))

а ведь нужно проверять после команды старт именно 0x08 а не 0хF8 :)


Последний раз редактировалось VNS Ср авг 17, 2022 11:46:29, всего редактировалось 1 раз.

Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:47:13 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Чт июн 08, 2017 17:52:33
Сообщений: 39
Рейтинг сообщения: 0
если перед выходом из прерывания добавить TWCR = (1<<TWINT); то зависания нет ,но адрес упороно не передается (по осциллнографу и лог анализатору.

SR (TWI_vect) // прерывание по i2c
{

switch((TWSR & 0xF8))
{
case 8: // если старт прошел
{ out=(TWSR & 0xF8);
TWDR = i2c_SlaveAddress; // в дата регистр пишем адрес подчиненного (он уже сдвинут на 1 в лево!)
TWCR = (1<<TWINT)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN); // команда напередачу
break;
}

case 0x18: // если аск от ведомого получен
{
TWDR=200; // передаем например 200
TWCR = (1<<TWINT)|(1<<TWEN);
}
}

TWCR = (1<<TWINT); // если добавить сброс флага ,то зависания нет ,но адрес упороно не передается (по осциллнографу и лог анализатору.)
}

Добавлено after 1 minute 6 seconds:
Здравствуйте, хочу написать функцию на прерываниях для i2c. Формирую условие старта . в прерываниях ловлю код 0х08

Я в Си не понимаю, но вот что бросилось в глаза... пишете что ловите 0х08 а в коде пишете 0хF8... :dont_know:
Цитата:
switch((TWSR & 0xF8))


F8 это маска . она накладывается на регистр и смотрим какое число получилось


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:53:24 
Это не хвост, это антенна

Карма: 15
Рейтинг сообщений: 177
Зарегистрирован: Пт дек 10, 2021 12:48:46
Сообщений: 1326
Откуда: Тюмень
Рейтинг сообщения: 0
F8 это маска

Теперь понял... извиняюсь что отвлёк... :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 11:56:40 
Друг Кота
Аватар пользователя

Карма: 46
Рейтинг сообщений: 1368
Зарегистрирован: Пт авг 28, 2009 21:34:30
Сообщений: 7214
Откуда: 845-й км.
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Ну если вы так упорствуете:
vdv22 писал(а):
case 8: // если старт прошел
case 0x18: // если аск от ведомого получен
То где кейсы для 0x38, 0x48, 0x58 ... 0xF8? Каждый флаг должен обрабатываться.

В моём драйвере для силикон-лабовского кристалла обработчик выглядит так:
Спойлер
Код:
void I2C_IRQHandler(void) {

  if ((I2C_DEV->IEN & I2C_IEN_ARBLOST) && (I2C_DEV->IF & I2C_IF_ARBLOST)) {// Arbitration lost; Interrupt Flag: UCALIFG; Interrupt
      i2c_error_code = I2C_ERROR;
      i2c_state = i2c_idle;
      I2C_DEV->IFC = I2C_IFC_ARBLOST;
  }
  if ((I2C_DEV->IEN & I2C_IEN_NACK) && (I2C_DEV->IF & I2C_IF_NACK)) { // Not acknowledgment; Interrupt Flag: UCNACKIFG
      i2c_error_code = I2C_ERROR;
      i2c_state = i2c_stop;
      I2C_DEV->IFC = I2C_IFC_NACK;
      BUS_RegMaskedClear(&I2C_DEV->IEN, I2C_IEN_TXBL);
      I2C_DEV->CMD = I2C_CMD_STOP;
  }
  if ((I2C_DEV->IEN & I2C_IEN_START) && (I2C_DEV->IF & I2C_IF_START)) { // Start condition received; Interrupt Flag: UCSTTIFG
      I2C_DEV->IFC = I2C_IFC_START;
      I2C_DEV->TXDATA = i2c_addr;
      if (i2c_state != rcv_data) {
          BUS_RegMaskedSet(&I2C_DEV->IEN, I2C_IEN_TXBL);
      }
  }
  if ((I2C_DEV->IEN & I2C_IEN_RXFULL) && (I2C_DEV->IF & I2C_IF_RXFULL)) { // Check errata race condition
      if (((I2C_DEV->STATUS & I2C_STATUS_RXDATAV) == 0) && (I2C_DEV->STATUS & I2C_STATUS_RXFULL)) {
          I2C_DEV->RXDATA; // make dummy read.
      }
  }
итд...

И, заметьте, после каждого обработанного флага, соответствующий флаг сбрасывается (в регистре IFC). А вы сбрасывая глобальный флаг, возможно оставдяете, что-то необработанным.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 12:06:38 
Сверлит текстолит когтями

Карма: 20
Рейтинг сообщений: 296
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1219
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
Ждете, пока шина будет готова, проверьте код состояния для отправленного условия запуска:
Код:
while(!(TWCR & (1<<TWINT)));

Было бы хорошо обработать все возможные состояния.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 12:11:06 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Чт июн 08, 2017 17:52:33
Сообщений: 39
Рейтинг сообщения: 0
Обработчик всех флагов будет, но мне сейчас дадо чтоб он хоть адрес отправит - я в свиче обычно делаю default чтоб другое не нужное отсечь. Сейчас в прерывание он заходит только один раз (отслеживаю через uart ) то есть после получения 0x08.

Добавлено after 1 minute 45 seconds:
Ждете, пока шина будет готова, проверьте код состояния для отправленного условия запуска:
Код:
while(!(TWCR & (1<<TWINT)));

Было бы хорошо обработать все возможные состояния.

то что вы предлогаете это блокирующий режим -он у меня прекрасно работает . Но я не хочу в цикле жать -мне нужен режим с прерываниями.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: i2c на прерываниях не отправляется адрес.
СообщениеДобавлено: Ср авг 17, 2022 12:30:23 
Сверлит текстолит когтями

Карма: 20
Рейтинг сообщений: 296
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1219
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
Отключите возможности для прерывание в прерывании.
Обработайте все возможные команды/состояния.
Поставьте break; след второй выбор.
Спойлер
Код:
Вариант:
----------
ISR(TWI_vect){
  static unsigned char state = 0, lastVal = 0;
  // Disable Global Interrupt
  cli();
  switch(TW_STATUS){
    case TW_START:  // 0x08
    case TW_REP_START: // 0x10
    case TW_MT_SLA_ACK: // 0x18
    case TW_MT_SLA_NACK: // 0x20
    case TW_MT_DATA_ACK: // 0x28
    case TW_MT_DATA_NACK: // 0x30
    case TW_MR_SLA_ACK:   // 0x40
    case TW_MR_SLA_NACK:   // 0x48
    case TW_MR_DATA_ACK:  // 0x50
    case TW_MR_DATA_NACK:  //  0x58
    case TW_ST_ARB_LOST_SLA_ACK:  //  0xB0
    case TW_SR_ARB_LOST_SLA_ACK: //  0x68
    case TW_SR_GCALL_ACK:    //0x70
    case TW_SR_ARB_LOST_GCALL_ACK:  //  0x78
    case TW_SR_GCALL_DATA_ACK:   // 0x90
    case TW_SR_GCALL_DATA_NACK:  //  0x98
    case TW_NO_INFO:   // 0xF8
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
    case TW_SR_SLA_ACK:      // 0x60: SLA+W received, ACK returned
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
    case TW_SR_DATA_ACK:     // data received
      state = TWDR;
      if(lastVal == 'S'){
         targetTemp = state;
         state = 0;
      }
      lastVal = state;
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
    case TW_SR_STOP:         // 0xA0: stop or repeated start condition received while selected
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
    case TW_ST_SLA_ACK:      // 0xA8: SLA+R received, ACK returned
       if(state == 'T'){
            TWDR = temperature;           // Fill TWDR register whith the data to be sent
         }else if(state == 'H'){
            TWDR = humidity;
         }else{
            TWDR = -1;
         }
      TWCR = ((1 << TWEA) | (1 << TWINT) | (1 << TWEN) | (1 << TWIE));   // Enable TWI, Clear TWI interrupt flag
      break;
    case TW_ST_DATA_ACK:     // 0xB8: data transmitted, ACK received
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
    case TW_ST_DATA_NACK:    // 0xC0: data transmitted, NACK received
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
    case TW_ST_LAST_DATA:    // 0xC8: last data byte transmitted, ACK received
    case TW_BUS_ERROR:       // 0x00: illegal start or stop condition
    default:
      TWCR |= (1<<TWINT);    // Clear TWINT Flag
      break;
  }

  sei();
}


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 29


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y