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

 
 
> переключение контента+TimeOut I2C, Как выявить зависание
pokk
сообщение May 29 2017, 09:35
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Добрый день, есть функция чтение температуры из термодатчика Lm75ad во время ожидания ожидания флага передаю управления другому процессу portYIELD(); Так вот если замкнуть линии I2C то процесс чтения температуры зависает, а остальное все работает. Так вот как по феншую сделать отработку зависания ? Пока только одна идея перед каждый ожидание засекать время, и в диспетчере смотреть больше оно таймаута или нет, но мне это не нравиться тем что это надо прятать в дефайны, что не айс, или код "загромождать". Если другие способы определения ?


uint8_t OS_Lm75ad_Read(short unsigned int* dataout,const unsigned char addr){
static short unsigned int tmp[2];
static short unsigned int* dataout_temp;
//------------------------------------------------------------------------------------
LED_DEBUG_ON
dataout_temp=dataout;
while(I2C_GetFlagStatus(I2C_LM75AD, I2C_FLAG_BUSY)){portYIELD();};
LED_DEBUG_OFF
//------------------------------------------------------------------------------------
I2C_GenerateSTART(I2C_LM75AD, ENABLE);
/* check start bit flag */
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_MODE_SELECT)){portYIELD();};
LED_DEBUG_ON
//----------------------SEND_ADDR_Write-------------------------------------------------------
I2C_Send7bitAddress(I2C_LM75AD,(addr), I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){portYIELD();};
//----------------------POINT------------------------------------------------------------------
I2C_SendData(I2C_LM75AD,LM75AD_ADDR_REG_Temp); //Регист Temp(температура)
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){portYIELD();};
LED_DEBUG_ON
//----------------------RE-START-------------------------------------------------------------------
I2C_GenerateSTART(I2C_LM75AD, ENABLE);
/* check start bit flag */
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_MODE_SELECT)){portYIELD();};
LED_DEBUG_OFF
//-------------------Send_addr_read------------------------------------------------------
I2C_Send7bitAddress(I2C_LM75AD, (addr), I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){portYIELD();};
LED_DEBUG_ON
//------------------------------------------------------------------------------------------
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_BYTE_RECEIVED)){portYIELD();};
LED_DEBUG_OFF
tmp[0]=I2C_ReceiveData(I2C_LM75AD);
//------------------------------------------------------------------------------------------
while(!I2C_CheckEvent(I2C_LM75AD, I2C_EVENT_MASTER_BYTE_RECEIVED)){portYIELD();};
LED_DEBUG_ON
tmp[1]=I2C_ReceiveData(I2C_LM75AD);
//------------------------------------------------------------------------------------------
I2C_GenerateSTOP(I2C_LM75AD, ENABLE);
/*stop bit flag*/
I2C_AcknowledgeConfig(I2C_LM75AD, ENABLE);
while(I2C_GetFlagStatus(I2C_LM75AD, I2C_FLAG_BUSY)){portYIELD();};
LED_DEBUG_OFF
//------------------------------------------------------------------------------------------
*dataout_temp=(tmp[0]<<8)|tmp[1];
NOP;NOP;NOP;NOP;NOP;
LED_DEBUG_ON
//------------------------------------------------------------------------------------------
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
pokk
сообщение May 31 2017, 04:32
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 91
Регистрация: 3-07-11
Пользователь №: 66 028



Цитата
Если ваш ЖК-модуль на основе контроллера HD44780, то в DDRAM символы с кодами 00...07 - это переопределяемые символы. При инициализации занулите их, т. е. сделайте пробелами, чтобы при получении кода 0 выводился пробел а не крякозабра.
так и есть в 0 ячейка стоит символ градуса, по нему и сужу что там 0 на дате приходит =))

Цитата
Что надо обнаруживать: наличие и исправность датчика, или КЗ на I2C?

Что бы вся периферия на I2C работала гарантированно и после КЗ что бы нечего не зависало, и в случае какой либо помехи,её не было заметно.
Но вообще хочу сделать по полной и наличие датчиков на линии тоже, и в случае выхода одного из строя что бы все остальное работало.
(над последним пока ещё думаю как это сделать,пока останавливаюсь на том что, если много раз зависал в одной функции то перейти на более медленный опрос этой функции раз в 10 секунд, или вообще выключить её опрос)
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 31 2017, 08:29
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(pokk @ May 31 2017, 07:32) *
(1) . . .. , и в случае выхода одного из строя что бы все остальное работало.
(2) . . . .если много раз зависал в одной функции то перейти на более медленный опрос этой функции раз в 10 секунд, или вообще выключить её опрос)

