Перейти к содержанию
    

Работа с MSP430x2xx

Здравствуйте. Скажите пожалуйста, а в каком случае устанавливается бит UCBBUSY в регистре UCB0STAT модуля USCI в режиме I2C.

Дело вот в чём: В течении примерно часа происходит сбой на шине. Смотрю регистры и в каком месте произошёл сбой. Так вот, после успешного некоторого обмена с микросхемой слейвом, завершающийся операцией стоп, при следующем обмене происходит проверка занятости шины или то что SCL в нуле "if (UCB0STAT & (UCBBUSY + UCSCLLOW))".

Мастер на шине только я (контроллер), смотрю на шину осциллографом, на шине SDA и SCL уровень логический 1. А бит UCBBUSY установлен в 1 (все остальные в регистре нули). Помогает только путём возведения и опускания бита UCSWRST в регистре UCB0CTL1.

 

Кстати контроллер 430F2132

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Цитирую юзергайд

START and STOP conditions are generated by the master and are shown in Figure 17−3. A START condition is a high-to-low transition on the SDA line while SCL is high. A STOP condition is a low-to-high transition on the SDA line while SCL is high. The bus busy bit, UCBBUSY, is set after a START and cleared after a STOP.

При работе с битовыми масками рекомендуется использовать операцию "побитового ИЛИ", а не сложение, чтобы избежать недоразумений при случайном наложении одной и той же маски. То бишь ваша проверка условия должны выглядеть как

if (UCB0STAT & (UCBBUSY | UCSCLLOW))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендацию я конечно же учту, но в чём разница результата операций "|" и "+"?

PS А модуль USCI в режиме I2C + UART я всё таки укратил (пока ошибок не было). В понедельник проверю ещё раз и если всё в порядке приведу код.

И ещё (типа слова к разработчикам контроллера), зря запихали они в один вектор прерывания и передачу по UART и приём/передача по I2C, а в другой приём по UART с битами состояния шины I2C. Векторов что ли жалко было?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендацию я конечно же учту, но в чём разница результата операций "|" и "+"?

 

"|" - это побитовое ИЛИ , а "+" - сложение

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В понедельник проверю ещё раз и если всё в порядке приведу код.
Советую все же ознакомиться с оригинальной спецификацией I2C и реализовать функцию Bus clear. Весьма пригодится ;)

Векторов что ли жалко было?
Это сделано для совместимости с модулем USART, реализованным в более ранних сериях MSP430 (1xx, 4xx).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но результат то один и тот же!

 

Советую все же ознакомиться с оригинальной спецификацией I2C и реализовать функцию Bus clear. Весьма пригодится ;)

restart при зависании шины заложена.

Изменено пользователем KARLSON

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но результат то один и тот же!
При ошибке результат будет разный. Например, в случае двойного включения маски

#define BIT1 0x02
#define BIT2 0x04

mask &= (BIT1 | BIT2 | BIT1)); //реализуется в mask &= 0x06;
mask &= (BIT1 + BIT2 + BIT1)); //реализуется в mask &= 0x08;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не ошибка! Это нормальные логичные результаты. А вот в случает if (UCB0STAT & (UCBBUSY + UCSCLLOW)) результат будет один и тот же. Просто кто как привык писать код.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос по внешним прерываниям для Port1(2). Все выводы порта на вход и на всех настроены прерывания.

Если наступило событие по одному из выводов порта вызвавшее прерывание, то находясь в обработчике прерываний при наступлении события уже по другому выводу как поведет себя контроллер?

То есть если P1_1 перешел из лог. 1 в лог. 0 и мы попали обработчик прерывания Port1 и в это время P1_2 перешел из лог.1 в лог. 0 то потеряется ли это событие и что сделать чтобы его не потерять?

По сути такое может произойти на всех выводах порта.

 

И ещё вопрос если во время одного типа прерывания выставляется флаг для другого, то прерывание потеряется или отработается по очереди? (подразумевается, что все регистры правильно настроены и прерывания разрешены)

 

Если бы у меня была отладка то вопросы бы не задавал. Но в распоряжении только симулятор IAR :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Цитирую User's Guide: 8.2.6 P1 and P2 Interrupts -> Interrupt Flag Registers P1IFG, P2IFG

Only transitions, not static levels, cause interrupts. If any PxIFGx flag becomes set during a Px interrupt service routine, or is set after the RETI instruction of a Px interrupt service routine is executed, the set PxIFGx flag generates another interrupt. This ensures that each transition is acknowledged.
То бишь потери прерывания происходить не должно. Единственно, что это не гарантировалось во время непосредственной модификации регистров PxIFG. Этот баг под именем PORT3 описан где-то в errata для старых кристаллов.

Вот нашел его описание в MSP430F13x/14x/14x1 Device Erratasheet - SLAZ017A.PDF.

PORT3 Port3 - Bug description:

 

Module: PORT1/2, Function: Port interrupts can get lost

 

Port interrupts can get lost if they occur during CPU

access of the P1IFG and P2IFG registers.

 

Workaround:

None

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

rezident, спасибо! А то мне после Atmel непривычно разбираться в доках MSP. Прочитал этот раздел внимательнее. :)

Я специально написал в этой теме потому что работаю с MSP430x2xx.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Буду благодарен, если поясните один такой момент режимом энергосбережения. Зачем делать LPM3_EXIT; при выходе из прерывания? Ведь уже в при входе прерывание контроллер находится с активном режиме и работает на своей MCLK. И что произойдет, если забыть про LPM3_EXIT?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И что произойдет, если забыть про LPM3_EXIT?
При выходе из прерывания восстановится значение SR и ядро опять в режим LPM3 перейдет. Соответственно будут выполняться только обработчики активных прерываний, а основной цикл программы будет стоять.

См. в User's Manual: 2.2.3 Interrupt Processing -> Return From Interrupt.

Хотя, если у вас весь код программы выполняется именно в прерывании, то LPMx_EXIT и не требуется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, я так и предполагал. Уточнил для уверенности. Это может быть удобным для многих программ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Советую все же ознакомиться с оригинальной спецификацией I2C и реализовать функцию Bus clear. Весьма пригодится ;)

Это сделано для совместимости с модулем USART, реализованным в более ранних сериях MSP430 (1xx, 4xx).

Огромное спасибо за ссылку, нашел в документе требования к подтягивающим резистрам с учетом емкости проводников ПП, а то изрядно в свое время повозился... Из-за плохих фронтов на линиях интерфейса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...