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

 
 
 
Reply to this topicStart new topic
> PIC16F628A + 24LC512 + HT-PICC + i2c sample, Не проходит стоп-условие
stas00n
сообщение Jan 10 2011, 11:07
Сообщение #1


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



Добрый день, коллеги. Подскажите, что не так я делаю? Имеется PIC16LF628A (мастер) и 24LC512 (слейв); программный i2c из примеров HT-PICC 9.80. Пытаюсь записать один байт по адресу, скажем, 0:
1. Посылаю старт-условие и управляющий байт (0b10100000);
2. Посылаю 2 байта адреса (нули);
3. Посылаю байт данных (например, 0xAA);
4. Посылаю стоп-условие.
Прием байтов (пп. 1-3) слейв подтверждает, затем контроллер генерит стоп-условие, однако память почему-то в это время держит SDA в нуле, поэтому стоп условия не получает. Зациклил для наблюдений такой кусочек кода:
CODE
while(1){
t = i2c_WriteTo(I2C_DEVICE_ADDRESS);
t = i2c_PutByte (0);
t = i2c_PutByte (0);
t = i2c_PutByte (0xAA);
i2c_Stop();
__delay_ms(10);
}

Симуляция в протеусе показывает, что слейв не отпускает SDA:

В реальном железе наблюдаю настоящим осциллографом то же самое. в линиях включены резисторы по 150 Ом, со стороны контроллера "стоповый" импульс примерно 2 В, со стороны памяти совсем маленький...
В даташите процесс записи нарисован так:

Вроде все правильно делаю, а работает неправильно.
Прилагаю модель для протеуса и прошивку, хелп!


Прикрепленные файлы
Прикрепленный файл  dsn_n_hex.zip ( 18.32 килобайт ) Кол-во скачиваний: 18
 
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 10 2011, 11:22
Сообщение #2


Гуру
******

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



Я извиняюсь за такой вопрос, но есть ли у вас на линиях шины I2C pull-up резисторы? Если есть, то какого номинала? "в линиях включены резисторы по 150 Ом" - это о них или о резисторах, включенных последовательно с линией?
И еще. Вы зря сразу стали пробовать запись. Попробуйте вначале проверить алгоритм работы I2C на чтении EEPROM.
Go to the top of the page
 
+Quote Post
stas00n
сообщение Jan 10 2011, 11:49
Сообщение #3


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



Подтяжка, естественно есть, по 10 кОм; 150 Ом последовательно в линиях SDA, SCL между памятью и МК. С чтением тоже проблемы, но еще глубоко не копал в чем дело, сейчас этим занимаюсь. Кстати, забыл сказать - все тайминги в хайтековском модуле i2c.h увеличил в 100 раз, чтоб удобней было осциллографом смотреть.

Сообщение отредактировал stas00n - Jan 10 2011, 11:50
Go to the top of the page
 
+Quote Post
paskal
сообщение Jan 10 2011, 12:23
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769



Цитата(stas00n @ Jan 10 2011, 17:07) *
Симуляция в протеусе показывает, что слейв не отпускает SDA:

Слейв может держать SDA если хочет выдать на шину данные, либо выдать бит ACK. Так как вы туда записываете, то остается последний вариант. Может вы на шине CLK не додаете 1 такт чтоб слейв закончил выдавать acknowledge? (Т.е. он выдает ACK, а фронт по CLK который заканчивает эту операцию, слейв не получает)

p.s.
А подтяжка должна быть посильнее 10 кОм
Go to the top of the page
 
+Quote Post
stas00n
сообщение Jan 10 2011, 12:58
Сообщение #5


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



Такты считал - ровно 9 штук:
А резисторы 10кОм рекомендованы для частоты 100 кГц, у меня будет намного меньше.
Go to the top of the page
 
+Quote Post
paskal
сообщение Jan 10 2011, 13:13
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769



Цитата(stas00n @ Jan 10 2011, 18:58) *
Такты считал - ровно 9 штук

9-й такт должен закончится нулем. В единичном состоянии CLK, слейв не имеет права менять сигнал на SDA. попробуйте дернуть CLK еще раз, посмотрите что поменяется.
Go to the top of the page
 
+Quote Post
stas00n
сообщение Jan 10 2011, 13:55
Сообщение #7


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



Да! так заработало! Подправил макрос i2c_Stop() и вуаля, все пишется и читается! Спасибище огромное! cheers.gif А ведь исходник-то "фирмовый" хайтековский, вот ведь как бывает..
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 10 2011, 21:13
Сообщение #8


Гуру
******

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



