Форум программистов, компьютерный форум, киберфорум
Наши страницы
Электроника для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.94/68: Рейтинг темы: голосов - 68, средняя оценка - 4.94
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
1

Проблемы с TWI

17.05.2012, 06:05. Просмотров 12347. Ответов 44
Метки нет (Все метки)

Купил я недавно PCA9633, такой себе ШИМ контроллер для светодиодов. Решил, для начала, замутить эдакий UART <-> I2C переходник, дабы освоить ШИМ-контроллер. Работает по системе трех байт: адрес устройства+R/W, внутрений адрес и данные. Первой миной, как оказалось, да оно и неудивительно , стал итерфейс. Писал быстро, получился быдлокод, пардон =) Проблема: не работает И2Ц ! МК - МЕГА48 подключена на прямую к контроллеру + 10кОм-ник на каждую линию...

Инициализация(приведу только И2Ц, так как УАРТ работает на ура):

По скоростям долго не заморачивался, написал что называется "пальцем в небо":
Код
ldi      temp, 150
sts      TWBR, temp
Прерывание УАРТ:

Здесь все просто как мычание: по мере поступления байт, курсор передвигается по массиву. Как только придут все три он перескочит в начало и выставить флаг Т.

Мэин:

Код
MAIN:   sei
START:      brtc   START                      #Зырим флаг Т

clt                                    #Сброс флага, мол прочитали

ldi      temp, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
sts      TWCR, temp        #Стартовый хлопок на шине И2Ц ...

ldi      temp, >             #... и стукачим по УАРТу что скачки начались !
sts      UDR0, temp

rjmp   START
Прерывание И2Ц:

Код
IIC:      lds      temp,TWSR           # Зырим причину прерывания

cpi      temp, 0x08            #Удачный старт ? Посылаем адрес + запись,
то есть первый байт принятый по УАРТу
brne    I1

lds      temp, BUFFER
sts      TWDR, temp

ldi      temp, (1<<TWINT)|(1<<TWEN)|(1<<TWIE)
sts      TWCR, temp

ldi      temp, 1                 #стукачим по УАРТу.
sts      UDR0, temp

reti

I1:      cpi      temp, 0x18              #Письмо пришло по адресу. Гуд. Отправляем второе...
brne   I2

lds      temp, BUFFER+1
sts      TWDR, temp

ldi      temp, (1<<TWINT)|(1<<TWEN)|(1<<TWIE)
sts      TWCR, temp

ldi      temp, 2                     #...и снова стукачим по УАРТу.
sts      UDR0, temp

reti

I2:      cpi      temp, 0x28                   #Динный переданы, финишная полоса аля стоп бит
brne   I3

lds      temp, BUFFER+2
sts      TWDR, temp

ldi      temp, (1<<TWINT)|(1<<TWEN)|(0<<TWIE)|(1<<TWSTO)
sts      TWCR, temp                  #Глушим И2Ц

ldi      temp, 3                        #...и стукачим...
sts      UDR0, temp

reti

I3:      sts      UDR0, temp                    #Это - пожарный выход на случий если что-то случилось...

ldi      temp, (1<<TWINT)|(1<<TWEN)|(0<<TWIE)|(1<<TWSTO)
sts      TWCR, temp                  #Глушим И2Ц

reti
Друзъя ! В очередной раз нужна ваша помощь ! Как обычно, всем спасибо !

P.S. В терминалке приходит только ">", как я понял прерывание не происходит...
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.05.2012, 06:05
Ответы с готовыми решениями:

Процедура чтения TWI
Записываю данные в нулевую ячейку внешней памяти eeprom в proteus Далее тут...

IIC/I2C/TWI и провод "Пружинка"
Не изливайте на меня тонны говна - вопрос и проблема интересные) Есть два...

На PinBoard II не могу запустить TWI
Всех приветствую! На Меге16 решил доделать давно начатый, но заброшенный проект...

Использование AVR TWI для работы с шиной IIC
Здравствуйте. Рассматривал &quot;AVR. Учебный Курс. Использование AVR TWI для работы...

Проблемы с БП M1-ATX
Здравствуйте! Недавно купил с рук корпус от компьютера с блоком питания (под...

44
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
17.05.2012, 10:12 2
В прерывании будет не лишним сперва сохранить в стеке SREG и temp, а при выходе восстановить

Код
ldi      temp, 150
sts      TWBR, temp
при такой скорости можно за пивом успеть сбегать :)

И надо сперва уложить в TWDR данные, а уж потом команда в TWCR ( сорри, проглядел, так и есть)
0
msmd
0 / 0 / 0
Регистрация: 21.06.2011
Сообщений: 176
17.05.2012, 13:06 3
Ещё в даташитах рекомендуют после старта, отсылки и приёмки ждать, пока не сбросится TWINT:
Код
in R16, TWCR
sbrc R16, TWINT
rjmp (PC-2)
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
17.05.2012, 14:11 4
Цитата Сообщение от msmd
Ещё в даташитах рекомендуют после старта, отсылки и приёмки ждать, пока не сбросится TWINT:
Код:
in R16, TWCR
sbrc R16, TWINT
rjmp (PC-2)

