BASCOM AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Сообщения: 132
Зарегистрирован: Пт окт 19, 2012 05:54:55

Сообщение koms48 »

Указывать, иначе с 0 начнет.
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

Угу, в прерывании по переполнению этого таймера начальное значение счета задавать можно, например. Либо настроить таймер в режиме CTC (Clear To Compare - Сброс При Совпадении). Тогда достаточно будет один раз в регистр сравнения число загрузить, и таймер будет считать от 0 и до этого значения. :tea:
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Реклама
Встал на лапы
Сообщения: 127
Зарегистрирован: Вс мар 27, 2011 07:48:48
Откуда: г. Екатеринбург

Сообщение rojnov »

Спасибо, я так и думал, что тут не все так просто. А может кто-нибудь поделится куском кода для примера

использования Timer1 в режиме CTC, а то в сети все попадаются обрывки информации с разными вариантами написания,

замучился уже искать. Можно ткнуть ссылкой на конкретное место. Буду очень благодарен.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

Все просто, на самом деле. В конфигурации таймера указываете

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

Clear Timer = 1
А в регистр сравнения заносите нужное значение. Например (от таймера зависит):

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

Compare1a = 12345
И всех делов, таймер считает от 0 до 12345, а при совпадении вызывается соответствующее прерывание.

Пример:

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

Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1    ' 1/8000000 = 0,125мкс * 256 * 31250 = 1 cек
Compare1a = &H7A12                                             ' в регистре совпадения число, для отсчета 1 секунды
On Oc1a 1_sec                                                       ' вектор прерывания совпадения Т1

..

1_sec:                                                                   ' обработка прерывания отсчета 1 секунды
..
Return
Только в даташите смотрите, какие таймеры поддерживают этот режим.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 127
Зарегистрирован: Вс мар 27, 2011 07:48:48
Откуда: г. Екатеринбург

Сообщение rojnov »

Спасибо. Если я правильно понял, то выходит, что отсчитать нужный интервал времени можно двумя способами:
1. Задать Timer1 начальное значение, и он будет считать от этого значения и до 65535. Но в этом случае нужно

указывать начальное значение при каждом обращении к таймеру.
2. При конфигурировании Timer1 заносим конечное значение в регистр сравнения, и таймер каждый раз считает от 0

до этого значения. Второй способ мне кажется более удобным.
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

Совершенно верно. Удобство зависит от того, как используется таймер. Второй вариант больше подходит под задачу "запустили и забыли". Отсчет времени тот же, например. Первый же вариант тоже жизнеспособен, когда нужно изредка запускать отсчет какой-либо выдержки. Тут можно даже написать функцию, в которую передается значение для начального отсчета, а в прерывании по переполнению выставляется флаг окончания отсчета. Все это удобно и гибко.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Реклама
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

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

Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1    ' 1/8000000 = 0,125мкс * 256 * 31250 = 1 cек
Compare1a = &H7A12                                             ' в регистре совпадения число, для отсчета 1 секунды
On Oc1a 1_sec                                                       ' вектор прерывания совпадения Т1

..

1_sec:                                                                   ' обработка прерывания отсчета 1 секунды
..
Return
Все таки, учитывая что прерывание по сравнению вызывается в следующем, после сравнения, такте, логичнее записать

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

Fcpu=8000000
Config Timer1 = Timer , Prescale = 256 , Clear Timer = 1    ' 1/8000000 = 0,125мкс * 256 * 31250 = 1 cек
Compare1a = Fcpu/256-1        ; в регистре совпадения число, для отсчета 1 секунды
;Compare1a = &H7A12                                             ' в регистре совпадения число, для отсчета 1 секунды
On Oc1a 1_sec                                                       ' вектор прерывания совпадения Т1

..

1_sec:                                                                   ' обработка прерывания отсчета 1 секунды
..
Return
Встал на лапы
Сообщения: 127
Зарегистрирован: Вс мар 27, 2011 07:48:48
Откуда: г. Екатеринбург

Сообщение rojnov »

Благодарю за информацию. Вечером буду пробовать.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

akl, так и есть, один такт отнимать нужно. :) Код старый, первые шаги еще. Для примера приведен был. :tea:
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Встал на лапы
Сообщения: 127
Зарегистрирован: Вс мар 27, 2011 07:48:48
Откуда: г. Екатеринбург

Сообщение rojnov »

Приветствую неспящих!
Наконец у меня дошли руки, чтобы живьём проверить, как обращаться с Timer1. Взяв за основу образец, который мне

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

которая, по идее, должна отсчитывать секунды и при этом моргать светодиодом каждую секунду. Собрал все это на

макетке, о оно не хочет работать. На индикаторе - нули, на кнопки не реагирует. Бейсик не ругается. Не могу

понять, чего ему не хватает. Может, кто подскажет, что я не так делаю. Хочется подружиться с Timer1.

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

$regfile = "2313def.dat"
$crystal = 4000000
$hwstack = 32
$swstack = 8
$framesize = 16

Dim Seco As Byte
Dim Number(2) As Byte
Dim Count As Byte
Dim A As Byte
Dim F As Bit


Config Portb = Output
Config Portd.3 = Output                                     '1 разряд
Config Portd.4 = Output                                     '2 разряд
Config Portd.5 = Output                                     'светодиод
Config Pind.1 = Input

Config Debounce = 50
Config Timer0 = Timer , Prescale = 256
On Ovf0 Indic
Config Timer1 = Timer , Prescale = 64 , Clear Timer = 1
'Compare1a = 62500
Ocr1a = 62500
On Oc1a Timecount                                           ' рассчет времени
Config Int0 = Falling
On Int0 Breaktime

Dig1 Alias Portd.3
Dig2 Alias Portd.4
Diod Alias Portd.5
Pusk Alias Pind.1                                           'кнопка пуск

Enable Interrupts
Enable Int0
Enable Timer0
Enable Timer1
Start Timer0

Seco = 0 : F = 0

Do
If Pusk = 0 Then                                            'нажата кнопка Пуск
   Start Timer1
End If

If F = 1 Then                                               ' секунда отсчитана
Set Diod                                                    'моргание светодиодом
Waitms 200
Reset Diod
F = 0                                                       'сброс флага
End If
Loop

Breaktime:                                                  'нажата кнопка Стоп
Stop Timer1
Timer1 = 0 : Seco = 0                                       ' остановка таймера, обнуление
Return

Indic:                                                      'индикация
A = Seco
Number(1) = A / 10
Number(2) = A Mod 10
Reset Dig1 : Reset Dig2
Incr Count : If Count > 2 Then Count = 1
Portb = Lookup(number(count) , Digits)
Select Case Count
Case 1 : Set Dig1
Case 2 : Set Dig2
End Select
Return

Timecount:                                                  'рассчет времени
Incr Seco : If Seco > 59 Then Seco = 0
F = 1                                                       'установка флага
Return

End

Digits:
Data &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110
Data &B01101101 , &B01111101 , &B00000111 , &B01111111 , &B01101111
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

Здравствуйте.

Enable Timer1 - это разрешение прерывания по переполнению. У Вас же прерывание по совпадению. А следовательно, Enable Oc1a.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Встал на лапы
Сообщения: 127
Зарегистрирован: Вс мар 27, 2011 07:48:48
Откуда: г. Екатеринбург

Сообщение rojnov »

Привет! Исправил код по вашему совету. Все работает супер. Спасибо за помощь. Заодно узнал, что Timer1 начинает работать после команды Enable Timer1, поэтому приходится его сначала тушить, а в нужном месте запускать командой Start Timer1.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

Вообще таймер начинает тикать как только будет сконфигурированы биты прескаллера. Вот как только задали Prescale, таймер пошагал считать. Команда Stop Timer останавливает таймер именно обнуляя прескалллер, а запускает восстанавливая его значение.

Команда же Enable / Disable Timer разрешает / запрещает именно прерывание этого таймера в регистре TIMSK. Что все это значит?

