|
Помогите по i2c, вопрос по asm, Подскажите начинающему, не ясны некоторые моменты |
|
|
|
Jun 23 2008, 17:02
|
Частый гость
 
Группа: Участник
Сообщений: 87
Регистрация: 23-06-08
Пользователь №: 38 503

|
Разбираюсь с протоколом i2c, нашел доку (апноут) AVR 300: Software I2C™ Master Interface и файлик на асме к нему. Пытаюсь сделать програмно эмуляцию i2c под tiny2313. Так вот файлик на асме обзывается: Title : I2C (Single) Master Implementation ;* Version : 1.0 (BETA) ;* Last updated : 97.08.27 ;* Target : AT90Sxxxx (any AVR device) Есть 2 вопроса по тексту программы: 1. Дока пишет, что частоты i2c могут быть 100 и 400кгц. И в программе-примере соответсвенно используются специальне циклы задержки: ;* FUNCTION ;* i2c_hp_delay 100khz ;* i2c_qp_delay 100khz ;* ;* DESCRIPTION ;* hp - half i2c clock period delay (normal: 5.0us / fast: 1.3us) ;* qp - quarter i2c clock period delay (normal: 2.5us / fast: 0.6us) В каких случаях применятся задержка на полпериода, а в каких случаях на четверть периода? 2. В первом же куске кода реализуется повторный старт, например. _________________________________ Кусочек кода из программы для пояснения 2-го вопроса. .... .equ SCLP = 1 ; SCL Pin number (port D) .equ SDAP = 0 ; SDA Pin number (port D) .... i2c_rep_start: sbi DDRD,SCLP ; force SCL low cbi DDRD,SDAP ; release SDA rcall i2c_hp_delay ; half period delay cbi DDRD,SCLP ; release SCL rcall i2c_qp_delay ; quarter period delay _________________________________ Берем первую команду sbi - установить бит. Регистр DDRD ведь управляет направлением работы порта ввода-вывода, каким образом реаизуется установка SCL в ноль? В тексте проги пишут : sbi DDRD,SCLP ; force SCL low Ну и далее по тексту идет cbi и т.д. Не понятно каким образом управляя только DDRD на выводах контроллера реализуются логические уровни? Поясните плз. Ведь чтоб на выводах что-то появилось нужно вывести порт с помощью out, например. Даже если в PORTD что-то есть, и мы конфигурируем порт на ввод, в PORTD нужно что-то положить, чтоб там было что-то и на выводе порта появилась 0 или 1. Поясните плз или подскажите плз, как по другому можно реализовать работу порта для управления только одним выводом. PS Буду очень признателен, если кто-то поделится кусочком кода на asm, релизующего програмно i2c ---------------------------------------------------------------------
|
|
|
|
|
Jun 23 2008, 17:12
|

Частый гость
 
Группа: Свой
Сообщений: 75
Регистрация: 19-12-07
Из: Житоимр
Пользователь №: 33 457

|
Цитата(V000va @ Jun 23 2008, 21:02)  Берем первую команду sbi - установить бит. Регистр DDRD ведь управляет направлением работы порта ввода-вывода, каким образом реаизуется установка SCL в ноль? В тексте проги пишут :
sbi DDRD,SCLP ; force SCL low
Ну и далее по тексту идет cbi и т.д. Не понятно каким образом управляя только DDRD на выводах контроллера реализуются логические уровни? Поясните плз. В схеме на пине SCLP порта D должен весеть подтягивающий резистор, примерно 4,7к на питание. 1. Когда направление (по умолчанию) порта Д как вход, на SCLP логическая еденица. 2. Когда направление порта конфигурируется как выход( sbi DDRD,SCLP ), вывод SCLP коротит резистор на землю, отсюда появляется лог. еденица
Сообщение отредактировал Kalina - Jun 23 2008, 17:16
|
|
|
|
|
Jun 23 2008, 17:20
|
Частый гость
 
Группа: Участник
Сообщений: 87
Регистрация: 23-06-08
Пользователь №: 38 503