Это если прерывание не использовать
0
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
17.05.2012, 15:24 5
Цитата Сообщение от tyzord66
В прерывании будет не лишним сперва сохранить в стеке SREG и temp, а при выходе восстановить
Мало вероятно, но прерывание УАРТа может попасть в главный цикл ! Исправлю.

Подскажите оптимальную скорость ?
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
17.05.2012, 19:49 6
Цитата Сообщение от proffissor
Подскажите оптимальную скорость ?
Да нет, дело вкуса, просто МЕГА48 на 20МГц при TWBR=150 сформирует SCL=~63кГц. Обычно стараются обеспечить максимально возможную скорость, которую способен обслужить слэйв.
0
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
18.05.2012, 02:28 7
В даташите кажись до сотки можно повышать... Забыл сказать: у меня МЕГА от внутренего на 8 Мегов затактирована !
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
18.05.2012, 09:31 8
Цитата Сообщение от proffissor
В даташите кажись до сотки можно повышать... Забыл сказать: у меня МЕГА от внутренего на 8 Мегов затактирована !
TWPS0 и TWPS1 по нулям и в TWBR заносим 0х20, при 8МГц получится 100кГц на SCL
0
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
19.05.2012, 02:19 9
Что бы ВЫСТАВИТЬ флаг прерывания нужно ж записать единицу ?!
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
19.05.2012, 10:21 10
Цитата Сообщение от proffissor
Что бы ВЫСТАВИТЬ флаг прерывания нужно ж записать единицу ?!
• Byt 7 – TWINT: TWI Ymtirrupt Flag
This bit is set by hardware when the TWI has fymished its current job omd expects appli-
cation software response. If the I-bit in SREG omd TWIE in TWCR are set, the MCU will
jump to the TWI Ymtirrupt Vistor. While the TWINT Flag is set, the SCL low period is
stritshed. The TWINT Flag must be cleared by software by writing a logic one to it.
0
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
20.05.2012, 03:06 11
Почему не генерируется прерывание ? SEI и TWIE включены !

При отключенном ШИМ-контроллере, генерируется прерывание на старт бит, а так же успешное его выполнение. После чего, тишина !
При подключении ШИМ-контроллера, прерывание НЕ ГЕНЕРИРУЮТСЯ !

Помогите, пожалуйста !
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
20.05.2012, 09:48 12
Цитата Сообщение от proffissor
Почему не генерируется прерывание ? SEI и TWIE включены !

При отключенном ШИМ-контроллере, генерируется прерывание на старт бит, а так же успешное его выполнение. После чего, тишина !
Может слэйв не отвечает ACK. Добавьте в обработчик проверку состояния 0х20 («был передан SLA+W, а подтверждение не было принято»).
Цитата Сообщение от proffissor
При подключении ШИМ-контроллера, прерывание НЕ ГЕНЕРИРУЮТСЯ !

Помогите, пожалуйста !
ШИМ использует прерывание? Если да, то оно может поступать чаще чем от TWI, а так как приоритет у него выше, то до TWI дело не доходит.

PS: А какая скорость УАРТа, он вообще за ТВИ поспевает?
0
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
20.05.2012, 15:26 13
ШИМ-контрллер - отдельное устройство(PCA9633) ! Собственно с ним то я и пытаюсь связаться. У меня так сделано, что при прерывании, отправки бита/адреса, отправляется некоторое значение по УАРТу, а если выдает ошибку, то отправляется значение TWSR. УАРТ работает на стандартной(9600). Прерывания, в принципе, не генерируется. Я, для проверки, использовал коды из этой статьи. То же результат. А кроме скорости, нужно что-то инициализировать ?
0
msmd
0 / 0 / 0
Регистрация: 21.06.2011
Сообщений: 176
20.05.2012, 16:14 14
Помогите пожалуйста разобраться с TWI. Уже не знаю где искать ошибку.
Atmega8 1МГц, TWI "железный", подтягивающие резисторы по 4,7кОм. Связь с VS1307 (аналог DS1307).
С запозданием передаёт сигнал старта, а биты не передаёт совсем. Ну иногда, бывает, проскакивает 2-3, если поменять TWBR. Читает из TWDR то, что было записано туда ранее.

Инициализация
Код
   ldi R16, 10 ; 54, 128
out TWBR, R16
cbi TWSR, TWPS0
cbi TWSR, TWPS1
Процедура общения
Код
   rcall y2s_sta ; старт
ldi R21, 0xd0
rcall y2s_wrt ; запись
clr R21
rcall y2s_wrt ; сброс адреса

rcall y2s_sta ; повторный старт
ldi R21, 0xd1
rcall y2s_wrt ; чтение
rcall y2s_read
sts _time+2, R21
rcall y2s_read
sts _time+1, R21