Кстати, напряжение половины уровня лог.1 может также свидетельствовать о некорректности реализации алгоритма I2C, когда лог.1 выдается мастером не ОК или Z-состоянием выхода SDA, а нормальной лог.1. При этом к питанию линию "тянет" транзисторный выходной каскад, а не внешний pull-up резистор. Проверьте, что это не так.
Go to the top of the page
 
+Quote Post
stas00n
сообщение Jan 11 2011, 07:56
Сообщение #9


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



rezident, да есть такое дело, для дергания выводами в хайтековском модуле применяются макросы SDA_HIGH(); SDA_LOW() и т.д.:
CODE

/* Change port as required - defaults to port b */
#define SCL RA1 /* clock on port A bit 1 */
#define SCL_DIR TRISA1
#define SDA RA0 /* data on port A bit 0 */
#define SDA_DIR TRISA0
#define I2CTRIS TRISA
#define I2C_INPUT 1 /* data direction input */
#define I2C_OUTPUT 0 /* data direction output */
//....
#define SCL_HIGH() SCL = 1; SCL_DIR = I2C_OUTPUT
#define SCL_LOW() SCL = 0; SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA = 1; SDA_DIR = I2C_OUTPUT
#define SDA_LOW() SDA = 0; SDA_DIR = I2C_OUTPUT

Может, стоит изменить их на такие:
CODE

//....
#define SCL_HIGH() SCL_DIR = I2C_INPUT
#define SCL_LOW() SCL = 0; SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA_DIR = I2C_INPUT
#define SDA_LOW() SDA = 0; SDA_DIR = I2C_OUTPUT
?

Сообщение отредактировал stas00n - Jan 11 2011, 08:00
Go to the top of the page
 
+Quote Post
paskal
сообщение Jan 11 2011, 14:54
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 29-10-06
Из: Тула
Пользователь №: 21 769



Цитата(rezident @ Jan 11 2011, 03:13) *
Кстати, напряжение половины уровня лог.1 может также свидетельствовать о некорректности реализации алгоритма I2C, когда лог.1 выдается мастером не ОК или Z-состоянием выхода SDA, а нормальной лог.1. При этом к питанию линию "тянет" транзисторный выходной каскад, а не внешний pull-up резистор. Проверьте, что это не так.

В том месте мастер должен быть неактивен, а 24LC512 выводить бит ACK. Может быть там на короткий момент происходит конфликт на шине когда слейв выдает 0, а мастер тянет к логической 1.


Цитата(stas00n @ Jan 11 2011, 13:56) *
Может, стоит изменить их на такие:
CODE

//....
#define SCL_HIGH() SCL_DIR = I2C_INPUT
#define SCL_LOW() SCL = 0; SCL_DIR = I2C_OUTPUT
#define SDA_HIGH() SDA_DIR = I2C_INPUT
#define SDA_LOW() SDA = 0; SDA_DIR = I2C_OUTPUT

Теоретически так и надо
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 11 2011, 17:56
Сообщение #11


Гуру
******

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



Цитата(paskal @ Jan 11 2011, 22:54) *
когда слейв выдает 0, а мастер тянет к логической 1
Дык это уже криминал. Никто на шине I2C не имеет права тянуть ее принудительно к лог.1 ни в какой момент времени.
Go to the top of the page
 
+Quote Post
stas00n
сообщение Jan 11 2011, 19:05
Сообщение #12


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



Тем не менее, такие вот фокусы подсовывает хайтек. Реализация i2c из папки с примерами из комплекта компилятора. Уже начинаю думать - не проще ли было бы самому с нуля написать?
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 11 2011, 19:15
Сообщение #13


Гуру
******

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



Цитата(stas00n @ Jan 12 2011, 03:05) *
Уже начинаю думать - не проще ли было бы самому с нуля написать?
Может и не проще, но уж точно полезнее. Вылавливать глюки в чужих программах сложнее, особенно когда для них нет никакой внятной документации (хотя бы в виде описания алгоритмов).
Go to the top of the page
 
+Quote Post
stas00n
сообщение Jan 11 2011, 19:16
Сообщение #14


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

Группа: Участник
Сообщений: 181
Регистрация: 26-11-10
Пользователь №: 61 198



Цитата(paskal @ Jan 11 2011, 19:54) *
В том месте мастер должен быть неактивен, а 24LC512 выводить бит ACK. Может быть там на короткий момент происходит конфликт на шине когда слейв выдает 0, а мастер тянет к логической 1.

Да нет, ACK нормально проходил, мастер переключался на вход, конфликт возникал позже, когда мастер пытался послать стоп-условие установкой выхода SDA в "1" (к тому же, как выяснилось, - некорректно), а слейв держал SDA в нуле из-за того что отрицательный фронт не поступал на SCL после передачи ACK.
Сейчас все исправил, работает sm.gif
Go to the top of the page
 
+Quote Post

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

 


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


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