Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Таймер.

Сообщений 1 страница 7 из 7

1

Продолжаю дальше изучать AVR и BASCOM. Теперь возник вопрос по таймеру. По сравнению с  классическими контроллерами архитектуры MCS-51, в AVR таймеры имеют больше режимов работы . Но с этой гибкостью гибкостью необходимо разобраться.
Допустим, стоит задача сделать секундомер, который будет измерять время с точностью до сотых долей секунды. Тактируем контроллер от кристалла 4 МГц.
Моя логика работы в этом случае.  Выбираем режим сравнения с очисткой регистров таймера, делитель тактовой частоты =1.  Загружаем в регистр OCR1A значение 40000 и ждем прерывания. Получился вот такой код

Код:
$regfile = "m8def.dat"                                      'настройки
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

Config Portd.6 = Input                                      'конфигурирование  портов

Config Timer1 = Timer , Prescale = 1 , Compare A = Set , Clear Timer = 1       'конфигурирование  таймера

'обЪявление  переменных
Dim Endtime As Word
Dim Counttime As Word

On Oc1a Compa                                               'подпрограмма  обраб. прерываний

Endtime = 40000

Compare A = Endtime                                         'задание предела  счёта  таймера
Counttime = 0                                               'очистим переменную

Enable Interrupts                                           'разрешение  прерываний
Enable Oc1a

Do                                                          ' ждем нажатия кнопки

Loop Until Portd.6 = 0
'"старт" счета времени

Start Timer1

Do                                                          ' ждем нажатия кнопки
Loop Until Portd.6 = 0
'"СТОП" счета
Stop Timer1

'вывод значения Counttime на индикатор
'дальше какой-то код
'
'


Compa:                                                      'обработка  препрывания
  Counttime = Counttime + 1
Return

End

В итоге, после компиляции в строке
Compare A = Endtime
ошибка 46 : Assigment error [COMPARE A:0 ENDTIME:6]

Не понятно из-за чего такой косяк вылазит? Что не так?

Отредактировано spin (2012-11-04 10:40:37)

0

2

Пример взят тут http://www.avr.ru/beginer/bascom/article3 . В моей версии хелпа по слову TIMER0, TIMER1 есть только структурная схема таймера и небольшое описание к этой схеме. Может у меня хелп к BASCOM'у урезанный?  o.O

Судя по datasheet'у, после перехода по прерыванию значение регистров TCNTxH и TCNTxL обнулятся. После этого счет будет идти дальше до достижения значения 40 000. Таким образом прерывание выполняться вечно не будет.

Но вопрос остался открытым - что это за ошибка 46, которую выдает компилятор?

Кроме того, в datasheet'е указывается, что с каждым тактом счетчик таймера может увеличиваться или уменьшаться. Это зависит от настроек таймера. Если делать вставки на асме, то ясно. Каким образом задавать эти настройки в BASCOM'е, не используя вставок на асме?

Отредактировано spin (2012-11-01 19:52:51)

0

3

Спасибо, конечно, за код. В этом коде мне понятно все. Ну и перезагружать таймер в прерывании - этот прием достаточно известный. Прошу меня сильно не пинать (простите "чайника"  :blush: ), но мне хочется разобраться более детально.
По-моему, в этом коде есть недостаток - выполнение прерывания выполняется не всегда одинаковое количество тактов. Иногда это кардинально может повлиять на точность разрабатываемого устройства. В некоторых случаях, при нехватке памяти для записи программы, можно будет оптимизировать этот кусок кода, использовав аппаратные возможности контроллеров, которые заложены разработчиками.
Т.е. хочется понять - это ограниченные возможности самого BASCOM'a или неумение использовать его возможности.

В приведенном мной листинге программы речь идет об ATMega8. Вот на нем попробую остановиться.

RDW написал(а):

В АТмегах: все таймера как правило нужно перегружать самому (ручками/в коде), счет идёт в большую сторону.

Смотрим datasheet ATMega8, стр. 87, режим Clear Timer on Compare Match (CTC) . Там говорится, что при достижении счетчика (TCNT1) значения, которое хранится в регистрах OCR1A или ICR1, генерируется прерывание и сбрасывается значение счетчика (режим сброса по совпадению). Т.е. в этом режиме можно не беспокоиться: счетчик сбросится сам, аппаратурно. Вот и есть соблазн использовать именно этот режим в случае секундомера. Или я чего-то не так понял?
Теперь, после выбора режима работы таймера, осталось описать все это в листинге. Токмо не понятно как без вставок на асме...  :confused:

P.S. Режим таймера по совпадению похож на режим таймера с автозагрузкой архитектуры MCS-51 (хочешь-не хочешь, а все таки аналогии какие-то проводятся сами по себе). С MCS-51 я знаком значительно лучше, чем с AVR.

0

4

Вопрос решился. Ошибка была в строке Compare A = Endtime. Надо было написать Compare1a = Endtime и все работает  :blush:

Вот этот кусок компилится без проблем

Код:
$regfile = "m8def.dat"                                      'настройки
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

Config Portd.6 = Input                                      'конфигурирование  портов

Butt Alias Portd.6

Config Timer1 = Counter , Edge = Falling , Compare A = Set , Clear Timer = 1
       'конфигурирование  таймера
Dim Counttime As Word

Dim Endtime As Word

On Oc1a Compa                                               'подпрограмма  обраб. прерываний

Endtime = 40000                                             'задание предела  счёта  таймера

Compare1a = Endtime
Counttime = 0                                               'очистим переменную

Enable Interrupts                                           'разрешение  прерываний
Enable Oc1a

Do                                                          ' ждем нажатия кнопки

Loop Until Butt = 0
'"старт" счета времени

Start Timer1

Do                                                          ' ждем нажатия кнопки
Loop Until Butt = 0
'"СТОП" счета времени
Stop Timer1

'вывод значения Counttime на индикатор
'
'
'


Compa:                                                      'обработка  препрывания
  Incr Counttime
Return

End

0

5

Я не говорил, что в Вашем коде есть ошибки и он не прозрачен.  Напротив - все понятно.
Но я только начинаю изучать AVR и BASCOM. Т.е. мне хочется знать возможности камня и понять как им управляет BASCOM. Нашел в в datasheet'е такой режим работы таймера. Захотелось попробовать реализовать этот режим на практике.  Кроме того, в этом режиме можно подцепить на ногу светодиод и железка сама будет им мигать. Или генерировать какой-то сигнал на этом выводе, используя возможности камня.
Пример кода - это всего лишь "проба пера".

RDW написал(а):

И ещё, команда "INCR" увеличивает только 1 регист, т.е. байт, на word - скорее всего не будет корректно работать.

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

0

6

Доброй ночи! Вопрос знатокам "Bascom" возможно ли применение таймера для обработки нажатия кнопок? у меня проблема с дребезгом контактов, постоянно проскакивает  меню, приходится возвращаться в исходную позицию.  Если есть пример реализаций будьте добры помогите. в прерываний через INT0 не все гладко, с задержками туго работает использую микроконтроллер Атмега16 .

0

7

Toha написал(а):

возможно ли применение таймера для обработки нажатия кнопок?

Да. :) Хорошо сочетается с динамической индикацией по таймеру (если кнопок не больше чем разрядов индикатора). :)

0