» » Програмирование в AVR Studio 5 с самого начала. Часть 8

 
 
 
18

Програмирование в AVR Studio 5 с самого начала. Часть 8

Разместил galrad 9 декабря 2012. Просмотров: 40 468


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

В микроконтроллерах AVR могут быть от одного до 4-х таймеров, восьмиразрядные или шестнадцатиразрядные.
Упрощенно таймеры обозначаются буквой T, и номером от нуля до трех. Обычно четные Т0 и Т2 являются восьмиразрядными, а нечетные Т1 и Т3 шестнадцатиразрядными. При программировании упрощенный вариант используется только в комментариях, а в программах прописывается полное название таймера – регистр TCNT. Ниже показаны обозначения таймеров:

Таймеры

T0, T2 – (TCNT0, TCNT2) восьмиразрядные счетчики (четные)
TCNTn - счетный регистр 8 разрядного счетчика
где; n-номер счетчика

T1, T3 – (TCNT1Н и TCNT1L, TCNT3H и TCNT3L) шестнадцатиразрядные счетчики (нечетные)
TCNTny - счетный регистр 16 разрядного счетчика
где; n-номер счетчика
y-старший (H) или младший (L) разряд

Т1 состоит из двух восьмиразрядных регистров TCNT1Н и TCNT1L, а
Т3 из двух регистров TCNT3H и TCNT3L. Буквой H обозначается старший разряд, а L младший.

Так как таймеры являются регистрами, то к ним можно обращаться в любой момент времени, считывать, записывать, обнулять и менять значение.
Приняты определенные правила записи и чтения в таймеры TCNT1Н и TCNT1L.

1. Программы записи и чтения данных таймера должны быть атомарными, т.е. перед чтением или записью мы запрещаем прерывания, а по окончании процесса вновь разрешаем.
2. При записи сначала записывается старший байт H а затем младший L.
3. При чтении сначала считывается младший байт L затем старший H.
Например:
Запись данных в счетный регистр.

CLI ; Запрещаем прерывания
OUT  TCNT1H,R16 ; Запись старшего байта
OUT  TCNT1L,R17 ; Запись младшего байта
SEI ; Разрешаем прерывания


Чтение данных из счетного регистра

CLI ; Запрещаем прерывания
IN  TCNT1L,R16      ; Считывание младшего байта
IN      TCNT1H,R17      ; Считывание старшего байта
SEI     ; Разрешаем прерывания


Почему такие правила? А все для того, чтобы не исказились данные за то время, которое уйдет на процесс считывания из каждого регистра.
Если использовать прямое чтение 8-битных регистров TCNT1H и TCNT1L, то нельзя быть уверенным, что эти регистры прочитались одновременно. Может произойти следующая ситуация: Счетчик содержал значение $01FF, Вы считали TCNT1H (содержащий значение 01 в какую-то переменную). За это время пришел счетный импульс, и содержимое TCNT1L стало равно $00, а в TCNT1H записалось значение $02.

Теперь Вы читаете значение TCNT1L в другую переменную, получаете в этой переменной значение $00 (ведь таймер/счетчик уже произвел счет). 16-битное значение этих переменных получилось $0100, но на момент считывания старшего байта содержимое счетчика было $01FF, и младший байт у Вас должен был прочитаться как FF. Для предотвращения такой ситуации служит временный регистр, содержащийся в блоке таймера/счетчика. Этот регистр прозрачный, т.е. действует автоматически. При считывании значения регистра TCNT1L в переменную, содержимое TCNT1H попадает в этот регистр. Затем при чтении старшего байта в переменную, считывается значение временного регистра. Временный регистр абсолютно прозрачен для пользователя, но для его корректной работы необходимо соблюдать указанную выше последовательность действий. Обращение к регистрам через дополнительный (буферный) регистр называется двойной буферизацией

Таймеры связаны с счетными импульсами, которые могут быть внешними и поступать на специальный вход микросхемы или формироваться собственным генератором. В свою очередь частота собственного генератора может синхронизироваться внешним кварцевым резонатором, а может определяться внутренней RC – схемой. После этого, внешняя частота или частота собственного генератора, проходят предделитель, управляемый регистром CLKPRастоту генератора после предделителя (прескалера) CLKPR нередко называют тактовым сигналом (тактовой частотой) процессора (CPU).
Частота, подаваемая на вход таймера обозначается как CLKTn Эта частота соответствует тактовому сигналу процессора.
Один счетный импульс увеличивает значение таймера на единицу, поэтому регистры TCNT являются счетными, и называются таймером/счетчиком (ТС).
Для правильной работы таймера/счетчика по внешнему тактовому сигналу минимальное время между двумя переключениями внешнего тактового сигнала должно быть не менее одного периода тактового сигнала CPU. Синхронизируется внешний тактовый сигнал нарастающим фронтом внутреннего тактового сигнала CPU. (Это нужно помнить при построении частотомеров).
Управляющим регистром для таймера/счетчика TCNT является регистр TCCR.
Маской прерывания для таймера/счетчика TCNT служит регистр TIMSK (регистр управления прерываниями таймера).
Регистром флагов маски прерывания TIMSK - является регистр TIFR. Запомните, что эти 3 регистра (TCCR, TIMSK, TIFR) при работе таймера/счетчика TCNT используются почти всегда.

