Таймеры в at tiny2313
t
timsa™
17:59, 02.06.2011
Сваял я новое устройство - измеритель каденса (скорости кручения педалей велосипеда). Но никак не могу отладить. Тинька по jtag'у не подключается, а эмуляторы фигню какую-то гонят. Помогите плиз.
На педали закреплен магнит, на раме - датчик Холла (SS495A).
Скорость вращения педалей от 10 до 100 оборотов в минуту, показывается зажиганием линеечки светодиодов.
По изменению уровня на INT0 (PD2) увеличиваю счетчик.
Параллельно пытаюсь запрограммировать таймер на срабатывание каждые 6 секунд. В обработке определяю сколько натикало на INT0, обнуляю и показываю светодиодами.
Но толи INT0 не появляется вообще, толи таймер вовсе не каждые 6 секунд срабатывает...
На педали закреплен магнит, на раме - датчик Холла (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 |
Если я не ошибаюсь, то установив WGM12 вы сконфигурировали отсечку по OCR1A, а значение загружаете в OCR1B
А watchdog отключен? а то недавно на pic10f200 напоролся.
Не проще ли сбрасывать TIMER1, а потом ловить переполнение TIMER0 в режиме счетчика и смотреть, сколько на TIMER1 набежало?
Непонятно нафига связываться с OCR1Bx, можно же просто TCNT1x выставить в 0x10000-46875 и ловить OVR..
И в любом случае можно просто проверить, срабатывает таймер или нет и за сколько - каждое срабатывание таймера переключать какую-нибудь свободную ногу. чтоб светодиот шесть секунд горел - шесть нет. Та же фигня с INT0 - моргайте чем-нибудь
[Сообщение изменено пользователем 02.06.2011 19:20]
А watchdog отключен? а то недавно на pic10f200 напоролся.
Не проще ли сбрасывать TIMER1, а потом ловить переполнение TIMER0 в режиме счетчика и смотреть, сколько на TIMER1 набежало?
Непонятно нафига связываться с OCR1Bx, можно же просто TCNT1x выставить в 0x10000-46875 и ловить OVR..
И в любом случае можно просто проверить, срабатывает таймер или нет и за сколько - каждое срабатывание таймера переключать какую-нибудь свободную ногу. чтоб светодиот шесть секунд горел - шесть нет. Та же фигня с INT0 - моргайте чем-нибудь
[Сообщение изменено пользователем 02.06.2011 19:20]
t
timsa™
20:17, 02.06.2011
WGM12 вы сконфигурировали отсечку по OCR1A, а значение загружаете в OCR1B
а вот с этим я как раз и запутался. таймер 1A,1B,1C это три разных таймера1 или это один и тот же таймер? Я не понимаю как можно устанавливая OCR1A поймать прерывание на OVF1B.
Не проще ли сбрасывать TIMER1, а потом ловить переполнение TIMER0 в режиме счетчика и смотреть, сколько на TIMER1 набежало?
для меня это выглядит гораздо сложнее чем просто запрограммировать один таймер на тиканье с заданной частотой.
t
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 |
М
Мoзгoпрaв и мoзгoвeд©
21:54, 02.06.2011
таймер 1A,1B,1C
Разные таймера...
Смотрю пдфку на тини2313 и ищу там таймер А, Б и Ц, нету
для меня это выглядит гораздо сложнее чем просто запрограммировать
один таймер на тиканье с заданной частотой.
Дык книжку почитайте или пдфку
Там много интересного.
Непонятно нафига связываться с OCR1Bx, можно же просто TCNT1x выставить в 0x10000-46875 и ловить OVR..
Надо два таймера, один считает время, другой обороты
Делов то на 6 часов работы с отладкой и чаепитием
таймер 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.
М
Мoзгoпрaв и мoзгoвeд©
22:12, 02.06.2011
я предлагал, но потому подумав решил, что фигня получится - оборотов-то от 10 в минуту. Хотя по хорошему один фиг придется больше магнитов везде навтыкать.
не прийдется, смотря по какому интервалу считать ;-)
Если в минутах то да магнитов кучку надо для точности, в секундах - нет ;-)
х
0хCB
22:17, 02.06.2011
interrupt то enabled?
t
timsa™
22:23, 02.06.2011
Делов то на 6 часов работы с отладкой и чаепитием
вообще-то на час. из которого 15 минут плата травилась и еще 15 минут паял. и похоже я уже сделал :-) в отладчике таймер четко отсчитал 6 секунд. я руками подергал ножку инт0 и он четко зажег нужное количество лампочек.
к сожалению мануал не очень понятный (хотя с английским у меня ок), а книжек нету. в инете как ни странно тоже сложно найти хорошие примеры. поиском находится много, но вот проблемы там совсем другие разбираются. поэтому и приходится здесь спрашивать.
таймер один - это TIMER1. Он постоянно считает. OCR1x - это отсечки, когда значение TIMER1
большое кстати спасибо за то, что ткнули куда копать. исправил и всё заработало (в отладчике). завтра проверю в железе.
фигня получится - оборотов-то от 10 в минуту
именно! я уж было начал математику городить, а потом сделал как сделал.
t
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
|
надо еще от использования оперативки отказаться
М
Мoзгoпрaв и мoзгoвeд©
23:22, 02.06.2011
вот весь код
Жуть код... :-)
Неиспользуемые прерывания можно не описывать (org)
У мну есть книжки додековские про тини и меги если надо могу недорого отдать, мне они уже не нужны :-)
А тебе в самый раз, на русском и многое понятно становится.
23:36, 02.06.2011
Если задача тупо померять частоту и вывести на линейный индикатор - нафег ваще прерывания? На этих то скоростях. Давай я тебе на пике 16505 прогу накидаю в 15 минут. Без прерываний.
23:53, 02.06.2011
Кароч, не знаю чо там фтиньках, мне оне параллельны, на пике это делаецо так.
1 Програмируецо таймер на самую унылую скорость
2 Скорость всё равно охрененная
3 Програмируецо цикл штоп 6 секунд отщетать за 200 переполнений таймера примерно
4 Внутри этого цикла программно, безо всяких прерываний, щетаецо холл
5 Холл выплёвываем в линейку
6 Начинаем сначала
1 Програмируецо таймер на самую унылую скорость
2 Скорость всё равно охрененная
3 Програмируецо цикл штоп 6 секунд отщетать за 200 переполнений таймера примерно
4 Внутри этого цикла программно, безо всяких прерываний, щетаецо холл
5 Холл выплёвываем в линейку
6 Начинаем сначала
00:15, 03.06.2011
Типа так. Не хватает только начальных настроек конфигурации и преобразования х в набор битов для светодиодов. Остальное рабочее точно. Ни одного прерывания.
е1 сцуко всё форматирование текста удаляет. GPIO,0 - это вход с холла есличовдрук
[Сообщение изменено пользователем 03.06.2011 00:19]
Исходник: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]
Типа так.
ну если уж так подходить, то я бы вобще просто сделал: по Wake-Up On Pin Change к регистру, назовем его x, плюсовал число k. По сбросу от WDT вычитал бы число m. Значение x/n выводил на светодиоды. Числа k, m и n подбираются опытно-рассчетным путем.
а, да, и вобще микроконтроллеры тут не нужны, можно прикрутить генератор и столбик светодиодный от эквалайзера :-)
[Сообщение изменено пользователем 03.06.2011 00:29]
00:34, 03.06.2011
по Wake-Up On Pin Change
К чему эти изыски? Ещё потом после сброса разбирацо кто инициировал.........
00:44, 03.06.2011
батарейка спасибо скажет
Со светодиодами то?
Не, ну я понимаю тут колхозил редкопользуемую автономную хрень, извращалсо с этими вакеупами.................. Оно сцуко ещё шары спросоня 18мсек продирает, а там уже кодовая посылка прёт во всю, хоть линию задержки ставь
х
0хCB
00:49, 03.06.2011
6 секунд, не слишком ли редко показания обновлятся будут?
лучше период мерять, а по нему обороты считать.
лучше период мерять, а по нему обороты считать.
t
timsa™
00:51, 03.06.2011
эй! у меня цель время с удовольствием провести, а не разработать самый точный в мире ключ для откручивания винта на 16 с правой дюймовой резьбой!
за помощь по делу спасибо, а комментарии типа: "зачем тут тинька, возьми три К155ЛА3... и четыре МП40" засуньте... по доброму :-)
за помощь по делу спасибо, а комментарии типа: "зачем тут тинька, возьми три К155ЛА3... и четыре МП40" засуньте... по доброму :-)
00:51, 03.06.2011
Да куда велоупячкам чаще то? Тем более каденс.
Предлагаю фкалхозеть род или сельсин
Предлагаю фкалхозеть род или сельсин
Авторизуйтесь, чтобы принять участие в дискуссии.