Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как маскировать прерывания I2C в atmega128?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Pechka
Каким способом можно не меняя состояния конечного автомата I2C запретить или разрешить прерывание по I2C? Например, в одной из функций программы нужно на время запретить прерывание I2C (и только его!) а затем включить, но чтобы при этом не портить состояние конечного автомата? Через регистр TWCR портится состояние и обмен происходит с ошибками. Глобальным cli, sei не подходит - другие функции должны работать.
P.S. контроллер atmega128
_Артём_
Цитата(Pechka @ Jun 5 2013, 18:03) *
Каким способом можно не меняя состояния конечного автомата I2C запретить или разрешить прерывание по I2C?

Код
void disableTwiInterrupt()
{
TWCR=(1<<TWEN) | (1<<TWEA) |(0<<TWIE);
}



Цитата(Pechka @ Jun 5 2013, 18:03) *
Через регистр TWCR портится состояние и обмен происходит с ошибками.

Что именно портится? Каким образом меняете TWCR?
Pechka
Цитата(_Артём_ @ Jun 5 2013, 18:24) *
Что именно портится? Каким образом меняете TWCR?

Через регистр TWCR происходит передача команд в аппаратный блок (в зависимости от значения TWSR в TWCR кладутся разные значения для обеспечения обмена). Таким образом, меняя значение TWCR в процессе обмена не ясно, что именно будет передано в линию: команда из только что обработанного прерывания I2C либо данные, обновленные в приведенной процедуре. Если TWINT=1 то, понятно, проблем нет - машина состояния ждет действий от приложения, а вот если TWINT=0 и штука обменивается данными - тогда не понятно. Например, я ведущий и посылаю стоп, а после этого делаю отключение прерывания указанным способом, то стоп дойдёт до ведомого или же потеряется?
_Артём_
Цитата(Pechka @ Jun 5 2013, 18:40) *
Таким образом, меняя значение TWCR в процессе обмена не ясно, что именно будет передано в линию: команда из только что обработанного прерывания I2C либо данные, обновленные в приведенной процедуре.

Запись в регистр TWCR запускает генерацию START, STOP и тп. Для запуска нужного действия нужно в соответствующий бит записать 1.
Запись 0 никаких действий не вызывает.

Цитата(Pechka @ Jun 5 2013, 18:40) *
если TWINT=0 и штука обменивается данными - тогда не понятно. Например, я ведущий и посылаю стоп, а после этого делаю отключение прерывания указанным способом, то стоп дойдёт до ведомого или же потеряется?

Вроде нет указаний что STOP не дойдёт, но тут надо проверять.

Цитата(Pechka @ Jun 5 2013, 18:40) *
после этого делаю отключение прерывания указанным способом, то стоп дойдёт до ведомого или же потеряется?

Нельзя одновременно запретить прерывание и запустить нужное действие?
Код
void TwiSendStop()
{
TWCR=0
| (1<<TWEN)
| (1<<TWEA)
| (0<<TWIE)
| (1<<TWSTO)
| (1<<TWINT)
;
}
Pechka
Цитата(_Артём_ @ Jun 5 2013, 19:05) *
Запись в регистр TWCR запускает генерацию START, STOP и тп. Для запуска нужного действия нужно в соответствующий бит записать 1.
Запись 0 никаких действий не вызывает.

А ещё ACK, (TWEA). Если происходит обмен и в прерывании АСК был выставлен, а потом снялся - он будет выставлен или снят в итоге?
Цитата(_Артём_ @ Jun 5 2013, 19:05) *
Вроде нет указаний что STOP не дойдёт, но тут надо проверять.

Хотелось бы готовое решение.
Цитата(_Артём_ @ Jun 5 2013, 19:05) *
Нельзя одновременно запретить прерывание и запустить нужное действие?

Нет, поскольку процессы асинхронные и независимые.

Мне нужно просто чтобы TWI закончил текущее действие и ждал пока ему включат прерывания для дальнейшей работы sad.gif


_Артём_
Цитата(Pechka @ Jun 5 2013, 19:38) *
А ещё ACK, (TWEA). Если происходит обмен и в прерывании АСК был выставлен, а потом снялся - он будет выставлен или снят в итоге?

Естественно TWEA (а также TWEN) нужно оставлять такими же - если был 1, то пишем 1 и наоборот.
Для этого нужно предварительно прочитать текущее состояние TWCR, замаскировать биты в которых нельзя писать единицы и записать новое значение TWCR с запрещённым прерыванием.
Или если в программе TWEA всегда имеет одинаковое значение, то сразу писать в TWCR без предварительного чтения.

Цитата(Pechka @ Jun 5 2013, 19:38) *
Хотелось бы готовое решение.

Может такое решение где-то и выложено в сети, но его ещё надо найти.
Но с другой стороны - меги достаточно простые МК и может проще всё сделать заново.

Цитата(Pechka @ Jun 5 2013, 19:38) *
Мне нужно просто чтобы TWI закончил текущее действие и ждал пока ему включат прерывания для дальнейшей работы sad.gif

Так может прерывания для TWI вообще не нужно?
Работать например через поллинг.

Цитата(Pechka @ Jun 5 2013, 19:38) *
ему включат прерывания для дальнейшей работы sad.gif

Может проще не разрешать прерывание, а вызвать функцию которая выполнит нужные действия с TWI ?
Pechka
Цитата(_Артём_ @ Jun 5 2013, 19:57) *
Естественно TWEA (а также TWEN) нужно оставлять такими же - если был 1, то пишем 1 и наоборот.
Для этого нужно предварительно прочитать текущее состояние TWCR, замаскировать биты в которых нельзя писать единицы и записать новое значение TWCR с запрещённым прерыванием.
Или если в программе TWEA всегда имеет одинаковое значение, то сразу писать в TWCR без предварительного чтения.


Может такое решение где-то и выложено в сети, но его ещё надо найти.
Но с другой стороны - меги достаточно простые МК и может проще всё сделать заново.


Так может прерывания для TWI вообще не нужно?
Работать например через поллинг.


Может проще не разрешать прерывание, а вызвать функцию которая выполнит нужные действия с TWI ?

Без прерываний не получится - и так ресурс на пределе. Там кроме TWI ещё куча всего. Прочитать, обнулить биты TWIE, TWINT и записать обратно - может сработать - попробую завтра. Спасибо!
Pechka
Цитата(Pechka @ Jun 5 2013, 20:43) *
Без прерываний не получится - и так ресурс на пределе. Там кроме TWI ещё куча всего. Прочитать, обнулить биты TWIE, TWINT и записать обратно - может сработать - попробую завтра. Спасибо!

Не помогло. Может, проблема в чем-то ещё - буду разбираться.
ILYAUL
Вообще-то он автомат и как любой автомат не любит не определённого состояния.
Даже после формирования стоп нормальным считается проверить состояние бита TWSTO , а уж затем делать следующий шаг.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.