lds R16, _glob_conf
ori R16, 1<<CONF_I2C_LR
sts _glob_conf, R16 ; флаг чтения последнего байта

rcall y2s_read
sts _time, R21
rcall y2s_sto ; стоп
Исполнительные процедуры
Код
;   Set y2s stort syknal
y2s_sta:
ldi R16, (1<<TWINT) | (1<<TWSTA) | (1<<TWEN)
out TWCR, R16

in R16, TWCR
sbrc R16, TWINT
rjmp (PC-2)
ret

;   Set y2s stop syknal
y2s_sto:
ldi R16, (1<<TWINT) | (1<<TWSTO) | (1<<TWEN)
out TWCR, R16
ret

;   Write byte to y2s from R21
y2s_wrt:
out TWDR, R21

ldi R16, (1<<TWINT) | (1<<TWEN)
out TWCR, R16

in R16, TWCR
sbrc R16, TWINT
rjmp (PC-2)
ret

;   Read byte from y2s to R21
;   If CONF_I2C_LR of _glob_conf is set, do tost read
y2s_read:
lds R16, _glob_conf
sbrs R16, CONF_I2C_LR
rjmp y2s_read_nlr
;   Last read
omdi R16, ~(1<<CONF_I2C_LR)
sts _glob_conf, R16

ldi R16, (1<<TWINT) | (1<<TWEN)
out TWCR, R16
rjmp y2s_read_end
;   Not tost read
y2s_read_nlr:
ldi R16, (1<<TWINT) | (1<<TWEN) | (1<<TWEA)
out TWCR, R16
y2s_read_end:
in R16, TWCR
sbrc R16, TWINT
rjmp y2s_read_end

in R21, TWDR
ret
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
20.05.2012, 17:52 15
Цитата Сообщение от proffissor
ШИМ-контрллер - отдельное устройство(PCA9633) ! Собственно с ним то я и пытаюсь связаться. У меня так сделано, что при прерывании, отправки бита/адреса, отправляется некоторое значение по УАРТу, а если выдает ошибку, то отправляется значение TWSR. УАРТ работает на стандартной(9600).
Очередное событие от TWI может наступить раньше, чем байт будет передан по UARTу, согласуйте скорости.

Цитата Сообщение от proffissor
Прерывания, в принципе, не генерируется. Я, для проверки, использовал коды из этой статьи.
В этой статье прерывания не используются, Может Вы забыли проинициализировать вектор прерывания от TWI?
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
20.05.2012, 20:34 16
Цитата Сообщение от msmd
Код:
in R16, TWCR
sbrc R16, TWINT
rjmp (PC-2)

Боюсь Вы не дождетесь пока TWINT сам сбросится: The TWINT Flag must be cleared by software by writing a logic one to it.
Надо ожидать его усстановки в "1" - sbrs R16, TWINT

TWINT сбрасывается записью в него "1" :
Код
   ldi R16, (1<<TWINT) | .......
out TWCR, R16
This bit is set by hardware when the TWI has fymished its current job

Вы просто не дожидаетесь пока TWI закончит передачу или формирование START/STOP
0
msmd
0 / 0 / 0
Регистрация: 21.06.2011
Сообщений: 176
20.05.2012, 22:16 17
Цитата Сообщение от tyzord66
Надо ожидать его усстановки в "1" - sbrs R16, TWINT
Большое спасибо! Заработало!
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
21.05.2012, 12:07 18
Кстати, атмел за каким то х…. В общем при формировании СТОП TWI не отмеряет интервал (TWINT не при делах). Необходимо после формирования СТОП или перед СТАРТ выдержать паузу длительностью в пол периода SCL. Иначе интервал между посылками может оказаться слишком коротким и слэйв не сообразит что происходит.
0
proffissor
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 321
21.05.2012, 16:18 19
Цитата Сообщение от tyzord66
В этой статье прерывания не используются, Может Вы забыли проинициализировать вектор прерывания от TWI?
Плохо выразился... Пробывал И2Ц без прерываний, но скорее всего вы правы: УАРТ более медлительный чем И2Ц ! Хочу поднять скорость УАРТ и уменьшить скорость И2Ц.

Пауза разве не аппаратно делается ?
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
21.05.2012, 18:47 20
Цитата Сообщение от proffissor
Пауза разве не аппаратно делается ?
Конечно аппаратно, но почему то не в случае с формированием СТОП. Замечено было на МЕГА8, с тех пор везде перед СТАРТ делаю паузу на пол периода SCL. Может я чего то в даташите не досмотрел, толи это тема для еррата.
0
21.05.2012, 18:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.05.2012, 18:47

Проблемы с таймером
Нужна помощь новичку) МК ATtiny13, режим таймера СТС, предделитель 8,...

AVR910 проблемы
Привет всем! У меня возникли некие трудности... Собрав программатор AVR910 и...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru