0
Ну звеняйте, на каждый чих состояний шины ни один производитель не стал заморачиваться регистрами флагов прерываний и векторами переходов. Т.ч или флаг или состояние шины, что в принципе одно и тоже, не выигрывается ничего.
  • avatar
  • ILYAUL
  • 31 июля 2018, 23:23
0
Почему дембель?
  • avatar
  • ILYAUL
  • 08 сентября 2016, 22:02
0
И кстати, тут forum.easyelectronics.ru/viewtopic.php?f=4&t=23185&p=426914#p426914 уже всё обсудили
  • avatar
  • ILYAUL
  • 21 января 2016, 20:17
0
Это какие новые
  • avatar
  • ILYAUL
  • 21 января 2016, 20:15
0
Так они особо не мучались, открыли DS на микруху и скопировали формулу оттуда, подставив где надо константы.
  • avatar
  • ILYAUL
  • 04 февраля 2014, 14:25
0
Ему должно быть пофиг, температура участвует в расчёте давления и оно должно оставаться стабильным
  • avatar
  • ILYAUL
  • 03 февраля 2014, 12:56
0
Да, какое-то странное давление, если даже грубо пересчитать 239134/133 = 1798 мм.рт.ст
  • avatar
  • ILYAUL
  • 03 февраля 2014, 12:54
0
Т.е i2c_busy — целый регистр отвечает за то, что шина занята? Или в нем есть разбивка, кем занята?
Судя по команде tst — всё таки целый.
Я бы использовал флаг T регистра SREG для которого есть набор команд для установки, снятия и проверки его состояния.
  • avatar
  • ILYAUL
  • 21 декабря 2013, 22:31
0
Key_opros:              
                lds temp,i2c_want_job   ;проверяем флаги заданий по и2ц
                  ..........
                lds temp,i2c_busy       ;сначала проверим флаг занятости и2ц 
                

Чем они отличаются?
Key_opros:              
                lds temp,i2c_want_job   ;проверяем флаги заданий по и2ц

И буквально на следующем шаге
Led_opros:      ;теперь проверим а установлен ли флаг отправки нового значения в PCF8574led
                lds temp,i2c_want_job

Зачем?
И и2ц глаза режет
  • avatar
  • ILYAUL
  • 21 декабря 2013, 21:52
0
Это каким образом нам прерывание TWI дает возможность не проверять ответ адресата? При условии работы на шине разнотипных устройств, со своими командами общения, до каких величин вырастает таблица? Что может быть быстрее приведённого мной выше обработчика INT0, который можно замаскировать и выполнить в свободное от основной работы время? Для старших микросхем ему даже RJMP не нужен.
На самом деле по тому же принципу можно использовать само прерывание TWI т.е. просто флаг. И обработчик TWI в MAIN, RCALL, ICALL ,RET/ При этом только критические секции скрыть СLI.
  • avatar
  • ILYAUL
  • 20 декабря 2013, 00:39
0
BeginInt EndInt макросы заталкивающие/выталкивающие temp и count и сохраняет SREG.
  • avatar
  • ILYAUL
  • 18 декабря 2013, 21:49
0
rcall   TWI_START                       ;+ стартуем
                ldi             temp,DS37SlaveAddr
                rcall   DATA                            ;+ посылаем SlaveAddress
                cpi             temp,SLVNORMW           ;- Если не $18 снова на START
                brne    TIME_RESTART            ;+ начинаем сначала
                ldi             temp,0x0F                       ;- Устанавливаем адрес статус регистра DS1337
                rcall   data                            ;+ Посылаем адрес регистра статуса
                cpi             temp,NORMDATW           ;+ Проверяем
                brne    TIME_RESTART            ;- если не $28 повтор
                clr             temp                            
                rcall   data                            ;- Очищаем регистр статуса
                cpi             temp,NORMDATW           ;+ Проверяем
                brne    TIME_RESTART            ;- если не $28 повтор

Вот это из кода надо выбросить т.к. он очищает регистр статуса ибо часы у меня настроены на вывод один раз в минуту и прерывание в микросхеме необходимо сбрасывать иначе последующие не получите.
  • avatar
  • ILYAUL
  • 18 декабря 2013, 21:45
0
Только с учетом что ICALL «умеют» использовать не все микросхемы AVR
  • avatar
  • ILYAUL
  • 18 декабря 2013, 21:38
0
Т.е Вы предлагаете мне сейчас изучить DS на совершенно неизвестную для меня микросхему, написать для нее код и посчитать такты :) Перед Вами код для DS1337 прямая родственница DS1307 и судя по всему ВЫ ее знаете. Посчитайте, даже предположив, что TIME_READ это код прерываниия. Т.е другое прерывание в этот момент не возможно. Будем считать что ошибок на шине нет т.е нет повторов.
st              Z+,temp                         ;+ и записываем в ОЗУ
                dec             count                           ;- вычитаем счётчик
