Таймеры в at tiny2313

timsa™
17:59, 02.06.2011
Сваял я новое устройство - измеритель каденса (скорости кручения педалей велосипеда). Но никак не могу отладить. Тинька по jtag'у не подключается, а эмуляторы фигню какую-то гонят. Помогите плиз.

На педали закреплен магнит, на раме - датчик Холла (SS495A).
Скорость вращения педалей от 10 до 100 оборотов в минуту, показывается зажиганием линеечки светодиодов.

По изменению уровня на INT0 (PD2) увеличиваю счетчик.
Параллельно пытаюсь запрограммировать таймер на срабатывание каждые 6 секунд. В обработке определяю сколько натикало на INT0, обнуляю и показываю светодиодами.

Но толи INT0 не появляется вообще, толи таймер вовсе не каждые 6 секунд срабатывает...


Исходник:
		; прерывания по изменению уровня на ножке INT0
		OUTI 	GIMSK,1<<INT0
		OUTI 	MCUCR,1<<ISC01|1<<ISC00

		; таймер с частотой 1 тик в 6 секунд (8МГц, прескалер 1024, досчитываем до 46875 = 0xB71B)
		OUTI	TIMSK,1<<OCIE1B
		OUTI 	TCCR1B,1<<CS12|0<<CS11|1<<CS10|1<<WGM12
		LDI		R16, 0xB7
		LDI		R17, 0x1B
		OUT	OCR1BH, R16
		OUT	OCR1BL, R17
0
19:18, 02.06.2011
Если я не ошибаюсь, то установив WGM12 вы сконфигурировали отсечку по OCR1A, а значение загружаете в OCR1B

А watchdog отключен? а то недавно на pic10f200 напоролся.

Не проще ли сбрасывать TIMER1, а потом ловить переполнение TIMER0 в режиме счетчика и смотреть, сколько на TIMER1 набежало?

Непонятно нафига связываться с OCR1Bx, можно же просто TCNT1x выставить в 0x10000-46875 и ловить OVR..

И в любом случае можно просто проверить, срабатывает таймер или нет и за сколько - каждое срабатывание таймера переключать какую-нибудь свободную ногу. чтоб светодиот шесть секунд горел - шесть нет. Та же фигня с INT0 - моргайте чем-нибудь

[Сообщение изменено пользователем 02.06.2011 19:20]
1 / 0
timsa™
20:17, 02.06.2011
От пользователя ITihonov
WGM12 вы сконфигурировали отсечку по OCR1A, а значение загружаете в OCR1B

а вот с этим я как раз и запутался. таймер 1A,1B,1C это три разных таймера1 или это один и тот же таймер? Я не понимаю как можно устанавливая OCR1A поймать прерывание на OVF1B.

От пользователя ITihonov
Не проще ли сбрасывать TIMER1, а потом ловить переполнение TIMER0 в режиме счетчика и смотреть, сколько на TIMER1 набежало?


для меня это выглядит гораздо сложнее чем просто запрограммировать один таймер на тиканье с заданной частотой.
0
timsa™
21:51, 02.06.2011
Поставил CodeVisionAVR, там есть удобный (хоть и тоже мутный) визард.
На нем наваял вот такое:
Исходник:
		OUTI 	GIMSK,1<<INT0
		OUTI 	MCUCR,1<<ISC01|1<<ISC00
		OUTI	TIMSK,1<<OCIE1A
		OUTI 	TCCR1B,1<<CS12|0<<CS11|1<<CS10|1<<WGM12
		LDI		R16, 0xB7
		LDI		R17, 0x1B
		OUT	OCR1AH, R16
		OUT	OCR1AL, R17
0
Мoзгoпрaв и мoзгoвeд©
21:54, 02.06.2011
От пользователя timsa™
таймер 1A,1B,1C

Разные таймера...
Смотрю пдфку на тини2313 и ищу там таймер А, Б и Ц, нету :-D

От пользователя timsa™
для меня это выглядит гораздо сложнее чем просто запрограммировать один таймер на тиканье с заданной частотой.

Дык книжку почитайте или пдфку ;-)
Там много интересного. ;-)
От пользователя ITihonov
Непонятно нафига связываться с OCR1Bx, можно же просто TCNT1x выставить в 0x10000-46875 и ловить OVR..


Надо два таймера, один считает время, другой обороты ;-)

Делов то на 6 часов работы с отладкой и чаепитием :cool:
0
21:58, 02.06.2011
От пользователя timsa™
таймер 1A,1B,1C это три разных таймера1 или это один и тот же таймер? Я не понимаю как можно устанавливая OCR1A поймать прерывание на OVF1B.


таймер один - это TIMER1. Он постоянно считает. OCR1x - это отсечки, когда значение TIMER1 (прочитать можно через TCNT1x) становится равно им, срабатывает прерывание. Никаких OVF1B нету, есть TIMER1 COMPA и TIMER1 COMPB (Timer/Counter1 Compare Match A или B) - "Compare Match" - это "сравнили и совпало".

НО. Когда ты ставишь WGM12, а остальные WGM в нулях, ты выбираешь режим CTC (Clear Timer on Compare), когда максимальным значением счетчика является OCR1A. Счетчик его достигнет и сбросится в ноль. Вызовется TIMER1 COMPA.

Т.е. в маске прерываний тебе надо OCIE1A включить вместо OCIE1B (режим со сбросом счетчика только для A есть). И писать свое волшебное значение в OCR1AL/H.
1 / 0
22:00, 02.06.2011
От пользователя Мозгоправ и мозговед
Надо два таймера, один считает время, другой обороты ;-)


я предлагал, но потому подумав решил, что фигня получится - оборотов-то от 10 в минуту. Хотя по хорошему один фиг придется больше магнитов везде навтыкать.
0
Мoзгoпрaв и мoзгoвeд©
22:12, 02.06.2011
От пользователя ITihonov
я предлагал, но потому подумав решил, что фигня получится - оборотов-то от 10 в минуту. Хотя по хорошему один фиг придется больше магнитов везде навтыкать.

не прийдется, смотря по какому интервалу считать ;-)
Если в минутах то да магнитов кучку надо для точности, в секундах - нет ;-)
0
0хCB
22:17, 02.06.2011
interrupt то enabled?
0
timsa™
22:23, 02.06.2011
От пользователя Мозгоправ и мозговед
Делов то на 6 часов работы с отладкой и чаепитием

вообще-то на час. из которого 15 минут плата травилась и еще 15 минут паял. и похоже я уже сделал :-) в отладчике таймер четко отсчитал 6 секунд. я руками подергал ножку инт0 и он четко зажег нужное количество лампочек.

к сожалению мануал не очень понятный (хотя с английским у меня ок), а книжек нету. в инете как ни странно тоже сложно найти хорошие примеры. поиском находится много, но вот проблемы там совсем другие разбираются. поэтому и приходится здесь спрашивать.

От пользователя ITihonov
таймер один - это TIMER1. Он постоянно считает. OCR1x - это отсечки, когда значение TIMER1


большое кстати спасибо за то, что ткнули куда копать. исправил и всё заработало (в отладчике). завтра проверю в железе.

От пользователя ITihonov
фигня получится - оборотов-то от 10 в минуту


именно! я уж было начал математику городить, а потом сделал как сделал.
0
timsa™
22:25, 02.06.2011
вот весь код

Исходник:
		.include "tn2313def.inc"	; Используем ATTiny2313-20SU
		.include "macro.inc"		; Макросы

; Оперативка
		.DSEG					; Сегмент ОЗУ
rp6s:
		.byte	1

; Код
		.CSEG					; Кодовый сегмент
		.ORG	$000
		RJMP	Reset			; Инициализация всего и вся
		.ORG	INT0addr		; External Interrupt Request 0
		RJMP	Cycle
		.ORG	INT1addr		; External Interrupt Request 1
		RETI
		.ORG	ICP1addr		; Timer/Counter1 Capture Event
		RETI
		.ORG	OC1Aaddr		; Timer/Counter1 Compare Match A
		RJMP	Timer
		.ORG	OVF1addr		; Timer/Counter1 Overflow
		RETI
		.ORG	OVF0addr		; Timer/Counter0 Overflow
		RETI
		.ORG	URXCaddr		; USART, Rx Complete
		RETI
		.ORG	UDREaddr		; USART Data Register Empty
		RETI
		.ORG	UTXCaddr		; USART, Tx Complete
		RETI
		.ORG	ACIaddr			; Analog Comparator
		RETI
		.ORG	PCIaddr			; Pin Change Interrupt Request
		RETI
		.ORG	OC1Baddr		; 
		RETI
		.ORG	OC0Aaddr		; 
		RETI
		.ORG	OC0Baddr		; 
		RETI
		.ORG	USI_STARTaddr	; USI Start Condition
		RETI
		.ORG	USI_OVFaddr		; USI Overflow
		RETI
		.ORG	ERDYaddr		; 
		RETI
		.ORG	WDTaddr			; Watchdog Timer Overflow
		RETI
		.ORG	INT_VECTORS_SIZE

; Обработчики прерываний

Timer:
		CLI
		PUSHF
		PUSH	R16
		PUSH	R17
		LDS		R16, rp6s
		RCALL	LightOn
		CLR		R16
		STS		rp6s, R16
		POP		R17
		POP		R16
		POPF
		SEI
		RETI

Cycle:
		CLI
		PUSHF
		PUSH	R16
		LDS		R16, rp6s
		INC		R16
		STS		rp6s, R16
		POP		R16
		POPF
		SEI
		RETI

; Объявим переменные
.equ	XTAL	= 8000000 

Reset:
; Чистим оперативку
		LDI		ZL, Low(SRAM_START)
		LDI		ZH, High(SRAM_START)
		CLR		R16
		LDI		R17, SRAM_SIZE
clr_sram:
		ST		Z+, R16
		DEC		R17
		BRNE	clr_sram

; Инициализация стека
		LDI		R16,Low(RAMEND)
		OUT		SPL,R16

; Чистим регистры
		LDI		ZL, 30				; Адрес самого старшего регистра	
		CLR		ZH					; А тут у нас будет ноль
		DEC		ZL					; Уменьшая адрес
		ST		Z, ZH				; Записываем в регистр 0
		BRNE	PC-2				; Пока не перебрали все не успокоились

; Инициализация железа
		; вход с датчика
		CLRB	DDRD,2,R16		; DDRD.2 = 0 (ножка работает на вход)
		; выходы на лампочки
		SETB	DDRB,0,R16		; DDRB.0 = 1 (ножка работает на выход)
		SETB	DDRB,1,R16		; DDRB.1 = 1 (ножка работает на выход)
		SETB	DDRB,2,R16		; DDRB.2 = 1 (ножка работает на выход)
		SETB	DDRB,3,R16		; DDRB.3 = 1 (ножка работает на выход)
		SETB	DDRB,4,R16		; DDRB.4 = 1 (ножка работает на выход)
		SETB	DDRB,5,R16		; DDRB.5 = 1 (ножка работает на выход)
		SETB	DDRB,6,R16		; DDRB.6 = 1 (ножка работает на выход)
		SETB	DDRB,7,R16		; DDRB.7 = 1 (ножка работает на выход)
		SETB	DDRD,0,R16		; DDRD.0 = 1 (ножка работает на выход)
		SETB	DDRD,1,R16		; DDRD.1 = 1 (ножка работает на выход)

		; прерывания по изменению уровня на ножке INT0
		OUTI 	GIMSK,1<<INT0
		OUTI 	MCUCR,1<<ISC01|1<<ISC00

		; таймер с частотой 1 тик в 6 секунд (8МГц, прескалер 1024, досчитываем до 46875 = 0xB71B)
		OUTI	TIMSK,1<<OCIE1A
		OUTI 	TCCR1B,1<<CS12|0<<CS11|1<<CS10|1<<WGM12
		LDI		R16, 0xB7
		LDI		R17, 0x1B
		OUT		OCR1AH, R16
		OUT		OCR1AL, R17

; Включаем прерывания
;		SEI

; Программа
Main:
		LDI		R16, 10
		RCALL	LightOn		; зажгем 10

		LDI		R16,0x00
		LDI		R17,0x00
		LDI		R18,0x03
		RCALL	Delay		; тупим 196608 циклов

		RCALL	LightOff	; погасим всё

		LDI		R16,0x00
		LDI		R17,0x00
		LDI		R18,0x03
		RCALL	Delay		; тупим 196608 циклов

		LDI		R16, 5
		RCALL	LightOn		; зажгем 5

		LDI		R16,0x00
		LDI		R17,0x00
		LDI		R18,0x03
		RCALL	Delay		; тупим 196608 циклов

		RCALL	LightOff	; погасим всё

		SEI

Loop:
		NOP
		NOP
		NOP
		NOP
		NOP
		RJMP	Loop

; Тупилка
Delay:
_loop1:	SUBI  R16,1
		SBCI  R17,0
		SBCI  R18,0
		BRCC  _loop1
		RET

; Включить в соответствии с R16 (0-ничего не горит, 10-горят все)
LightOn:
		RCALL	LightOff	; погасим всё
		TST		R16
		BREQ	_exit
		CLRB	PORTB,7,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,6,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,5,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,4,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,3,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,2,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,1,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTB,0,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTD,0,R17
		DEC		R16
		BREQ	_exit
		CLRB	PORTD,1,R17
_exit:
    	RET

; Выключить всё
LightOff:
		SETB	PORTB,7,R17
		SETB	PORTB,6,R17
		SETB	PORTB,5,R17
		SETB	PORTB,4,R17
		SETB	PORTB,3,R17
		SETB	PORTB,2,R17
		SETB	PORTB,1,R17
		SETB	PORTB,0,R17
		SETB	PORTD,0,R17
		SETB	PORTD,1,R17
    	RET

; Епром
		.ESEG				; Сегмент EEPROM


надо еще от использования оперативки отказаться
0
22:30, 02.06.2011
От пользователя timsa™
датчик Холла (SS495A).

Он ж аналоговый 8(
0
Мoзгoпрaв и мoзгoвeд©
23:22, 02.06.2011
От пользователя timsa™
вот весь код

Жуть код... :-)

Неиспользуемые прерывания можно не описывать (org)

У мну есть книжки додековские про тини и меги если надо могу недорого отдать, мне они уже не нужны :-)
А тебе в самый раз, на русском и многое понятно становится.
0
23:34, 02.06.2011
От пользователя Мозгоправ и мозговед
Жуть код...

Таку фигню на асме в 30 строк писать :-D
1 / 0
23:36, 02.06.2011
Если задача тупо померять частоту и вывести на линейный индикатор - нафег ваще прерывания? На этих то скоростях. Давай я тебе на пике 16505 прогу накидаю в 15 минут. Без прерываний.
0
23:53, 02.06.2011
Кароч, не знаю чо там фтиньках, мне оне параллельны, на пике это делаецо так.
1 Програмируецо таймер на самую унылую скорость
2 Скорость всё равно охрененная
3 Програмируецо цикл штоп 6 секунд отщетать за 200 переполнений таймера примерно
4 Внутри этого цикла программно, безо всяких прерываний, щетаецо холл
5 Холл выплёвываем в линейку
6 Начинаем сначала
0
00:15, 03.06.2011
Типа так. Не хватает только начальных настроек конфигурации и преобразования х в набор битов для светодиодов. Остальное рабочее точно. Ни одного прерывания.
Исходник:
main	clrf	x
	movlw	180
	movwf	y

m1	clrf	TMR0

m2	btfss	GPIO,0
	goto	m3
	btfss	TMR0,7
	goto	m2
	decfsz	y,f
	goto	m1
	goto	indik


m3	incf	y,f
	goto	m4

m5	clrf	TMR0
	
m4	btfsc	GPIO,0
	goto	m2
	btfss	TMR0,7
	goto	m4
	decfsz	y,f
	goto	m5

indik	/ну тут вывод в порт значения х/

	goto	main


е1 сцуко всё форматирование текста удаляет. GPIO,0 - это вход с холла есличовдрук

[Сообщение изменено пользователем 03.06.2011 00:19]
1 / 0
00:27, 03.06.2011
От пользователя ddd[гость]
Типа так.


ну если уж так подходить, то я бы вобще просто сделал: по Wake-Up On Pin Change к регистру, назовем его x, плюсовал число k. По сбросу от WDT вычитал бы число m. Значение x/n выводил на светодиоды. Числа k, m и n подбираются опытно-рассчетным путем.

а, да, и вобще микроконтроллеры тут не нужны, можно прикрутить генератор и столбик светодиодный от эквалайзера :-)

[Сообщение изменено пользователем 03.06.2011 00:29]
0
00:34, 03.06.2011
От пользователя ITihonov
по Wake-Up On Pin Change

К чему эти изыски? Ещё потом после сброса разбирацо кто инициировал......... :beach:
0
00:40, 03.06.2011
От пользователя ddd[гость]
К чему эти изыски? Ещё потом после сброса разбирацо кто инициировал......... :beach:


батарейка спасибо скажет :-)
0
00:44, 03.06.2011
От пользователя ITihonov
батарейка спасибо скажет

Со светодиодами то? :-D
Не, ну я понимаю тут колхозил редкопользуемую автономную хрень, извращалсо с этими вакеупами.................. Оно сцуко ещё шары спросоня 18мсек продирает, а там уже кодовая посылка прёт во всю, хоть линию задержки ставь :vis: :-D
0
0хCB
00:49, 03.06.2011
6 секунд, не слишком ли редко показания обновлятся будут?
лучше период мерять, а по нему обороты считать.
0
timsa™
00:51, 03.06.2011
эй! у меня цель время с удовольствием провести, а не разработать самый точный в мире ключ для откручивания винта на 16 с правой дюймовой резьбой!

за помощь по делу спасибо, а комментарии типа: "зачем тут тинька, возьми три К155ЛА3... и четыре МП40" засуньте... ;-) по доброму :-)
0
00:51, 03.06.2011
Да куда велоупячкам чаще то? Тем более каденс.

Предлагаю фкалхозеть род или сельсин :ultra:
0
00:52, 03.06.2011
От пользователя timsa™
у меня цель время с удовольствием провести

екатеринбург.ню фпомосчь :super:
0
Авторизуйтесь, чтобы принять участие в дискуссии.