Здравствуйте, хочу написать функцию на прерываниях для 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); } }
TWCR = 1<<TWINT|0<<TWSTA|0<<TWSTO|1<<TWEN|1<<TWIE; // команда напередачу
какой разный стиль... а вот я бы везде ставил скобки, потому что, к стыду своему, приоритетность плохо помню. а зачем при команде на передачу ещё раз включать и интерфейс, и прерывание, это действительно по даташиту так у атмелов?
Добавлено after 4 minutes 49 seconds: а, TWCR-у всё заново присваивается... ну. так некрасиво. Это портит логику работы.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
если перед выходом из прерывания добавить 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); // если добавить сброс флага ,то зависания нет ,но адрес упороно не передается (по осциллнографу и лог анализатору.) }
И, заметьте, после каждого обработанного флага, соответствующий флаг сбрасывается (в регистре IFC). А вы сбрасывая глобальный флаг, возможно оставдяете, что-то необработанным.
Обработчик всех флагов будет, но мне сейчас дадо чтоб он хоть адрес отправит - я в свиче обычно делаю default чтоб другое не нужное отсечь. Сейчас в прерывание он заходит только один раз (отслеживаю через uart ) то есть после получения 0x08.
Отключите возможности для прерывание в прерывании. Обработайте все возможные команды/состояния. Поставьте 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; }
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 38
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения