ATTiny2313: 1-wire slave (ведомое устройство)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

Делаю устройство, запоминающее ключи от домофонов и потом перебирающее их. С чтением ключа и его запоминанием существенных проблем не возникло, всё работает. А вот с эмуляцией ключа возникли! Домофон совершенно не реагирует. Никак. Вот код эмулятора ключа (avr-gcc):

Код: Выделить всё


SPL	=	0x3d
SPH	=	0x3e
SREG	=	0x3f
PORTD	=	0x12
DDRD	=	0x11
PIND	=	0x10

SLPORT	=	PORTD
SLPIN	=	PIND
SLDDR	=	DDRD

SLBIT	=	0

	.globl	w1sInit
	.globl	w1sTry
	.section .text
;void w1sInit();
w1sInit:
	; Бит на вход с резитором.
	cbi	SLDDR, SLBIT
	sbi	SLPORT, SLBIT
	ret

; r2 - состояние. 0 - сток (игнорировать всё), 1 - начало (чтение команды), 2 - передача кода, 0xff - допуск.
; r3 - осталось битов
; r4 - команда (0) или остаток байт (2)
; Y - текущий байт кода.
auotomatonReset:
	ldi	r18, 1
	mov	r2, r18
	ldi	r18, 8
	mov	r3, r18
	eor	r4, r4
	push	r28
	push	r29
	ldi	r18, 8
1:	lpm	r0, z+
	st	y+, r0
	dec	r18
	brne	1b
	pop	r29
	pop	r28
	ret

auotomatonBit:
	tst	r2	; 1
	breq	9f	; 1
	mov	r18, r2
	cpi	r18, 0xff
	breq	255f
	dec	r2	; 1
	brne	2f	; 1
	inc	r2	; 1
	; чтение команды
	; Ждать 15 мкс
	ldi	r24, 27	; 1
	ldi	r25, 0	; 1
	rcall	cwait	; 112
	;120 считать бит
	in	r0, SLPIN	; 1
	bst	r0, SLBIT	; 1
	lsr	r4	; 1
	bld	r4, 7	; 1
	dec	r3	; 1
	breq	fullcmd	; 1
	; если не все биты считаны
	;480 выйти
	ldi	r24, 88	;1
	ldi	r25, 0	; 1
	rcall	cwait	; ~360
	ret
fullcmd:	; 1
	mov	r18, r4	; 1
	cpi	r18, 0x33	; 1
	brne	9f	; 1
	; если всё биты считаны и если команда == 0x33
	;	перейти в состояние 2
	inc	r2	; 1
	ldi	r18, 8	; 1
	mov	r4, r18	; 1
	mov	r3, r18	; 1
	;480 выйти
	ldi	r24, 85	;1
	ldi	r25, 0	; 1
	rcall	cwait	; ~360
	ret

2:	inc	r2	; 1
	; Взять текущий бит
	ld	r18, Y
	andi	r18, 1
	brne	one
	; Бит на выход и передать ноль.
	sbi	SLDDR, SLBIT
	cbi	SLPORT, SLBIT
one:	; ждать 60 мкс (480)
	ldi	r24, 120
	ldi	r25, 0
	rcall	cwait
	; Бит на вход
	cbi	SLDDR, SLBIT
	sbi	SLPORT, SLBIT
	; Следующий бит
	dec	r3
	brne	set
	; Следующий байт
	ldi	r18, 8
	mov	r3, r18
	adiw	r28, 1
	dec	r4
	; готово
	breq	255f
	ret
set:	ld	r18, Y
	lsr	r18
	st	Y, r18
	ret
	; перейти в состояние 0
9:	eor	r2, r2
	ret
255:	eor	r2, r2
	dec	r2
	ret

; unsigned int w1sTry(unsigned int pgm_addr);
w1sTry:
	push	r2
	push	r3
	push	r4
	push	r28
	push	r29
	; прерываний нет
	in	r28, SPL
	in	r29, SPH
	sbiw	r28, 8
	out	SPL, r28
	out	SPH, r29
	adiw	r28, 1
	mov	r30, r24
	mov	r31, r25

	sbi	SLPORT, SLBIT
	; Если на входе 1, вернуть 1
	sbic	SLPIN, SLBIT
	rjmp	11f
	; Если ноль, ждать единицы.
reset:
	rcall	auotomatonReset
1:	sbis	SLPIN, SLBIT
	rjmp	1b
	; Ждать ~40 мкс (~320)
	ldi	r25, hi8(80)
	ldi	r24, lo8(80)
	rcall	cwait
	; Выдать ноль и ждать 150-200 мкс (~1500)
	sbi	SLDDR, SLBIT
	cbi	SLPORT, SLBIT
	ldi	r25, hi8(325)
	ldi	r24, lo8(325)
	rcall	cwait
	; r23::r20 - счетчик. Время порядка 0,5 с (2^19 * 8 = 2^22 тактов).
3:	ldi	r20, 0
	ldi	r21, 0
	ldi	r22, 8
	ldi	r23, 0
	; Бит на вход.
	cbi	SLDDR, SLBIT
	sbi	SLPORT, SLBIT
	; Ждать нуля
1:	subi	r20, 1	; 1
	sbci	r21, 0	; 1
	sbci	r22, 0	; 1
	sbci	r23, 0	; 1
	brcs	12f	; 1 слишком долго
	sbic	SLPIN, SLBIT ; 1
	rjmp	1b	; 2
	; Ноль.
	rcall	auotomatonBit
	mov	r18, r2
	cpi	r18, 0xff
	; конец связи
	breq	3f
	cpi	r18, 0
	; неправильно что-то
	breq	13f
	rjmp	3b

3:	eor	r24, r24
	eor	r25, r25
	rjmp	100f
11:	eor	r25, r25
	ldi	r24, 1
	rjmp	100f
12:	eor	r25, r25
	ldi	r24, 2
	rjmp	100f
13:	eor	r25, r25
	ldi	r24, 3
	; прерываний нет
100:	in	r28, SPL
	in	r29, SPH
	adiw	r28, 8
	out	SPL, r28
	out	SPH, r29
	pop	r29
	pop	r28
	pop	r3
	pop	r4
	pop	r2
	ret
Пожалуйста, почитайте и помогите разобраться, что не так. Питается всё это дело от двух батареек (три вольта или чуть меньше, они подсажены). На ножку SLBIT подключен внешний резистор 10 кОм к VCC. Функция w1sTry(pgm_addr) проверяет наличие мастера на шине и пытается передать ему 8 байт из памяти программ в ответ на команду 0x33.
Последний раз редактировалось eqltv Чт фев 04, 2010 12:19:05, всего редактировалось 1 раз.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я так понимаю, вы пишите на WinAVR - но к чему тогда ассемблер?! неужели на Си написать все не желаете?
Контактная информация:
Реклама
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

ARV писал(а):я так понимаю, вы пишите на WinAVR - но к чему тогда ассемблер?! неужели на Си написать все не желаете?
Читайте внимательней. Я пишу на avr-gcc. Ассемблер - для точности пауз и для уменьшения объема кода. На нем написан только протокол 1-wire, остальное - на си.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

пока для меня разницы между WinAVR и avr-gcc нет :) или у вас какая-то особо экзотическая сборка AVR-GCC?

лично я реализовал 1-wire-slave полностью на Си с применением функций задержек, обычных для WinAVR - без единой строки ассемблера :) и посему и спросил, в чем тонкость вашего случая
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

ARV писал(а):лично я реализовал 1-wire-slave
И у вас работало? Какое это было устройство? Если не трудно, разместите код.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

во-первых, неужели вы считаете, что я стал бы говорить "я сделал", если бы оно не работало?!

во-вторых, я лично тестировал в протеусе - там работало :) а MOLCHEK на основе моего кода сделал какой-то свой конкретный девайс и по его словам - все работает отлично.

код я планирую выложить у себя на сайте, но пока не решился :)
Контактная информация:
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

Во вложении посмотри...
Писал "на вскидку" для проверки устройства, потом этот шаблон правил под конкретные задачи.

ЗЫ: все на ASM и задержки считались для частоты 8MHz и делителя таймера 64
Правда комментариев не густо.
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

md5sum, спасибо за ответ!
Я написал свой вариант на C++ (из плюсовых возможностей использовались только анонимные неймспейсы для уменьшения объема полученного кода) и решаюсь его разместить. Пользуйтесь!

Код: Выделить всё

#define VALID 0
#define RESET 1
#define TIMEOUT 2
	unsigned char state = RESET;
	unsigned char w1sTRByte(unsigned char b)
	{
		unsigned char i;
		unsigned char r = 0;
		for(i = 8; i > 0; --i)
		{
			r >>= 1;
			if(waitBit(0, 65500))
			{
				state = TIMEOUT;
				return 0;
			}
			if(b & 1)
			{
				usleep(15);
				if(getBit())
					r |= 0x80;
				usleep(45);
			}
			else
			{
				setZero();
				usleep(60);
				setInput();
			}
			b >>= 1;
			if(waitBit(1, 420))
			{
				state = RESET;
				return 0;
			}
		}
		return r;
	}
Эта функция передает или получает байт по шине 1-wire в ведомом режиме. Для получения байта входным параметром нужно передать 0xff.
Функция usleep(unsigned int) делает паузу в микросекундах. Функция waitBit(bool state, unsigned int us) ожидает не более us микросекунд значения на шине.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

eqltv писал(а):Я написал свой вариант на C++ (из плюсовых возможностей использовались только анонимные неймспейсы для уменьшения объема полученного кода) и решаюсь его разместить. Пользуйтесь!
видимо со зрением что-то... не вижу я в вашем коде никаких плюсовых возможностей :( если уж вы писали на WinAVR - отчего не использовали функции _delay_us(), а сочиняли что-то свое? да и особенно пользоваться нечем - это не код, а заготовка по сути...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс янв 31, 2010 17:16:17

Сообщение eqltv »

ARV писал(а):видимо со зрением что-то... не вижу я в вашем коде никаких плюсовых возможностей :( если уж вы писали на WinAVR - отчего не использовали функции _delay_us(), а сочиняли что-то свое? да и особенно пользоваться нечем - это не код, а заготовка по сути...
_delay_us делает задержку подсчетом тактов, а мой usleep - через счетчик. Но можно использовать и _delay_us, если очень хочется.
Плюсовых возможностей не видно, потому что их тут и нет, в нэймспейс обернут почти весь код, а я привел лишь основную функцию. Остальной код нет смысла приводить, потому что он специфичен для конкретной задачи и не будет интересен.
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

ребятки...это всё хорошо...принять и отправить бит это несложно....потом кидаемся байтами, потом скретчпадами:))

а как несчет поиска?
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

clawham писал(а):ребятки...это всё хорошо...принять и отправить бит это несложно....потом кидаемся байтами, потом скретчпадами:))

а как несчет поиска?
А что с поиском?
С точки зрения слейва или мастера интересует?
— Не говорите мне что делать и я не скажу куда Вам идти...
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»