(1) если датчик закоротит одну из линий I2C - то естественно, "ляжет" вся шина. И с этим ничего не сделаешь.
Шина I2C - внутрисхемный интерфейс, и если датчик висит на проводе более 10 см - готовьтесь к проблемам.
Чтоб ОНО таки работало, проверьте подтягивающие резисторы I2C. Они должны быть (для надежной рабты периферии, в соотв-ии с миним. требованиями стандарта)
R = 4.7 ... 10 кОм. ОНО будет, конечно, работать и на 100к, но помехоустойчивать будет приближаться к 0.
Снижать вниз R нельзя, можно попалить выходные узлы как мастера, так и слейвов.
Экранируйте провод линии - если они внешние для прибора.
Для работы с длинной внешней шиной I2C есть спец. микросхемы-драйверы.
(2)
не используйте
Код
while( USCI_I2C_RDY_ ) { }  - прямой путь к завесам в нем.

лучше так
Код
MyTimer.Start(1000);
while( USCI_I2C_RDY )  // бит периферийного узла I2C
{
   if( MyTimer.IsElaps() )
   {
        RetCode = eI2C_ERR_RDY;
        break;
   }
}

Завесы при работе с периферией I2C вполне возможны. slave может войти в "ступор" (ожидание) и ваш софт получит коллизию - навечно, до второго пришествия
Reset. Вывести шину из этого состояния софтово можно принудительной подачей 9 clk (узел I2C отключить. ногодрыг SCK)

Вообще, если что-то не работает или "глючит" - 99 проц. - вина аффтара софта и железа sm.gif
Не устраняйте последствия, найдите и устраните причину сбойной работы.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 31 2017, 09:30
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(k155la3 @ May 31 2017, 10:29) *
Вообще, если что-то не работает или "глючит" - 99 проц. - вина аффтара софта и железа sm.gif
Не устраняйте последствия, найдите и устраните причину сбойной работы.

Т.е. - заменить автора? biggrin.gif
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 31 2017, 10:55
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(jcxz @ May 31 2017, 12:30) *
Т.е. - заменить автора?

Нет. Пока мы тут "бухтим как косм. корабли бороздят Большой Театр" ОН должен "расти на собой".
Это не к ТС или к кому либо sm.gif

Цитата(pokk @ May 31 2017, 13:02) *
С этим понятно я имел ввиду то что он по адресу не будет отвечать. . . .

При холодном старте
1. Проверка на "залипший" слейв. Если залипло - попытка сброса залипа. Если неудачно - LCD_Display("I2C fault", __LINE__);
2. Проверки на наличие и исправность всх имеющихся на шине slave
Код
for(. . . )
{
    if( I2C_SlaveIsConnect( slave_list[i] )
           continue;
    else
    {
            LCD_Display("Slave error", i);
            while(1)  {}
    }
}

3. Надежность работы конечно зависит от типа-марки-произовдителя slave. Мне пока достаточно I2C_SlaveIsConnect( ADDR )
так как небыло необходимости.
4. Таймауты готовности slave (в смысле его внутреннего состояния). К примеру если это EEPROM в том или ином виде - то надо при последоватьельной записи
потока данных выдерживать таймауты, пока в EEPROM пройдут внутренние операции (собственно запись). В вашем случае - время оцифровки. Пред любой операцией
- читать регистры статуса напредмет готовности.

ps - "Так вот если замкнуть линии I2C то процесс чтения температуры зависает, ... "
Это понятно, на шине любое изменение (фронт, спад) отслеживается автоматами как master так и slave.
Можно завесить все - если при этом вошел в коллизию (фактически из-за помехи) автомат master-а, или "зависнет" какой либо слейв - ожидая неизвестно чего,
напр. после ложного "старта".
Проверяйте HW - если глючек в нем, то копаться в софте бессмыслено.


Сообщение отредактировал k155la3 - May 31 2017, 11:00
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- pokk   переключение контента+TimeOut I2C   May 29 2017, 09:35
- - firew0rker   Cчeтчик с условием таймаута можно запрятать в функ...   May 30 2017, 02:20
- - pokk   А где перезапустить счетчик ? Что бы для последую...   May 30 2017, 03:37
|- - firew0rker   Цитата(pokk @ May 30 2017, 10:37) А где п...   May 30 2017, 05:13
- - pokk   firew0rker, спасибо за помощь примерно то что я и...   May 31 2017, 02:33
- - firew0rker   Подключите линию Е через расширитель. При КЗ на ли...   May 31 2017, 02:57
- - pokk   "Подключите линию Е через расширитель. При КЗ...   May 31 2017, 03:20
- - firew0rker   Если ваш ЖК-модуль на основе контроллера HD44780, ...   May 31 2017, 03:39
- - firew0rker   Согласна с написанным k155la3 и ещё добавлю: чтобы...   May 31 2017, 09:09
- - pokk   Цитата(1) если датчик закоротит одну из линий I2C ...   May 31 2017, 10:02


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

 


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


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