|
Цитата(Kalina @ Jun 23 2008, 20:12)  В схеме на пине SCLP порта D должен весеть подтягивающий резистор, примерно 4,7к на питание. 1. Когда направление (по умолчанию) порта Д как вход, на SCLP логическая еденица. 2. Когда направление порта конфигурируется как выход( sbi DDRD,SCLP ), вывод SCLP коротит резистор на землю, отсюда появляется лог. еденица да , резистор в схеме апноута присутсвует, в пункте 2 Вашего ответа, вы хотели сказать, появляется логический 0?
|
|
|
|
|
Jun 23 2008, 17:25
|

Частый гость
 
Группа: Свой
Сообщений: 75
Регистрация: 19-12-07
Из: Житоимр
Пользователь №: 33 457

|
Цитата(V000va @ Jun 23 2008, 21:20)  в пункте 2 Вашего ответа, вы хотели сказать, появляется логический 0? Да именно так оно и есть, когда пин SCLP порта PORTD равен 0!!!!, командой sbi DDRD,SCLP вы выводите этот ноль...
Сообщение отредактировал Kalina - Jun 23 2008, 17:26
|
|
|
|
|
Jun 23 2008, 17:29
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(V000va @ Jun 23 2008, 20:02)  В каких случаях применятся задержка на полпериода, а в каких случаях на четверть периода?
В первом же куске кода реализуется повторный старт, например.
Берем первую команду sbi - установить бит. Регистр DDRD ведь управляет направлением работы порта ввода-вывода, каким образом реаизуется установка SCL в ноль? В тексте проги пишут :
sbi DDRD,SCLP ; force SCL low Ну и далее по тексту идет cbi и т.д. Не понятно каким образом управляя только DDRD на выводах контроллера реализуются логические уровни? По пунктам. 1. В данном случае длительность задержки i2c_hp_delay совпала с минимальным временем паузы после старта (в доках оно называется Tsu_sta - для старта, Tsu_sto - для стопа) оно должно быть не менее 4,7мкс. 2. Поскольку i2c подразумевает выходы с открытым коллектором, во избежание неприятностей на пинах под i2c не должна появляться комбинация например DDRD.SCLP=1 и PORTD.SCLP=1. То же и SDA касается. Таким образом, весь изврат с DDRx предназначен для эмуляции выхода с открытым коллектором
|
|
|
|
|
Jun 23 2008, 17:48
|
Частый гость
 
Группа: Участник
Сообщений: 87
Регистрация: 23-06-08
Пользователь №: 38 503