Это счетчик байтов которые необходимо отправить.
  • avatar
  • ILYAUL
  • 18 декабря 2013, 21:35
0
Архитектура AVR для прерывания TWI не содержит однозначности в отличие от других прерываний USART, TIMERs, ADC и прочего. Которые могут обрабатываться достаточно быстро.
ИМХО, его в крайнем случае можно использовать только для отправки, получения данных (т.к. код при этом одинаков) а всё остальное за рамками прерывания.
  • avatar
  • ILYAUL
  • 18 декабря 2013, 16:16
0
О каком реальном времени Вы говорите? Не очень понял.
Прошла минута, отработал INT0:
sbr Flags,1<<CLOCK
reti

Дальше по флагу
rcall TIME_Read
  • avatar
  • ILYAUL
  • 18 декабря 2013, 15:04
0
TWI не делают на прерывании- это нонсенс. (очень медленный интерфейс по сравнению с ресурсами проца. И тем более столько сидеть в прерывании. К тому же для каждой шага обмена существует свой индивидуальный код т.ч. проверять все ошибки при выполнении определенного действия — тратить время.

;**************************************************
;*       ;;+INIT and write in  DS1337;;*	  	  *
;**************************************************
DS37INIT:
		ldi		count,BUFINTDS		;= Загружаем размер буфера InitDS1337
		rcall	TWI_START			;= стартуем
		ldi		temp,DS37SlaveAddr
		rcall	DATA				;= посылаем SlaveAddress
		cpi		temp,SLVNORMW		;- Если не $18 снова на START
		brne	RetInit				;= повтор
		clr		temp				;= Установка на регистр $00 DS1337 (секунды )
		rcall	DATA
		cpi		temp,NORMDATW		;= Проверка на ACK
		brne	RetInit				;-Если не $28 снова на START
FLASH_or_SRAM:
		sbrc	Flags1,fl_SRAM_FLASH
		rjmp	SRAM_DS1337
		lpm		temp,Z+				;= извлекаем данные
INIT_DS37:
		rcall	DATA				;= Вызываем подпрограмму отсылки
		cpi		temp,NORMDATW		;= Проверка на ACK
		brne	RetInit				;- Если не $28 снова на START
		dec		count				;= вычитаем счётчик данных для DS1337
		brne	FLASH_or_SRAM
		rjmp	OutINTDS37			;+ Инициализация закончена.
RetInit:
		rcall	STOP				;* STOP - Not GOOT
		rjmp	DS37INIT			;= снова на СТАРT
OutINTDS37:
		rcall	STOP				;/ STOP - GOOD
		ret
SRAM_DS1337:
		ld		temp,Z+
		rjmp	INIT_DS37

;**************************************************
;*   		;;+Проверка сбоя часов;;*   		  *
;**************************************************
TIME_ERROR:
		rcall	TWI_START			;+ стартуем
		ldi		temp,DS37SlaveAddr
		rcall	DATA				;+ посылаем SlaveAddress
		cpi		temp,SLVNORMW		;- Если не $18 снова на START
		brne	RESTART				;+ начинаем сначала
		ldi		temp,0x0F			;- Устанавливаем адрес статус регистра DS1337
		rcall	data				;+ Посылаем адрес регистра статуса
		cpi		temp,NORMDATW		;+ Проверяем
		brne	RESTART				;- если не $28 повтор
		rcall	TWI_START			;+ Ещё раз cтартуем
		ldi		temp,DS37SlaveAddr+1
		rcall	DATA				;- посылаем SlaveAddress на чтение
		cpi		temp,SLVNORMR		;+ Проверяем
		brne	RESTART				;- если не $40 повтор
		rcall	DATA				;+ Вызываем подпрограмму
		cpi		temp,NORMDATR		;- Если не $50
		brne	RESTART				;+ начинаем сначала
		lds		temp,TWDR			;- Если $50 считываем данные
		sbrs	temp,MsbOne			; Проверяем установлен старший бит
		rjmp	ERR_TIME_END
		sbr		Flags,1<<fl_Err_Time
ERR_TIME_END:
		ret
RESTART:
		rcall	STOP
		rjmp	TIME_ERROR
;**************************************************
;*    ;;/Программа чтения данных из DS1337;;*	  *
;**************************************************
TIME_Read:
		BeginInt					;- Заталкиваем в стек
		ldwi	Z,BUFDS1337			;+ Заносим начальный адрес SRAM DS37 в регистр (Z)
		ldi		count,BUFINTDS-1	;- Загружаем размер буфера InitDS1337
;* Сбрасываем флаг A2F
TIME_START:
		rcall	TWI_START			;+ стартуем
		ldi		temp,DS37SlaveAddr
		rcall	DATA				;+ посылаем SlaveAddress
		cpi		temp,SLVNORMW		;- Если не $18 снова на START
		brne	TIME_RESTART		;+ начинаем сначала
		ldi		temp,0x0F			;- Устанавливаем адрес статус регистра DS1337
		rcall	data				;+ Посылаем адрес регистра статуса
		cpi		temp,NORMDATW		;+ Проверяем
		brne	TIME_RESTART		;- если не $28 повтор
		clr		temp				
		rcall	data				;- Очищаем регистр статуса
		cpi		temp,NORMDATW		;+ Проверяем
		brne	TIME_RESTART		;- если не $28 повтор
TIME_Read1:
		rcall	TWI_START			;+ Ещё раз cтартуем
		ldi		temp,DS37SlaveAddr+1
		rcall	DATA				;- посылаем SlaveAddress на чтение
		cpi		temp,SLVNORMR		;+ Проверяем
		brne	TIME_RESTART		;- если не $40 повтор
TIME_Read4:
		rcall	DATA				;+ Вызываем подпрограмму
		cpi		temp,NORMDATR		;- Если не $50
		brne	TIME_RESTART		;+ начинаем сначала
		lds		temp,TWDR			;- Если $50 считываем данные
		st		Z+,temp				;+ и записываем в ОЗУ
		dec		count				;- вычитаем счётчик
		brne	TIME_Read4			;+ нет - след. данные
		rcall	DSNACK
		rcall	STOP				;/ - STOP GOOD
		EndInt						;- Выталкиваем из стека
		sbr		Flags,1<<fl_Minut	;+ Устанавливаем флаг минуты
		reti
TIME_RESTART:
		rcall	STOP				;- формируем STOP
		rjmp	TIME_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				;= Правильный код -выход из подпрограммы
		cpi		temp,REPSTART
		brne	TWI_START			;= Нет - повтор.
RETURN:
		ret
;**************************************************
;*   ;;+Подпрограмма IN/OUT данных в DS;;* 		  *
;**************************************************
DATA:
		sts		TWDR,temp
		ldi		temp,(1<<TWINT)|(1<<TWEN)|(1<<TWEA)
		sts		TWCR,temp			;= режим данные
waitDT:
		lds		temp,TWCR			;= Проверка бита TWINT
		sbrs	temp,TWINT
		rjmp	waitDT
		lds		temp,TWSR			;= получаем код передачи
		ret
;**************************************************
;*      ;;+Подпрограмма формирование STOP;;*      *
;**************************************************
STOP:
		ldi		temp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
		sts		TWCR,temp			;= Формирование режима STOP
waitTWIStop:
		lds		temp,TWCR			;= Считываем регистр управления
		sbrc	temp,TWSTO			;= Проверяем бит STOP
		rjmp	waitTWIStop			;= Не установлен - повторяем проверку
		ret
;**************************************************
;*              ;;+Формируем NACK;;*              *
;**************************************************
DSNACK:
		ldi		temp,(1<<TWINT)|(1<<TWEN)|(0<<TWEA)
		sts		TWCR,temp			;= формируем режим NACK
waitDT1:
		lds		temp,TWCR
		sbrs	temp,TWINT			;= Проверка бита TWINT
		rjmp	waitDT1				;= Ждём
		lds		temp,TWSR			;= получаем код ответа
		cpi		temp,NACK			;- Если не $58
		brne	TIME3				;= Всё сначала - обидно!
		lds		temp,TWDR			;= Если $58 считываем данные
		st		Z,temp				;= и записываем в ОЗУ
		ret
TIME3:
		rcall	STOP				;= формируем STOP
		rjmp	TIME_Read1			;= начинаем заново

;|*************************************************
  • avatar
  • ILYAUL
  • 18 декабря 2013, 12:03
0
Да
  • avatar
  • ILYAUL
  • 17 декабря 2013, 14:12
+1
500 байт прерывание — я застрелюсь лучше.

CPI TEMP,0x28
BREQ MData_out_ack
CPI TEMP,0x08
BREQ Ok_start                   
CPI TEMP,0x18
BREQ MSlaW_ack
CPI TEMP,0x10
BREQ Duble_start
CPI TEMP,0x00
BREQ Bus_fail
CPI TEMP,0x20
BREQ MSlaW_nack         
CPI TEMP,0x30
BREQ MData_out_nack
CPI TEMP,0x38
BREQ Luser_line
RJMP EXIT_INTERRUPT_TWI

Это убивает
  • avatar
  • ILYAUL
  • 17 декабря 2013, 13:40
0
Я думаю, что если используется математика в проекте. И какой-то регистр получает значение отличное от 0. А при мягком рестарте, с выбором инициализации, может сохранить значение и посчитать не тот результат.
  • avatar
  • ILYAUL
  • 06 декабря 2013, 17:22