Прерывания могут вызываться по переполнению регистра TCNT, сравнению значения регистра TCNT со значением специальных регистров сравнения OCR, захвату – по значениям специальных регистров захвата ICR и определяются режимом работы таймера/счетчика. Кроме этого запрос прерывания может происходить по срабатыванию сторожевого таймера (Watchdog Timer) WDT.

Таймеры/счетчики могут работать в разных режимах и соответственно выполнять разные функции.
Режим работы, то есть, поведение таймера/счетчика и выхода сигнала совпадения, определяется как режимом работы генератора сигналов, управляемого регистрами WGM02; WGM01; WGM00 (сокращенная запись WGM02:0), так и режимом вывода сигнала совпадения, управляемых регистрами СОМ0х1; СОМ0х0 (сокращенная запись СОМ0х1:0). Состояние битов, от которых зависит режим вывода сигнала совпадения, не влияет на последовательность подсчета, которая определяется только состоянием битов конфигурации генератора сигналов.

Биты СОМ0х1:0 определяют, должен ли выходной сигнал ШИМ быть инвертирован или нет (инвертированный или не инвертированный ШИМ).
(ШИМ) Широтно-импульсная модуляция или Pulse-width modulation (PWM).
Для не-ШИМ-режимов содержимое битов СОМ0х1:0 определяет, должен ли сигнал на выходе быть установлен в единицу, сброшен в ноль либо переключен в противоположное состояние в момент совпадения

Выделяют следующие режимы работы таймеров:

Normal – подсчет и прерывание по переполнению. В этом режиме, при выставленном бите TOIE регистра TIMSK возникает запрос на прерывание. Условием для прерывания будет обнуление регистра таймера TCNT, которое происходит после заполнения всех ячеек (после числа 0xFF) и фиксируется аппаратным поднятием флага переполнения TOV в регистре TIFR.
Флаг TOV0 в этом случае ведет себя как девятый бит, за тем исключением, что он только устанавливается, но не сбрасывается.
Используя прерывание по переполнению таймера, которое автоматически очищает флаг TOV0, можно увеличить коэффициент пересчета программным путем. Режим Normal не имеет других функций и считается наиболее простым.

Capture – (захват) запоминание значения счетчика в специальном регистре захвата ICRx по управляющему сигналу (от специального входа микроконтроллера (ICP) или от выхода встроенного компаратора), где x- соответствует номеру счетчика. Одновременно с захватом происходит запрос на прерывание и переход на векторы прерывания - CAPT. Устанавливается прерывание в этом режиме битом ICIE или TICIE в регистре TIMSK, и фиксируется поднятием флага ICF в регистре TIFR.

CTC – (Clear Timer on Compare) сброс при совпадении – сравнение со значением специальных регистров совпадения OCR, которые используется для того, чтобы управлять коэффициентом пересчета счетчика.
Происходит запрос на прерывание и переход на векторы прерывания - COMP. Регистры совпадения обозначаются как OCRnxy
где; n - номер счетчика,
x –регистр А или B (если регистров совпадения 2, то обозначают первый как как регистр A, а второй как регистр B, каждый из них может быть 16 разрядным)
y - старший (H) или младший (L) разряд регистров совпадения.

В большинстве моделей микроконтроллеров одному восьмиразрядному таймеру соответствуют два восьмиразрядных регистра сравнения OCR, регистр А и регистр В. Например, таймеру TCNT0 соответствуют два регистра сравнения OCR0A и OCR0B.
Если таймер шестнадцатиразрядный, то ему соответствуют четыре восьмиразрядных регистра сравнения, например, таймеру TCNT1 соответствуют OCR1AH и OCR1AL, OCR1BH и OCR1BL.

В режиме СТС возникает запрос прерывания, сброс таймеров (при совпадении с OCR1 и OCR1A) или изменяется состояние выводов микроконтроллера, которые зависят от установленных настоек таймера.

Значения ячеек регистров TIMSK и TIFR в разных моделях микроконтроллеров имеют похожие функции и названия, но могут отличаться расположением, и при переходе с одного контроллера на другой трудностей не вызывают.

Tiny


Бит 0 - OCIE0A: прерывание по совпадению таймера-счетчика T0A
Бит 1 - TOIE0: прерывание по переполнению Т0
Бит 2 - OCIE0B: прерывание по совпадению таймера-счетчика T0B
Бит 3 - ICIE1: Разрешение прерывания по входу захвата (вход ICP)
Бит 4 - Зарезервировано
Бит 5 – OCIE1B: прерывание по совпадению таймера-счетчика T1B
Бит 6 – OCIE1A: прерывание по совпадению таймера-счетчика T1A
Бит 7 – TOIE1: прерывание по переполнению Т1

Флаги соответствуют прерываниям в регистре TIMSK. Устанавливаются в "1" при выполнении условий соответствующего прерывания.

Mega8




Mega16


Бит 7 - OCIE2: прерывание по совпадению Т2
Бит 6 - TOIE2: прерывание по переполнению Т2
Бит 5 - TICIE1: прерывание по захвату Т1
Бит 4 - OCIE1A: прерывание по совпадению A Т1
Бит 3 - OCIE1B: прерывание по совпадению В Т1
Бит 2 - TOIE1: прерывание по переполнению Т1
Бит 1 - OCIE0: прерывание по совпадению таймера-счетчика T0 (В Mega8 этот бит зарезервирован)
Бит 0 - TOIE0: прерывание по переполнению Т0
Если соответствующий бит установлен в "1" и бит I (7-й бит) регистра состояний SREG установлен в "1", тогда соответствующее прерывание будет срабатывать.

Флаги соответствуют прерываниям в регистре TIMSK. Устанавливаются в "1" при выполнении условий соответствующего прерывания.

Теперь рассмотрим механизмы управления функциями таймеров

За установку различных режимов и функций таймеров отвечает регистр TCCR
TCCRnx - восьмиразрядные регистры управления таймерами
где; n-номер счетчика
х-буквенное обозначение регистра управления

Например в микроконтроллере ATtiny2313 простому восьмиразрядному таймеру/счетчику T0 будет соответствовать регистры - TCCR0А и TCCR0B
a, шестнадцатиразрядному таймеру/счетчику T1 – восьмиразрядные регистры TCCR1A, TCCR1B, TCCR1C. В других моделях микроконтроллеров управляющих регистров может быть больше, которые обозначаются буквами латинского алфавита – A,B,C,D и т.д.

Для того, чтобы упорядочить типы таймеров/счетчиков по их функциональному назначению, их тоже принято обозначать в виде заглавных букв латинского алфавита:
A – Восьмиразрядный таймер-счетчик без дополнительных функций
B – Восьмиразрядный таймер-счетчик с функциями сравнения/ШИМ
C – Восьмиразрядный таймер-счетчик с функциями сравнения/ШИМ и функцией счета реального времени
D – Шестнадцатиразрядный таймер-счетчик с функциями захвата и сравнения/ШИМ
E – Шестнадцатиразрядный таймер-счетчик с функцией захвата и двумя каналами для выполнения функций сравнения/ШИМ.

В данном случае функции таймеров/счетчиков конкретизированы, и поэтому выглядят более наглядно. Это может вносить некоторую путаницу с буквенным обозначением восьмиразрядных регистров управления, которые просто идут по порядку, и могут сбивать с толку начинающих.

При описании счетчиков используются специальные обозначения для всех его важных состояний.

BOTTOM – счетчик достигает значения BOTTOM (начало), когда его содержимое равно 0х0000
MAX - счетчик достигает значения MAX (максимум), когда его содержимое равно 0хFF для восьмибитных таймеров/счетчиков и 0xFFFF для шестнадцатибитных таймеров/счетчиков.
TOP - Счетчик достигает значения ТОР (вершина), когда его содержимое
достигает самого высокого значения в данном режиме работы. В
зависимости от режима значение ТОР может быть равно либо OxFF (МАХ) для восьмибитных таймеров/счетчиков или 0x00FF, 0x01FF, 0x03FF для шестнадцатибитных таймеров/счетчиков либо значению, записанному в регистре OCR0A (режим сброса по совпадению - CTC)

Напомню, что в ATtiny2313 один 8- разрядный таймер/счетчик с отдельным предделителем и один 16-разрядный таймер/счетчик с отдельным предделителем, схемой сравнения, схемой захвата и двумя каналами широтно-импульсной модуляции (ШИМ).
Или по другому - один таймер/счетчик типа A и один таймер/счетчик типа D
с регистрами управления TCCR0А, TCCR0B и TCCR1A, TCCR1B, TCCR1С.

ATtiny2313

T0, таймер/счетчик типа A, регистры управления TCCR0А, TCCR0B


T1, таймер/счетчик типа B, регистры управления TCCR1А, TCCR1B, TCCR1C




Рассмотрим назначение битов регистров TCCR:
CS02:CS01:C00 - Разряды, определяющие источник тактового сигнала таймера/счетчика Т0.
CS12:CS11:C10 - Разряды, определяющие источник тактового сигнала таймера/счетчика Т1.

где n - номер счетчика
В зависимости от установленных бит CS, мы можем получить прямой, инверсный или поделенный на 8,64, 256, 1024 счетный импульс, а так же полностью остановить счет.

Для практического программирования нужно просто запомнить эту таблицу с назначением битов CS.
COM0A1:COM0A0:COM0B1:COM0B0 - Эти разряды определяют поведение вывода OC1A:OC1B при совпадении значения счетного регистра TCNT0 и регистра сравнения OCR0A:OCR0B
COM1A1:COM1A0:COM1B1:COM1B0 - Эти разряды определяют поведение вывода OC1A:OC1B при совпадении значения счетного регистра TCNT1 и регистра сравнения OCR1A:OCR1B

ICNC1 - Разряд управления схемой помех, если бит равен "0" захват будет по первому активному фронту, если "1" захват будет после четвертой одинаковой выборки сигнала захвата.

ICES1 - Разряд выбора активного фронта сигнала, если его значение равно "0", сохранение счетного регистра TCNT1 в регистре захвата OCR1 будет по спадающему фронту сигнала, если "1" по нарастающему.

WGM02: WGM01: WGM00 - Эти разряды определяют режим работы таймера/счетчика Т0



WGM13:WGM12:WGM11:WGM10 - Эти разряды определяют режим работы таймера/счетчика Т1