|
Цитата(_Pasha @ Jun 23 2008, 20:29)  По пунктам. 1. В данном случае длительность задержки i2c_hp_delay совпала с минимальным временем паузы после старта (в доках оно называется Tsu_sta - для старта, Tsu_sto - для стопа) оно должно быть не менее 4,7мкс. 2. Поскольку i2c подразумевает выходы с открытым коллектором, во избежание неприятностей на пинах под i2c не должна появляться комбинация например DDRD.SCLP=1 и PORTD.SCLP=1. То же и SDA касается. Таким образом, весь изврат с DDRx предназначен для эмуляции выхода с открытым коллектором Со вторым пунктом вроде разобрался, а по задержкам можете пояснить подробнее? Например в другой подпрограмме этого же дока так же используются задержки, но не понятно когда какая. ____________________________________ i2c_get_ack: sbi DDRD,SCLP ; force SCL low cbi DDRD,SDAP ; release SDA rcall i2c_hp_delay ; half period delay cbi DDRD,SCLP ; release SCL i2c_get_ack_wait: sbis PIND,SCLP ; wait SCL high ;(In case wait states are inserted) rjmp i2c_get_ack_wait clc ; clear carry flag sbic PIND,SDAP ; if SDA is high sec ; set carry flag rcall i2c_hp_delay ; half period delay ret ________________________________________________ подозреваю, что они берутся исходя из временных диаграмм обмена, но уверенности нет.
|
|
|
|
|
Jun 24 2008, 17:53
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(V000va @ Jun 23 2008, 21:48)  Со вторым пунктом вроде разобрался, а по задержкам можете пояснить подробнее? Даю забудь ты про эадержки Вот тебе небольшой примерчик работы с шиной Код Начни с простого ; ************************************************** ; * * ; * Init Bit Rate fot TWI * ; * * ; ************************************************** ldi temp,SYSCLK/(2*SCL_Freq)-8;TWI Bit Rate Register - TWBR sts TWBR,temp Так ты определишь скорость передачи где SYSCLK - твой кварц SCL_FREQ - cкорость шины Всё начинается с формирования START Код ; ************************************************* ; * * ; * Подпрограмма Init TWI_START * ; * Формирование START и проверка ответа. * ; * * ; * * ; *************************************************
TWI_START: ldi temp, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN) sts TWCR, temp; формирование режима START waitST: lds temp,TWCR ; Проверка бита TWINT sbrs temp,TWINT rjmp waitST ; Не получен -цикл lds temp,TWSR ; Проверка кода ответа ; cpi temp,START breq RETURN ; Правильный код -выход из подпрограммы brne TWI_START ; Нет - повтор. RETURN: ret В первой строке ты формируешь режим старт - в момент начала передачи ( от тебя не зависит) бит TWINT сбрасывается -ты просто ждёшь когда он станет 1 , а в регистр TWSR получаем код 08H если всё хорошо. Если всё плохо - всё надо начинать с начала. я вложил файл - посмотри - в таком режиме я работаю с DS 400Кгц без формирования задержек
Сообщение отредактировал ILYAUL - Jun 24 2008, 17:55
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Jun 25 2008, 15:20
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
По задержкам - смотри у автора стандарта http://www.semiconductors.philips.com/acro...98/39340011.pdf, страница 32-33, STANDART MODE Или аппноут атмела (правда, на сайте атмела я его чего-то не нашел) http://www.eetchina.com/ARTICLES/2003APR/P...OURCES=DOWNLOADХотя, если сравнить эти 2 pdf'а, то оказывается, что у атмела quarter_period равен 2,5мкс, а соответствующие временные задержки у филипса (su-sto hd-sta) - не менее 4 мкс. Более того, филипс рекомендует удержание линии SDA минимум 300нс после спада SCL при записи данных на шину (NOTE 2, страница 32). У Атмела задержка - только 3 такта (i2c_write), что было приемлимо только для серии AT90 (до 8МГц) Думаю, что логичнне всего взять атмеловский avr300 за основу и подкорректировать тайминги по официальной спецификации от филипса.
|
|
|
|
|
Jun 28 2008, 13:49
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425

|
Цитата(V000va @ Jun 25 2008, 15:38)  Дык я так понимаю для серии Mega все просто и понятно, т.к. в ней есть Byte-oriented Two-wire Serial Interface (аналог I2c), а в tiny его нет. В tiny2313 есть Universal Serial Interface (USI), который может работать в режиме I2C. Соответствующий appnote также имеется
|
|
|
|
|
Jul 1 2008, 17:30
|
Частый гость
 
Группа: Участник
Сообщений: 87
Регистрация: 23-06-08
Пользователь №: 38 503