После того как таймер был сконфигурирован, он начинает считать. Если прерывание было запрещено, то он просто крутит счетный регистр по кругу, без всяких внешних реакций. С одной-то стороны и ладно. Если речь идет о таймере индикации, например. А с другой это чревато тем, что мы не знаем что там в счетном регистре в момент разрешения прерывания. И если важно именно прошедшее время, то нужно однозначно таймер перезапускать, обнуляя счетный регистр. Такие дела. :tea:
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Если BASCOM при старте чистит регистр TIFR, то ладно. Но, я бы почистил флаги, записью 1, устраняя, таким образом, всю предисторию.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

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

Этот флаг сбрасывается при переходе по соответствующему вектору прерывания, либо как заметил akl, самостоятельной записью 1 в соответствующий бит регистра флагов (например, у таймеров TIFR - Timer/Counter Interrupt Flag Register).
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Встал на лапы
Сообщения: 132
Зарегистрирован: Пт окт 19, 2012 05:54:55

Сообщение koms48 »

Спасибо edm2007. Всё получилось.

Enable Oc1a.
On Oc1a

Откуда? Вхелпе их нет. Поясните где их раскопать, чтобы дале не домогаться?
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2255
Зарегистрирован: Вт апр 21, 2009 22:24:10
Откуда: Иркутск

Сообщение edm2007 »

Можно открыть файл .DAT соответствующего контроллера, в папке с установленной программой. Обычным блокнотом. Там много всего интересного, на самом деле. Например, прерывания Attiny2313:

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

[INTS]
INT0=$001	;External Interrupt0 Vector Address
INT1=$002	;External Interrupt1 Vector Address
ICP1=$003	;Input Capture1 Interrupt Vector Address
OC1A=$004	;Output Compare1 Interrupt Vector Address
OVF1=$005	;Overflow1 Interrupt Vector Address
OVF0=$006	;Overflow0 Interrupt Vector Address
URXC=$007	;UART Receive Complete Interrupt Vector Address
UDRE=$008	;UART Data Register Empty Interrupt Vector Address
UTXC=$009	;UART Transmit Complete Interrupt Vector Address
ACI=$00a	;Analog Comparator Interrupt Vector Address
PCINT=$00B
OC1B=$00C
OC0A=$00D
OC0B=$00E      ; timer 0 compare match B
UCI_START=$00F  ; USI start
UCI_OVFLW=$010  ; USI overflow
EERDY=$011      ; eeprom ready
WDT=$012        ; watch dog timer overflow
Далее в именах и видно, что Timer0 это Ovf0 (переполнение), например:

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

INTname6=OVF0@TIMER0,$006,TIMSK.TOIE0,TIFR.TOV0
А вместо Enable Oc1a можно написать Enable Compare1a, это уже будет в стиле баскома:

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

INTname4=OC1A@COMPARE1A,$004,TIMSK.OCIE1A,TIFR.OCF1A
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Контактная информация:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 151
Зарегистрирован: Сб ноя 19, 2011 20:13:47
Откуда: Тамбов

Сообщение xorkrus »

Здравия.
Тут уже мелькало, но предложенные варианты не прокатили.
Проблема: Unknown interrupt [PCINT3]
Код:

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

$regfile = "attiny13.dat"
$crystal = 4800000
$hwstack = 8
$swstack = 16
$framesize = 16

Config POTRB.3 = Input

On PCINT3 Button:
Gimsk = &B00100000
'5bit - pcint enable. Stranica 46, punkt 9.3.2
Pcmsk = &B00001000
'3bit - pcint3 enable. Stranica 47, punkt 9.3.4

Do
Loop

Button:
   Wait 1
Return
Даташит на тиньку13 на всякий случай прилагаю.
Что делать? Гугел не помогает :(
Демократии нет и не будет!
Государство - это я!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4741
Зарегистрирован: Вс янв 24, 2010 13:14:02
Откуда: Омск

Сообщение vem566 »

Не
On PCINT3 Button:,
а
On INT3 Button:
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 151
Зарегистрирован: Сб ноя 19, 2011 20:13:47
Откуда: Тамбов

Сообщение xorkrus »

Unknown interrupt [INT3]
Он же именно PC, потому что INT у тиньки13 только 0
Демократии нет и не будет!
Государство - это я!
Контактная информация:
Ответить

Вернуться в «AVR»