FOC1A:FOC1B - Эти разряды служат для принудительного изменения состояния вывода OC1A:OC1B
(Регистр TCCR1C и его биты FOC1A:FOC1B не прописаны в файле 2313def.inc поэтому при необходимости можно программно их назначить
.equ TCCR1С = 0x22 ; TCCR1C - Timer/Counter1 Control Register C
.equ FOC1B = 6 ; изменение состояния вывода OC1B
.equ FOC1A = 7 ; изменение состояния вывода OC1A

Посмотрите карту регистров ввода-вывода для ATtiny2313. Там есть регистр TCCR1С под адресом $0x22, но работает этот регистр или нет, я не проверял. (По технической документации должен работать.)

Рассмотрим еще два регистра:

GTCCR – главный регистр управления таймерами


В этом регистре всего один бит PSR10 – выполняет сброс предварительных делителей всех таймеров. После сброса предделителей таймеров бит PSR10 немедленно очищается (переводится в 0).
Есть еще один регистр, который управляет делителем тактовой частоты процессора CLKPR. Нередко начинающий программист путает биты регистра TCCR, определяющие источник тактового сигнала таймера/счетчика с битами управления предделителя CLKPR. Дело в том, что регистр CLKPR изменяет тактовую частоту процессора. Например, если в наличии имеется кварцевый резонатор на 64 МГц, а нам нужно 8 МГц то мы можем использовать этот резонатор, подключив через прескалер (предделитель), разделив исходную частоту на 8. Прескалер (предделитель) регистра TCCR (биты CS), управляет частотой, которая попадает на входы счетчиков/таймеров и ни как не влияет на тактовую частоту процессора.

Регистр CLKPR (Clock Prescale Register)

Изменяя его биты можно менять значение предделителя тактового сигнала
Для управления предделителем тактового сигнала предназначен регистр CLKPR, расположенный по адресу (0х46) в пространстве дополнительных регистров ввода/вывода. Формат этого регистра:

Старший бит (СLKРСЕ) служит для разрешения изменения частоты тактового сигнала, а биты CLKPS3...CLKPS0 задают коэффициент деления предделителя
Выбор коэффициента деления предделителя (прескалера) тактового сигнала

Для изменения содержимого битов CLKPS3...0 следует выполнить следующие действия:
1. Записать в бит СРСЕ лог. 1, а в биты CLKPS3...0 — лог. 0.

2. В течение следующих четырех тактов занести требуемое значение в биты CLKPS3...0, при этом бит СРСЕ будет сброшен в 0. В противном случае бит СРСЕ буден сброшен аппаратно по истечении четырех тактов, запрещая дальнейшее изменение битов CLKPS3...0.

Начальное состояние битов CLKPS3...0 определяется конфигурационной ячейкой CKDIV8. Если она не запрограммирована (1), то при запуске микроконтроллера в битах CLKPS3...0 будет находиться значение 0000. Если же ячейка CKDIV8 запрограммирована (0), стартовым значением битов CLKPS3...0 является 0011 (коэффициент деления — 8).

В микроконтроллере ATtiny2313 по умолчанию установлена частота встроенного тактового генератора 8 МГц, с коэффициентом деления прескалера 8, т.е. тактовая частота процессора равна 1 МГц. Биты регистра CLKPR доступны при прошивке кристалла программатором в виде фьюзов. О них мы еще поговорим отдельно.

Перепишем программу бегущих огней включив задержку от встроенных таймеров:




Теперь рассмотрим ШИМ

ШИМ – это широтно-импульсная модуляция, или PWM — Pulse Width Modulation - метод, позволяющий из цифровых импульсов получить аналоговый сигнал, а так-же один из способов регулирования мощности в нагрузке. Предположим, что у нас, есть генератор прямоугольных импульсов с постоянной амплитудой (размахом) и определенной частотой. Частота (Гц – герц) представляет собой количество импульсов в секунду и обратно пропорциональна периоду – (Т) времени, за которое появляется новый импульс; F= 1/T

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


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

а уменьшить мощность можно удлинением отрицательного участка периода. Именно по этому принципу работает ШИМ.

В импульсной технике нередко можно встретить слова скважность, меандр, коэффициент заполнения. Определимся с терминологией.
Отношение периода к длительности импульса называется скважностью. Величина обратная скважности называется периодом заполнения.
S=T/т=1/D; где
S-скважность, T-период, т-длительность импульса, D-коэфициент заполнения.
Скважность определяет соотношение между пиковой и средней мощностью импульсов напряжения или тока.
Сигнал со скважностью, равной двум — называется меандр.
В меандре есть положительный и нулевой полупериоды, которые равны по времени.
В микроконтроллерах с помощью таймеров или подпрограмм задержек мы можем сформировать сигнал с произвольным периодом, притом положительный и нулевой участки, с разными значениями.
Существуют два режима ШИМ:
Fast PWM (быстрый ШИМ)
Phase Correct PWM (ШИМ с точной фазой)
В микроконтроллерах AVR, частота ШИМ определяется тактовой частотой процессора и разрядностью таймера/счетчика. Регистр сравнения OCR определяет скважность выходного сигнала.
В режиме Fast PWM период начинается с положительного значения сигнала, до тех пор пока значение TCNT не совпадет со значением регистра OCR, когда значение счетчика/таймера TCNT станет равным значению регистра сравнения OCR, происходит спад сигнала до нуля, и продолжается до начала нового периода.
Как правило, ШИМ в микроконтроллерах построен на 8-битном счетчике/таймере TCNT, который считает от 0 до 256, период которого равен T=256/Fcpu, (Fcpu –тактовая частота процессора). Например, при тактовой частоте процессора в 1 МГц, период работы счетчика составит 256 микросекунд, а частота 3906Гц. Повышение разрядности счетчика вполне возможно, но это приводит к снижению частоты ШИМ, что само по себе не желательно.

Частоту ШИМ можно определить, разделив тактовую частоту процессора на 256. Например при тактовой частоте процессора 8 МГц, частота ШИМ составит 31250Гц.

Недостатком этого режима считается смещение фазы сигналов при изменении скважности.

В режиме Phase Correct PWM недостаток смещения фаз при изменении скважности устранен, за счет использования двух периодов, т.е. частота меньше в два раза в сравнении с режимом Fast PWM.

В режиме Phase Correct PWM счетчик/таймер TCNT сначала считает от 0 до 256. При совпадении со значением регистра OCR, сигнал на выходе сбрасывается, затем счет в счетчике/таймере TCNT идет в обратном порядке от 256 до 0, а при совпадении значения TCNT со значением регистра OCR, сигнал на выходе устанавливается в единичное состояние.

Для того чтобы задать ШИМ в микроконтроллере нам нужно определить несколько параметров, из описания понятно, что нужно: задать вид ШИМ и разрядность с помощью регистров WGM, прописать значение регистра OCR, выставить режим работы выхода сигнала ШИМ с помощью регистров COM.
Установить делители счетчика/таймера TCNT равным 1:1с помощью регистров CS.
Назначения регистров WGM для tiny2313 мы уже рассматривали выше в виде двух таблиц для TCNT0 и TCNT1.
Значения регистра OCR будем менять произвольно.

Подробнее рассмотрим назначение регистров COM.
Режим обычного таймера


Режим Fast PWM для регистров COM0


Режим Phase correct PWM для регистров COM0


Режим Fast PWM для регистров COM1


Режим Phase correct PWM для регистров COM1


В этих таблицах показаны функции выходов OC0A, OC0B и OC1A, OC1B в зависимости от состояния регистров COM0 и COM1 (ATtiny2313, для Mega8 и Mega16 таблицы несколько отличаются)

Биты CS02:CS01:CS00 – для таймера/счетчика Т0, CS12:CS11:CS10 – для таймера/счетчика Т1. Из них нас интересует только CS00 или CS10.
Теперь можно написать простенькую программу, демонстрирующую работу ШИМ. Если Вы разобрались с прерываниями, работой таймеров и поняли как работает ШИМ, то можно уверенно сказать, что Вы прошли самые тяжелые в освоении пункты. Остальное будет значительно проще!
Возьмем самую простую задачу – создать ШИМ сигнал в режиме Fast-PWM, на основе восьмибитного счетчика/таймера. Тогда нам потребуется прописать биты регистра управления таймера TCCR0A: COM0A1=1, WGM1=1, WGM0=1 и бит предделителя в регистре TCCR0B: CS00=1

Инициализация ШИМ:
 
 ldi temp,(1<<COM0A1)|(1<<COM0A0)|(1<<WGM01)|(1<<WGM00)  ; Выбор режима таймера
 out             TCCR0A, temp
 ldi             temp, (1<<CS00) 
 out             TCCR0B, temp    


Программа будет выглядеть следующим образом:


В Протеусе будет выглядеть так:

ShIM.rar | Файл 517,88 Kb загружен 37 раз.


Можно сделать шаг равный единице, тогда изменения будут выглядеть следующим образом:

plus:
 rcall delay  ; Переход в подпрограмму задержки 
 inc temp2    ; Переходим на один шаг и проверяем, не равен ли результат нулю
 breq plus_1   ; Если равен, то переходим на метку plus_1
 rjmp    Correct   ; Возват на опрос кнопок
plus_1:
 dec temp2       ; вычитаем единицу
 rjmp    Correct     ; Возврат на опрос кнопок

minus:
 rcall delay     ; Переход в подпрограмму задержки 
 dec temp2        ; Переходим на один шаг и проверяем, не равен ли результат нулю
 breq minus_1     ; Если равен, то переходим на метку minus_1
 rjmp    Correct    ; Возврат на опрос кнопок
minus_1:
 inc temp2     ; прибавить единицу
 rjmp    Correct    ; Возврат на опрос кнопок



В связи с неактуальностью AVRStudio 5, и микроконтроллера ATtiny2313 серия статей будет переписана под AtmelStudio6, и микроконтроллеры ATmega8 и ATmega16. Заранее приношу извинения за неудобства.
Радик (galrad)
РФ. Республика Башкортостан. г.Уфа
Профиль galrad
1964г.р. Специальность - врач. Ученая степень - кандидат медицинских наук. Радиоэлектроника - увлечение с 15 лет. Приоритетные направления - микроконтроллеры, цифровая электроника, измерения, ремонт компьютеров и сотовых телефонов, и т.п. Второе высшее образование - инженер-электроник.
 

Понравилось? Палец вверх!

  • всего лайков: 58

Поделись с друзьями!

Связанные материалы:


Схема на Датагоре. Новая статья Визуализация для микроконтроллера. Часть 2. TFT дисплей 1.8" (128х160) на ST7735... Следующий из рассматриваемых нами модулей обладает полноцветным дисплеем под управлением...
Схема на Датагоре. Новая статья Трансивер 2,4 ГГц Nordic Semiconductor nRF24L01. Перевод таблиц даташита, пояснения и коды для организации сети... Wireless Transceiver Module NRF24L01+ 2.4GHz, 4 шт. на Али Привет, датагорцы! Выкладываю перевод...
Схема на Датагоре. Новая статья Беспроводной канал связи 2,4 ГГц на базе трансивера nRF24L01+ от Nordic Semiconductor. Часть 1... Доброго вам дня, уважаемые граждане и гости Датагор.ру - этого замечательного сообщества...
Схема на Датагоре. Новая статья Несколько функций для програмной реализации протокола I2C на AVR... Добрый день, дорогие друзья! Решил поделиться с вами несколькими функция для работы по протоколу...
Схема на Датагоре. Новая статья Немного про шину 1-Wire и цифровой термометр DS18b20... Фотка от www.150cc.ru Здравствуйте, друзья. Хочу предложить вашему вниманию несколько простых...
Схема на Датагоре. Новая статья Программа ForMC в помощь программисту микроконтроллеров... Программа называется ForMC, изначально предназначалась для МК AVR. В ней объединены несколько...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 6... Продолжим разбор теоретических основ, без которых невозможно полноценное создание программ....
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 3... Мы научились включать и выключать светодиоды, а как сделать, чтобы они сами заморгали? Понятно, что...
Схема на Датагоре. Новая статья Програмирование в AVR Studio 5 с самого начала. Часть 2... Пишем первую программу!Большинство начинают с мигания светодиодов, и мы не исключение. Если...
Схема на Датагоре. Новая статья Astroburn Lite. Простая бесплатная программа для записи CD, DVD и Blu-ray дисков... Лучший выбор для тех, кто хочет иметь быструю и легкую в использовании программу с необходимыми...
Схема на Датагоре. Новая статья Микроконтроллеры AVR семейств Tiny и Mega фирмы ATMEL, Евстифеев А.В.... Издательство: Додэка XXI [М.], 560 стр. 2005 г. Книга посвящена вопросам практического применения...
Схема на Датагоре. Новая статья CoolReader2 - программа для чтения электронных книг... CoolReader — это удобная программа для чтения электронных книг. Чем мне приглянулась именно ЭТА...
<
  • Кандидат
17 октября 2012 20:31

Михаил / Dust112

Цитата
  • С нами с 22.05.2011
  • Ушёл в реал Пользователь offline
  • 14 комментариев
  • 1 публикация
 
  • 0
Радик, спасибо за статьи. В свое время ушло много времени на понимание таинств таймеров AVR.

<
  • Гражданин
20 октября 2012 20:57

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
По тексту про ШИМ очепятка: "Величина обратная скважности называется периодом заполнения. S=T/т=1/D; " Коэффициент заполнения.
Наконец-то понятно объяснили смысл фазокорректной ШИМ!

<
  • Гражданин
20 октября 2012 21:26

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Верно: не период, а коэффициент заполнения. Спасибо!

<
  • Гражданин
23 октября 2012 03:11

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
Вопрос. В тех МК, в которых контроллер ШИМ встроен (я так понимаю, что это усложнение схемы одного из таймеров), есть регистры ШИМ типа OCR0A и OCR0B (ATtiny13). Я правильно понимаю, что это не РОН, а специальные отдельные аппаратные регистры? И еще, МК имеет несколько ШИМ выходов (тини-13 2 шт). А таймер один. Значит ли это, что оба выхода ШИМ не могут работать одновременно, а только поочереди?

<
  • Кандидат
24 октября 2012 00:05

Михаил / Dust112

Цитата
  • С нами с 22.05.2011
  • Ушёл в реал Пользователь offline
  • 14 комментариев
  • 1 публикация
 
  • 0
Да, регистры OCR0A и OCR0B относятся только к таймеру.
Значения из OCR0A и OCR0B сравниваются с значение в TCNT0 и при совпадении значений происходит действия с определенной ножкой контролера, т.е. оба выхода могут работать одновременно.

<
  • Гражданин
24 октября 2012 19:51

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Цитата: AudioKiller
В тех МК, в которых контроллер ШИМ встроен (я так понимаю, что это усложнение схемы одного из таймеров), есть регистры ШИМ типа OCR0A и OCR0B (ATtiny13). Я правильно понимаю, что это не РОН, а специальные отдельные аппаратные регистры?

Аппаратный ШИМ можно реализовать практически в любом котроллере, где есть встроенный таймер. Основной регистр -TCNT, как боченок с водой, наполняется и как только заполнится, сразу опорожняется, скорость заполнения определяется краниками - битами CS регистра TCCR. Но мы можем определить уровень при любом заполнении, если поставим определитель уровня - регистры OCR, их может быть два на один боченок, (два регистра OCR на один 8-битный регистр TCNT), конечно-же OCR это не регистры общего назначения.
Цитата: AudioKiller
И еще, МК имеет несколько ШИМ выходов (тини-13 2 шт). А таймер один. Значит ли это, что оба выхода ШИМ не могут работать одновременно, а только поочереди?

Почему? Могут, только нужно учитывать, тот факт, чтобы - не было опорожнения бочка на первом определителе уровня, иначе уровень никогда не дойдет до второго, который будет установлен выше, только в этом случае придется заполнять по очереди, то для одной метки, то до другой. А так как а режиме ШИМ заполнение происходит до верху, сигналы будут формироваться на обеих выходах, а вот в каком режиме будет работать каждый выход, определяется регистрами COM.

<
  • Гражданин
24 октября 2012 21:21

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
Я хорошо разбираюсь в логических и цифровых элементах и старых процах (КР580 форева!), но в контроллерах не совсем понимаю их структуру и взаимодействие потрохов, а не понимая не могу нормально их пользовать. Вот и пытаюсь разобраться в тонкостях конструкции.

Т.е. регистры OCR - это специальные дополнительные аппаратные регистры - автоматически сравниваются с содержимым таймера, который в это время работает как циклический счетчик (на своей тактовой частоте) и выдают на соответствующий выход (бит порта, задействованный для выхода ШИМ) соответственно 1 или 0 в зависимости от сравнения их содержимого с содержимым счетчика таймера...

Действительно, таким образом можно одновременно использовать сколько угодно регистров и один счетчик. Но ведь это только для фаст-ШИМ. При фазокорректной ШИМ надо изменять направление счета, а если его изменить по результатам одного регистра OCR (у которого значение меньше), то до второго вооще не досчитает. Как тогда? Фазокорректная работает только с одним выходом? (как пример - Тини13)

И еще, те выходы МК, которые задействованы в аппаратной ШИМ, управляются от отдельной схемы сравнения содержимого OCR и таймера-счетчика, так? А вот если аппаратно ШИМ не реализовано, то я должен это делать ручками - хранить числа в РОН, сравнивать их со счетчиком и выдавать результаты в порт. Но тут уже сам выбираю любой из выходов. Правильно я понимаю?

<
  • Гражданин
24 октября 2012 22:19

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Цитата: AudioKiller
При фазокорректной ШИМ надо изменять направление счета, а если его изменить по результатам одного регистра OCR (у которого значение меньше), то до второго вооще не досчитает. Как тогда?

Направление счета меняется автоматически с большего на меньшее, после полного заполнения, значение регистра TCNT не сбрасывается, поэтому сравнение произойдет с обеими регистами OCR, естественно сигналы будут на обеих выходах, фаза при этом не смещается, по этому принципу управляются контроллером 3-х фазные двигатели.
Цитата: AudioKiller
И еще, те выходы МК, которые задействованы в аппаратной ШИМ, управляются от отдельной схемы сравнения содержимого OCR и таймера-счетчика, так? А вот если аппаратно ШИМ не реализовано, то я должен это делать ручками - хранить числа в РОН, сравнивать их со счетчиком и выдавать результаты в порт. Но тут уже сам выбираю любой из выходов. Правильно я понимаю?

По сути, Да. Вы можете реализовать прогаммно ШИМ, не используя всторенный таймер.

<
  • Гражданин
25 октября 2012 03:34

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
И выходит, что аппаратная ШИМ работает параллельно и практически независимо от ядра. А если ШИМ организовывать вручную, то ее надо пускать на малой скорости (только как?), чтобы прерывания, вызванные работой остальной части программы, ее не сбивали. А как это сделать, если в двух словах?

<
  • Гражданин
25 октября 2012 14:42

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Цитата: AudioKiller
А если ШИМ организовывать вручную, то ее надо пускать на малой скорости (только как?)

Ну, здесь уже программисту решать, все зависит от тех задач, которве перед вами поставлены.
Цитата: AudioKiller
А как это сделать, если в двух словах?

Контроллер в режиме ШИМ, выполняет функции генератора сигналов, длительность импульса определяется программными задержками. Если есть прерывания, то лучше зафиксировать событие поднятием флага, и чуть позже выполнить подпрограмму.

<
  • Гражданин
28 октября 2012 03:46

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
И еще вопрос. Правильно ли я понимаю, что в МК за прерывания по таймеру отвечает отдельная независимая схема, и при работе таймера в режиме ШИМ, он все равно выдает запрос на прерывание при переходе его счетчика через 0. Т.е. мы имеем прерывания с периодом, равным периоду ШИМ? И которые потом можно использовать для счета, например (т.е. мы не теряем таймер, как систему формирования временнЫх задержек, а просто немного усложняем с ним общение). И если надо программно сформировать задержку чего-то, то мы по прерыванию от таймера инкрементируем/декрементируем регистр в котором организован счетчик и все ОК. Так?

<
  • Гражданин
29 октября 2012 14:59

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Цитата: AudioKiller
Правильно ли я понимаю, что в МК за прерывания по таймеру отвечает отдельная независимая схема, и при работе таймера в режиме ШИМ, он все равно выдает запрос на прерывание при переходе его счетчика через 0. Т.е. мы имеем прерывания с периодом, равным периоду ШИМ?

В прерываниях работает та-же схема - счетный регистр TCNT, регистры совпадения OCR, а сработает прерывание или нет, зависит от установленного бита в регистре TIMSK (или по совпадению - бит OCIE, или по переполнению - бит TOIE, которые поднимают соответствующий флаг в регистре TIFR). Не забывайте, что прерывание сработает только тогда, когда установлен флаг разрешения глобального прерывания I в регистре SREG, при возникновении прерывания программа перейдет на соответствующую строку вектора прерывания.
Цитата: AudioKiller
И если надо программно сформировать задержку чего-то, то мы по прерыванию от таймера инкрементируем/декрементируем регистр в котором организован счетчик и все ОК. Так?

ШИМ организован на работе 8-битных регистров. Если вы используете короткие задержки, не требующих применение 16 и более битных регистров, то достаточно просто одновременно применять с ШИМ, в других случаях программный код несколько усложняется, но в принципе тоже позволяет (с танцами с бубном).
Просто нужно помнить, что регистр TCNT - счетный, он просто считает количество пришедших импульсов. В режиме Normal, вы можете записать в него какое-то число и подождать, пока полностью заполнится, время заполнения определяется регистрами CS, таким образом вы определяете время задержки. Чтобы узнать, когда же возникло обнуление, вы можете периодически считывать флаг Z, что не удобно, или установить прерывание и считывать флаг в регистре TIFR, или сразу переводить в подпрограмму прерывания... В режиме CTC происходит то же самые, но при совпадении значений TCNT с OCR, в режиме захвата по установленому сигналу (паример от компаратора) значение TCNT копируется в специальный регистр ICR, и выполняется прерывание...

<
  • Гражданин
29 октября 2012 21:38

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
Я об этом и спрашиваю. В смысле:

1. Если я настрою таймер на фаст-ШИМ, разрешу прерывания вообще и прерывание по переполнению таймера, то при том, что у меня непрерывно работает ШИМ выход, каждый 256-й счет таймера (с его тактовой частотй) я получаю прерывание. Причем, поскольку ШИМ реализуется аппаратно другими потрохами МК, то я могу спокойно это прерывание обработать, лишь бы оно не было длиннее, чем 256 периодов тактовой таймера.

2. И наоборот. Например, по прерыванию от таймера, в обработчике этого прерывания я могу загрузить в регистр OCR0 следующее значение, которое нужно выдать при помощи ШИМ, и спокойно заниматься чем-то в фоне. Т.е. у меня значения ШИМ меняются по прерыванию от того самого таймера, который эту ШИМ и организует.

Я правильно все понял (я имею ввиду принцип, понятно, что в каждом случае нужен свой ритуал, типа запрета/разрешеия прерываний и т.п.)?

<
  • Гражданин
30 октября 2012 13:46

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Цитата: AudioKiller
Я правильно все понял (я имею ввиду принцип, понятно, что в каждом случае нужен свой ритуал, типа запрета/разрешеия прерываний и т.п.)?

Верно! Можно изменить значение ШИМ в отдельной подпрограмме, которое вызовет прерывание, есть конечно моменты на которые необходимо обратить внимание, и такие варианты нередко используются...

<
  • Гражданин
30 октября 2012 14:00

Игорь Рогов / AudioKiller

Цитата
  • С нами с 10.01.2012
  • Ушёл в реал Пользователь offline
  • 293 комментария
  • 3 публикации
 
  • 0
Спасибо! drinks

<
  • Кандидат
14 декабря 2012 20:26

Иван / I2C

Цитата
  • С нами с 16.05.2009
  • Ушёл в реал Пользователь offline
  • 1 комментарий
  • 0 публикаций
 
  • 0
Радик, спасибо. В чём глубокий смысл очищать ZL & ZH перед инициализацией? В этом нет необходимости.
cpi ZL,low(RAMEND+1) ; Если не достигли конца младшего байта оперативной памяти
brne flush ; то продолжаем обнулять

clr ZL ; Очищаем индексы младшего
clr ZH ; и старшего байтов памяти

; ===================================================
; Инициализация регистров общего назначения
ldi ZL, 30 ; Адрес самого старшего регистра
clr ZH ; Обнуляем

<
  • Гражданин
15 декабря 2012 20:06

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 88 комментариев
  • 12 публикаций
 
  • 0
Цитата: I2C
В этом нет необходимости.

Во многих случаях, строки инициализации вообще не прописывают, кроме стека. Всегда предполагается, что если даже есть "мусор", правильно написанная программа однозначно от них ''освободится".

<
  • Прохожий
5 апреля 2013 20:49

/ Сергей

Цитата
  • С нами с --
  • 0 комментариев
  • 0 публикаций
 
  • 0
А здесь Вы ничего не перепутали?
Чтение данных из счетного регистра

CLI ; Запрещаем прерывания
IN TCNT1L,R16 ; Считывание младшего байта
IN TCNT1H,R17 ; Считывание старшего байта
SEI ; Разрешаем прерывания

Добавление комментария


Налетай! Паяльники, станции, жала с доставкой
  • smilelolbyewinkyahoocoollaughing
    crazybadcryingsadirefulsickstraight
    ballooncakegooddrinksmailbombsun
    nightrainstarscolddashguitar-manhandshake
    musicnegativenopardonshoksleepunknown
    wackoyawnblushbullyhashsmokingwhew
Скопируйте текст вашего комментария на случай неверного ответа на контрольный вопрос.