|
Цитата(Александр Куличок @ Jun 29 2008, 20:39)  Не забывай перед вызовом каждой операцией чтения устанавливать корректное значение флага переноса, который здесь используется для передачи ACK/NACK. Также не следует забывать о том,что между стопом и последующим стартом должно пройти минимум 5,7 мкс (это с учетом времени наростания SDA 1 мкс и минимального времени Bus free 4.7 мкс). Данную задержку нужно делать самому, т.к в авр300 ни перед стартом, ни после стопа ее нет. Эмулирую работу программы в Proteus. Анализатор i2c выдает вот что :  Где s - старт, d0 - адрес устройства slave + бит записи (0), А- подтверждение от slave, 00 - пишем адрес откуда будем читать. Sr - повторный старт d1 - адрес slave + бит чтения (1), послендие 00 перед N - это сами данные. N - подтверждение приема от master ( nack). После первого nack идут единицы сплошные, пока на них внимания не обращаю. Р- это стоп. Что интересно, если поменять адрес slave (указать неверный), то slave его не понимает и данных не дает. Т.е. можно предположить, что часть обмена до получения данных проходит верно. При приеме же данных, корректно принимаются только цифры 4 и 5, 0 и 1 в первых 4-х битах принимаемых. Цифры 3 и 2 не принимаются почему-то вообще. В последних 4 битах, правильно принимаются только цифры 0 и 1. Осциллограф показывает вот что:  где 1 - это аск от slave и начало даннных, 2 - это nack от master. В промежутке между 1 и 2 должна была передаться цифра 08. А реально передался 00.
Сообщение отредактировал V000va - Jul 1 2008, 17:34
|
|
|
|
|
Jul 1 2008, 19:02
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата После первого nack идут единицы сплошные, пока на них внимания не обращаю. И правильно идут, так как мастер после чтения 00 выдает nack, сигнаизируя о том, что это был последний запрашиваемый байт (после которого мастер обычно выдает "стоп"). В авр300 ACK/NACK выставляется ПЕРЕД вызовом процедуры чтения последнего байта (i2c_read или i2c_do_transfer). Иными словами, процедура чтения нескольких байт выглядит так: Код ....... ldi i2cadr,$A0+i2crd; Set device address and read rcall i2c_rep_start; Send repeated start condition and address
clc ; ACK rcall i2c_do_transfer; Execute transfer (read) ......... . . . . clc ; ACK rcall i2c_do_transfer; Execute transfer (read) sec ; **NACK** - читаем последний байт rcall i2c_do_transfer; Execute transfer (read) rcall i2c_stop; Send stop condition - releases bus Цитата Эмулирую работу программы в Proteus C протеусом не работал, поэтому вопрос - в протеусе учитывается, что пины контроллера подтянуты к питанию? Так как со стороны контроллера сигналы SDA/SCL либо садятся на "0", либо отпускаются в третье состояние (откуда их внешние резисторы "вытягивают" на логичекую "1" ).
|
|
|
|
|
Jul 2 2008, 10:34
|
Частый гость
 
Группа: Участник
Сообщений: 87
Регистрация: 23-06-08
Пользователь №: 38 503

|
Цитата(Александр Куличок @ Jul 1 2008, 22:02)  И правильно идут, так как мастер после чтения 00 выдает nack, сигнаизируя о том, что это был последний запрашиваемый байт (после которого мастер обычно выдает "стоп"). Вы несколько не поняли. Прочли 00 выдали nack в конце, это ясно. Далее после nack, если верить анализатору, идут: ff - nack - stop. Зачем после 00 идет nack понятно - это конец чтения. Почему же после 00 - nack идет ещё и ff - nack (т.е. сплошные единицы) -stop пока не ясно. Но с этим я разберусь. Важно другое, почему данные читаются не правильно, т.е. вместо 08, читается 00. Если взглянуть на осциллограмму (scl белая, sda синяя линия), то видно, что между цифрами 1 и 2 на ней, проходит один импульс. Т.е. если данные сдвинуть немного правее, чтоб импульс попал под лог "1" , на пятый слева импульс начала приема линии scl, то получится ожидаемая комбинация 08. Впечатление такое, что данные slave выдает не синхронизируясь с scl.  Цитата(Александр Куличок @ Jul 1 2008, 22:02)  C протеусом не работал, поэтому вопрос - в протеусе учитывается, что пины контроллера подтянуты к питанию? Так как со стороны контроллера сигналы SDA/SCL либо садятся на "0", либо отпускаются в третье состояние (откуда их внешние резисторы "вытягивают" на логичекую "1" ). Подтянуты пины к 1-це. Подозреваю что это глюк Proteus. А в чем работаете Вы, в чем моделируете схемы?
Сообщение отредактировал V000va - Jul 2 2008, 10:38
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|