реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> MSP430 и I2C. Постоянно - UCBBUSY.
devfom
сообщение Sep 1 2011, 09:10
Сообщение #1





Группа: Новичок
Сообщений: 8
Регистрация: 15-06-11
Пользователь №: 65 710



Добрый день. Есть микроконтроллер MSP40F5438 и не могу побороть проблему замкнутого цикла while( UCB1STAT & UCBBUSY ); Поиск показал, что я не одинок, и нашел информацию о том, что необходимо реализовывать I2C Bus Clear, из спецификации. Для этого написал простой цикл( здесь, и далее я использую UCB1, у которого PORT5.4 - SCL, PORT3.7 - SDA):
Код
P5DIR |= BIT4;
P5SEL &= ~BIT4;
P5OUT &= ~BIT4;
for( pulseCounter = 0; pulseCounter < 9; pulseCounter++ ) {
P5OUT |= BIT4;
__delay_cycles( 100 );
P5OUT &= ~BIT4;
__delay_cycles( 100 );
}
P5OUT |= BIT4;
P5SEL |= BIT4;


После его выполнения, шина по прежнему остается занятой. Микроконтроллер работает на частоте 25МГц поэтому __delay_cycles( 100 ); дает задержку в 5мкс.

Как все таки правильно делать ресет шины? Единственное, что пока я нашел, что шина становится свободной, как только я переподключаю девайс с которым общаюсь. Протокол обмена с девайсом прост - изначально контроллер и девайс находятся в режиме в slave-receiver, а переключаются в master-transmitter только когда нужно что-то передать. После конфигурирования, мне необходимо инициализировать девайс, но это невозможно т.к шина занята.
Спасибо за любые идеи.
Go to the top of the page
 
+Quote Post
KARLSON
сообщение Sep 1 2011, 12:53
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



А до того как подключили девайс к шине, на шине какие уровни по напряжению?
И зря так делаете P5OUT |= BIT4;
Вы управляйте направлением порта а не его логикой. OUT = 0; а потом либо DIR |= BIT4; либо DIR &= ~BIT4;

Сообщение отредактировал KARLSON - Sep 1 2011, 12:56


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 1 2011, 13:37
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Во-первых, вам правильно сделали замечание насчет управления лог.1 записью в P5OUT. Шина I2C управляется открытым коллектором или открытым стоком. Поэтому лог.1 нужно формировать, запрограммировав пин как вход, а не как выход с лог.1.
Во-вторых, в нормальном состоянии на шине I2C лог.1, а вы как-то странно заканчиваете цикл Bus clear выдавая лог.0 на SCL. Это неправильно. нужно освободить SCL, установив лог.1 в конце Bus clear.
В-третьих, Bus clear нужно выполнять до инициализации модуля I2C. Ну или после процедуры Bus clear (ре)инициализировать его вновь.
Ну и в-четвертых, "глупый" вопрос. У вас вообще pull-up резисторы на шине имеются?
Go to the top of the page
 
+Quote Post
devfom
сообщение Sep 2 2011, 07:25
Сообщение #4





Группа: Новичок
Сообщений: 8
Регистрация: 15-06-11
Пользователь №: 65 710



Цитата(KARLSON @ Sep 1 2011, 16:53) *
А до того как подключили девайс к шине, на шине какие уровни по напряжению?
И зря так делаете P5OUT |= BIT4;
Вы управляйте направлением порта а не его логикой. OUT = 0; а потом либо DIR |= BIT4; либо DIR &= ~BIT4;


К сожалению уровни посмотреть не могу, пишут под собранную железку и никуда не добраться.

Цитата(rezident @ Sep 1 2011, 17:37) *
Во-первых, вам правильно сделали замечание насчет управления лог.1 записью в P5OUT. Шина I2C управляется открытым коллектором или открытым стоком. Поэтому лог.1 нужно формировать, запрограммировав пин как вход, а не как выход с лог.1.
Во-вторых, в нормальном состоянии на шине I2C лог.1, а вы как-то странно заканчиваете цикл Bus clear выдавая лог.0 на SCL. Это неправильно. нужно освободить SCL, установив лог.1 в конце Bus clear.
В-третьих, Bus clear нужно выполнять до инициализации модуля I2C. Ну или после процедуры Bus clear (ре)инициализировать его вновь.
Ну и в-четвертых, "глупый" вопрос. У вас вообще pull-up резисторы на шине имеются?


Pull-up резисторы есть. Т.е выходит, что цикл инициализации USCI в режим I2C начинать с UCB1STAT & UCBBUSY, и если вернет истину, то делать сброс, а потом конфигурировать? Я заметил дебаггером, что флаг UCBBUSY устанавливается уже после инициализации, а не до того. В этом случае делаем Bus clear, и после него инициализировать все заново?

Поправил Bus clear функцию:
Код
void vI2CBusClear() {    
    char pulseCounter = 0;
    P5SEL &= ~BIT4;
    P5OUT &= ~BIT4;
    for( pulseCounter = 0; pulseCounter < 9; pulseCounter++ ) {
        P5DIR ^= BIT4;        
        __delay_cycles( 100 );
    }
    P5DIR &= ~BIT4;
    P5SEL |= BIT4;
}


Спасибо.

Сообщение отредактировал devfom - Sep 2 2011, 07:28
Go to the top of the page
 
+Quote Post
mib383
сообщение Jun 9 2012, 03:59
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Во-первых, вам правильно сделали замечание насчет управления лог.1 записью в P5OUT. Шина I2C управляется открытым коллектором или открытым стоком. Поэтому лог.1 нужно формировать, запрограммировав пин как вход, а не как выход с лог.1.
Насчет этого не очень понятно. Если порт поставить на вход, то как тогда подавать импульсы?

П.С. Такая же проблема
Go to the top of the page
 
+Quote Post
KARLSON
сообщение Jun 9 2012, 04:22
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



регистр OUT = 0, как для вывода SCL так и для вывода SDA. На этих линиях должны быть резисторы подвешенные к 3 В, примерно 5-15 кОм. Что бы сделать логическую "1" на линии, нужно порт сделать входом, PxDIR &= ~BITx; что бы сделать логический "0" необходимо порт сделать выходом, PxDIR |= BITx;
А лучше использовать аппаратный I2C.


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
mib383
сообщение Jun 9 2012, 04:42
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Я и так аппаратный использую. Но в msp340f47187, насколько я понимаю, нет аппаратного BusClear. Поэтому приходится перенастраивать порты (SEL = 0), а после давать импульсы. Или я где-то не прав...
И... насколько я понимаю, импульсы нужно подавать только на SCL? в спецификации написано:

... If the data line (SDA) is stuck LOW, the master should send nine !!clock pulses!!...


И, может быть, задаю глупый вопрос: объясните почему если порт настроен на вход, то будет лог 0, а если на выход, то будет лог 1?

И почему так делать лучше, чем через OUT = 0/1
Go to the top of the page
 
+Quote Post
KARLSON
сообщение Jun 9 2012, 04:43
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



Я же написал наоборот. Вход это 1, выход это 0.
Аппаратный я использовал во втором семействе. Никаких проблем не было.
Если Вы мастер, то и SCL и SDA дёргать надо, если нет то только SDA.

Цитата(mib383 @ Jun 9 2012, 08:42) *
И почему так делать лучше, чем через OUT = 0/1

Когда у slave будет 0, а вы раз так и OUT = 1 сделаете, то получится КЗ по питанию. 3В на GND и скорее всего порты выгорят.

Сообщение отредактировал KARLSON - Jun 9 2012, 04:49


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
mib383
сообщение Jun 9 2012, 04:47
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Спасибо. Но, честно говоря все равно не очень понятно.
Go to the top of the page
 
+Quote Post
KARLSON
сообщение Jun 9 2012, 04:51
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



Что именно не понятно?
Пока вы отвечали, я редактировал своё предыдущее сообщение.


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
mib383
сообщение Jun 9 2012, 04:57
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Ну допустим, почему если я мастер, нужно дергать обе линии, а не только SCL. Ведь в спецификации этого нет...

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

Сообщение отредактировал mib383 - Jun 9 2012, 05:01
Go to the top of the page
 
+Quote Post
mib383
сообщение Jun 9 2012, 07:04
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 4-04-12
Пользователь №: 71 177



Обнаружил, что после выставления адреса и настройки i2c на передачу нужна задержка перед стартовым состоянием. Не могу понять почему?

Снимаю вопрос) Разобрался, дело было не в этом
Go to the top of the page
 
+Quote Post
controller_m30
сообщение Jun 9 2012, 19:36
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 24-02-09
Пользователь №: 45 309



На MSP430F5342 делаю BusClear так...
1. При инициализации портов настраиваю линию порта SCL в out, а SDA в in.
2. Делаю 10 тактов SCL в последовательности 1,0;1,0;... 1,0
3. Перевод SDA в out, уровень SDA=0.
4. Сигнал STOP - SCL=1 и после этого SDA=1
5. Перевод выводов под управление модуля USCI записью 1 в порт PSEL.

Все изменения уровней делаются с задержкой чтоб соблюсти скорость не выше 100кГц.
Работает такой BusClear у меня уверенно. Проц находится в непрерывном опросе трёх IIC устройств, сброс и снятие питания делается часто (откл. батареек, подключение к программатору и проч.) - шина I2C всё время доступна.
Go to the top of the page
 
+Quote Post
controller_m30
сообщение Jun 10 2012, 05:46
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 24-02-09
Пользователь №: 45 309



Есть ещё предположение, что иногда STOP в конце BusClear может не сработать - если подчинённое устройство выдаст в это время ACK на шину (если ведомый IIC был как Slave Transmitter).
Потому, для надёжности я добавил сегодня STOP ещё ДО 10 тактов на линии SCL, а линию SDA использую как открытый коллектор чтоб уменьшить энергопотребление.

В итоге всё выглядит так:
1. Бит Pout(SDA)=0 (для будущей имитации открытого коллектора на линии SDA с применением регистра Pdir).
2. Pdir(SCL)=1, Pout(SCL)=0.
3. Pdir(SDA)=1 на линиях SCL и SDA получился ноль - исходная позиция для STOP.
4. Pout(SCL)=1, Pdir(SDA)=0 провёл первый STOP на шине.
5. 10 тактов SCL в последовательности 1,0;1,0;... 1,0
6. Pdir(SDA)=1 на линиях SCL и SDA ноль - исходная позиция для второго STOP.
7. Pout(SCL)=1, Pdir(SDA)=0 провёл второй STOP на шине.
8. Перевод выводов под управление модуля USCI записью 1 в порт PSEL.

В таком виде BusClear наверное ещё надёжнее. Если первый STOP придётся на ACK подчинённого, то после 10 тактов на линии SCL, второй STOP попадёт уже в точку rolleyes.gif

excl.gif Вот ещё что... У меня все устройства I2C не запускают никаких действий по сигналу STOP, потому я применяю STOP для BusClear (а одно устройство даже требует STOP для завершения обмена - иначе оно за себя не ручается biggrin.gif (барометр BMP085) ).
А если на шине I2C есть флешка - то лучше наверное ограничиться классическим BusClear из только из 9 тактов SCL...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 18:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01499 секунд с 7
ELECTRONIX ©2004-2016