3 ЛАБОРАТОРНАЯ РАБОТА № 7
Тема: ИСПОЛЬЗОВАНИЕ ТАЙМЕРА ДЛЯ ОТСЧЕТА ВРЕМЕНИ
Цель: получение навыков использования таймера для отсчета времени.
3.1 Краткие сведения из теории
Большинство задач управления, которые реализуются с помощью МК, требуют исполнения их в реальном времени. Под этим понимается способность системы получить информацию о состоянии управляемого объекта, выполнить необходимые расчетные процедуры и выдать управляющие воздействия в течение интервала времени, достаточного для желаемого изменения состояния объекта.
Схема тактирования и цикл выполнения команды
Входная тактовая частота, поступающая с вывода OSC1/CLKIN, делится внутри на четыре, и из нее формируются четыре циклические не перекрывающиеся тактовые последовательности Q1, Q2, Q3 и Q4. Счетчик команд увеличивается в такте Q1, команда считывается из памяти программы и защелкивается в регистре команд в такте Q4. Команда декодируется и выполняется в течение последующего цикла в тактах Q1...Q4. Схема тактирования и выполнения команды изображена на рис. 2
Рис. 2. Схема тактирования и выполнения команды
Цикл выполнения команды состоит из четырех тактов: Q1...Q4. Выборка команды и ее выполнение совмещены по времени таким образом, что выборка команды занимает один цикл, а выполнение – следующий цикл. Цикл выборки начинается с увеличения счетчика команд в такте Q1. В цикле выполнения команды выбранная команда защелкивается в регистр команд в такте Q1. В течение тактов Q2, Q3 и Q4 происходит декодирование и выполнение команды.
В такте Q2 считывается память данных (чтение операнда), а запись происходит в такте Q4.
Эффективное время выполнения команды составляет один цикл. Если команда изменяет счетчик команд (например, команда GOTO), то для ее выполнения потребуется два цикла, как показано в табл. 1.
1 movlw 5
2 movwf 0x0c
3 goto metka
4 movf 0x0d,0
5 metka movf 0x0e,0
Таблица 1
Номер цикла |
1 |
2 |
3 |
4 |
5 |
Загрузка |
Загрузка 1 |
Загрузка 2 |
Загрузка 3 |
Загрузка 4 |
Загрузка 5 |
Выполнение |
|
Выполнение 1 |
Выполнение 2 |
Выполнение 3 |
пропуск |
Таким образом, зная длительность машинного цикла, можно отсчитать время, затраченное на выполнение последовательности команд. Для организации временных задержек небольшой длительности можно вычислить количество команд, которые будут выполняться заданное время, и организовать цикл, повторяющийся найденное количество раз.
Модуль таймера-счетчика
Структура модуля таймера/счетчика TIMER0 рис. 3.
Рис. 3. Структурная схема таймера/счетчика TMR0
TIMER0 является программируемым модулем и содержит следующие компоненты:
§ 8-разрядный таймер/счетчик TMR0 с возможностью чтения и записи как регистр;
§ 8-разрядный программно управляемый предварительный делитель (предделитель);
§ мультиплексор входного сигнала для выбора внутреннего или внешнего тактового сигнала;
§ схему выбора фронта внешнего тактового сигнала;
§ формирователь запроса прерывания по переполнению регистра TMR0 с FFh до 00h.
Управление таймером-счетчиком осуществляется с помощью флагов регистра OPTION.
Регистр конфигурации (OPTION) является доступным по чтению и записи регистром, который содержит управляющие биты для конфигурации предварительного делителя (предделителя) и внешних прерываний, таймера. Назначение бит регистра приведено в табл. 2.
Назначение бит регистра OPTION
Таблица 2
№ |
Название |
Назначение |
бит равен 0 |
бит равен 1 |
7 |
/RBPU |
бит установки резисторов «pull-up» на выводах PORTB |
резисторы «pull-up» подключены |
резисторы «pull-up» отключены |
6 |
INTEDG |
бит выбора перехода сигнала прерывания |
прерывание по спаду сигнала на выводе RB0/INT |
прерывание по фронту сигнала на выводе RB0/INT |
5 |
T0CS |
бит выбора источника сигнала таймера TMR0 |
внутренний тактовый сигнал (CLKOUT) |
переход на выводе RA4/T0CKI |
4 |
T0SE |
бит выбора перехода источника сигнала для TMR0 |
приращение по фронту сигнала на выводе RA4/T0CKI |
приращение по спаду сигнала на выводе RA4/T0CKI |
3 |
PSA |
бит назначения предделителя |
предделитель подключен к TMR0 |
предделитель подключен к сторожевому таймеру |
2 |
PS2 |
биты выбора коэффициента деления предделителя |
Значения коэффициента деления предделителя при различных комбинациях значений этих бит приведено в табл. 3. |
|
1 |
PS1 |
|||
0 |
PS0 |
Таблица 3
Значения коэффициента деления предделителя при различных комбинациях значений бит PS2, PS1, PS0
Значения бит |
Предделитель TMR0 |
Предделитель WDT |
000 |
1:2 |
1:1 |
001 |
1:4 |
1:2 |
010 |
1:8 |
1:4 |
011 |
1:16 |
1:8 |
100 |
1:32 |
1:16 |
101 |
1:64 |
1:32 |
110 |
1:128 |
1:64 |
111 |
1:256 |
1:128 |
В том случае, когда предделитель обслуживает сторожевой таймер WDT, таймеру TMR0 назначается коэффициент предварительного деления 1:1.
Режим таймера выбирается путем сбрасывания в ноль бита T0CS регистра OPTION. В режиме таймера TMR0 инкрементируется каждый командный цикл (без предделителя). После записи информации в TMR0 инкрементирование его начнется после двух командных циклов. Это происходит со всеми командами, которые производят запись или чтение-модификацию-запись TMR0 (например, MOVF TMR0, CLRF TMR0). Избежать этого можно при помощи записи в TMR0 скорректированного значения. Если TMR0 нужно проверить на равенство нулю без останова счета, следует использовать инструкцию
MOVF TMR0,W
Режим счетчика выбирается путем установки в единицу бита T0CS регистра OPTION. В этом режиме регистр TMR0 будет инкрементироваться(увеличиваться на единицу) либо нарастающим, либо спадающим фронтом на выводе RA4/T0CKI от внешних событий. Направление фронта определяется управляющим битом T0SE в регистре OPTION. При T0SE = 0 будет выбран нарастающий фронт.
Предделитель может использоваться или совместно с TMR0, или со сторожевым (Watchdog) таймером. Вариант подключения делителя контролируется битом PSA регистра OPTION. При PSA=0 делитель будет подсоединен к TMR0. Содержимое делителя программе недоступно. Коэффициент деления предделителя программируется битами PS2…PS0 регистра OPTION.
Прерывание по TMR0 вырабатывается тогда, когда происходит переполнение регистра таймера/счетчика при переходе от FFh к 00h. Тогда устанавливается бит запроса T0IF в регистре INTCON. Данное прерывание можно замаскировать битом T0IE в регистре INTCON. Бит запроса T0IF должен быть сброшен программно при обработке прерывания. Прерывание по TMR0 не может вывести процессор из режима SLEEP потому, что таймер в этом режиме не функционирует.
При PSA=1 делитель будет подсоединен к сторожевому таймеру как постделитель (делитель на выходе). Возможные варианты использования предделителя показаны на рис. 4.
При использовании предделителя совместно с TMR0, все команды, изменяющие содержимое TMR0, обнуляют предделитель. Если предделитель используется совместно с WDT, команда CLRWDT обнуляет содержимое предделителя вместе с WDT.
При использовании модуля TIMER0 в режиме счетчика внешних событий необходимо учитывать то, что внешний тактовый сигнал синхронизируется внутренней частотой Fosc. Это приводит к появлению задержки во времени фактического инкрементирования содержимого TMR0.
Синхронизация происходит по окончании 2-го и 4-го тактов работы МК, поэтому, если предделитель не используется, то для фиксации входного события необходимо, чтобы длительности высокого и низкого состояний сигнала на входе RA4/T0CKI были бы не менее 2 периодов тактовой частоты Tosc плюс некоторая задержка ( ~ 20 нс).
Если модуль TIMER0 используется совместно с предделителем, то частота входного сигнала делится асинхронным счетчиком так, что сигнал на выходе предделителя становится симметричным. При этом необходимо, чтобы длительности высокого и низкого уровней сигнала на входе RA4/T0CKI были бы не менее 10 нс. Синхронизация сигнала происходит на выходе предделителя, поэтому существует небольшая задержка между фронтом внешнего сигнала и временем фактического инкремента таймера/счетчика. Эта задержка находится в диапазоне от 3 до 7 периодов колебаний тактового генератора. Таким образом, измерение интервала между событиями будет выполнено с точностью ±4 · Tosc.
Рис. 4. Схема работы таймера и сторожевого таймера с предделителем
3.2 Организация коротких временных задержек
Рассмотрим организацию коротких временных задержек с помощью таймера.
Пусть тактовая частота микроконтроллера f равна 10 МГц. Требуется организовать временную задержку 10 мс. Выполним необходимые расчеты.
Вычислим длительность одного такта.
,
тогда длительность машинного цикла, состоящего из четырех тактов
.
Вычислим количество машинных циклов, которые выполнятся за 10 мс:
.
Вычислим количество прерываний таймера за это количество машинных циклов. Так как прерывание таймера возникает через каждые 256 машинных циклов, поделим нацело количество машинных циклов на 256:
.
Вычислим оставшееся число машинных циклов:
.
Определим стартовое значение таймера так, чтобы прерывание произошло через 168 машинных циклов:
.
Таким образом, получается 97+1=98 прерываний таймера.
Определим состояние регистра OPTION так, чтобы переключиться на режим таймера:
/RBPU |
INTEDG |
T0CS |
T0SE |
PSA |
PS2 |
PS1 |
PS0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
Фрагмент программы, осуществляющий задержку на 10 мс
|
Bsf Status, rp0 |
; переключаемся в 1-й банк |
|
Bcf Option,TOCS |
; сбрасываем бит TOCS, чтобы включить таймер |
|
Bcf Status, rp0 |
; переключаемся в 0-й банк |
|
Movlw 98 |
; записываем число прерываний таймера |
|
Movwf 0x0c |
; в регистр-счетчик |
|
Movlw 88 |
; записываем стартовое значение |
|
Movwf TMR0 |
; в таймер |
L1 |
btfss intcon,TOIF |
; ожидаем прерывания таймера |
|
Goto l1 |
|
|
Bcf intcon, TOIF |
; сбрасываем флаг прерывания таймера |
|
Decfsz 0x0c,1 |
; отсчитываем прерывание таймера |
|
Goto l1 |
; возвращаемся на начало цикла |
3.3 Организация длительных временных задержек
При организации более длительных задержек количество прерываний таймера превосходит число 255 и не может храниться в регистре-счетчике прерываний. В этом случае целесообразно воспользоваться предделителем.
Пусть при той же тактовой частоте микроконтроллера требуется организовать временную задержку 320 мс.
;
.
Установим предделитель 1:32, тогда
;
;
;
.
Определим состояние регистра OPTION так, чтобы переключиться на режим таймера и установить перед ним предделитель 1:32:
/RBPU |
INTEDG |
T0CS |
T0SE |
PSA |
PS2 |
PS1 |
PS0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
Фрагмент программы, реализующий задержку 320 мс:
|
Bsf Status, rp0 |
; переключаемся в 1-й банк |
|
Movlw 0xd4 |
; записываем сформированный двоичный код |
|
movwf Option |
; в регистр Option |
|
Bcf Status, rp0 |
; переключаемся в 0-й банк |
|
Movlw 98 |
; записываем число прерываний таймера |
|
Movwf 0x0c |
; в регистр-счетчик |
|
Movlw 88 |
; записываем стартовое значение |
|
Movwf TMR0 |
; в таймер |
L1 |
btfss intcon,TOIF |
; ожидаем прерывания таймера |
|
Goto l1 |
|
|
Bcf intcon, TOIF |
; сбрасываем флаг прерывания таймера |
|
Decfsz 0x0c,1 |
; отсчитываем прерывание таймера |
|
Goto l1 |
; возвращаемся на начало цикла |
3.4 Задание на лабораторную работу № 7
Для измерения скорости используется диск с отверстием, при повороте которого на 3600 автомобиль проходит m см. При попадании света в отверстие происходит прерывание от 0-го бита PORTB. Вычислять и передавать в м/с скорость автомобиля на PORTA через каждые t мс, если тактовая частота процессора равна f.
Пример решения.
Пусть m=3 см, t=300 мс, f=10 МГц.
,
где n – число оборотов диска за 300 мс.
Вычислим длительность одного такта.
,
тогда длительность машинного цикла, состоящего из четырех тактов
.
Вычислим количество машинных циклов, которые выполнятся за 300 мс:
.
Вычислим количество прерываний таймера за это количество машинных циклов:
.
Так как число прерываний превышает 255, установим предделитель. Определим минимально необходимый масштаб предделителя:
.
Выбираем ближайший масштаб – 1:16. Тогда
,
,
,
.
Таким образом, количество прерываний 184, стартовое значение таймера равно 229.
Определим состояние регистра OPTION так, чтобы переключиться на режим таймера и установить перед ним предделитель 1:16:
/RBPU |
INTEDG |
T0CS |
T0SE |
PSA |
PS2 |
PS1 |
PS0 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
Пример программы
|
Npr equ 0x0d |
|
|
N equ 0x0c |
|
|
temp equ 0x0e |
|
|
a equ 0x0f |
|
|
count equ 0x10 |
|
|
rez equ 0x11 |
|
|
Org 0 |
; по адресу 0 делаем переход |
|
Goto Start |
; на начало программы |
|
Org 4 |
; по адресу 4 делаем переход на процедуру |
|
Goto Inter |
; обработки прерываний |
Start |
Bsf status, rp0 |
; переключаемся в банк 1 |
|
Clrf porta |
; настраиваем porta на выход |
|
Movlw 0xd3 |
; настраиваем option на режим таймера |
|
Movwf option |
; с предделителем 1:16 |
|
Bcf status, rp0 |
; переключаемся в банк 0 |
|
Clrf n |
; обнуляем счетчик оборотов |
|
Movlw 184 |
; записываем число прерываний |
|
Movwf npr |
; в счетчик прерываний |
|
Movlw 229 |
; записываем стартовое значение таймера |
|
Movwf tmr0 |
; в tmr0 |
|
Bsf intcon,toie |
; разрешаем прерывания от таймера |
|
Bsf intcon,inte |
; разрешаем прерывания от бита 0 |
|
Bsf intcon, gie |
; снимаем маску со всех прерываний |
L0 |
goto L0 |
; организуем бесконечный цикл |
Inter |
btfsc intcon,intf |
; если прерывание от 0 бита |
|
Call Count_s |
; вызываем процедуру Count_s |
|
Btfsc intcon,toif |
; если прерывание от таймера |
|
Call Count_time |
; вызываем процедуру Count_time |
|
Retfie |
; возврат из процедуры обработки прерываний |
Count_s |
bsf intcon, intf |
; сбрасываем флаг прерывания от 0 бита |
|
Incf n,1 |
; увеличиваем на 1 счетчик оборотов диска |
|
return |
; возврат из процедуры |
Count_time |
bcf intcon, toif |
; сбрасываем флаг прерывания от таймера |
|
Decfsz npr,1 |
; отсчитываем прерывание |
|
Goto End_count |
; если еще не все, переходим на конец процедуры |
|
Call div |
; в противном случае вычисляем скорость |
|
Movf rez,0 |
; пересылаем значение скорости |
|
Movwf porta |
; в porta |
|
Clrf n |
; обнуляем счетчик оборотов |
|
Movlw 184 |
; записываем число прерываний |
|
Movwf npr |
; в счетчик прерываний |
|
Movlw 229 |
; записываем стартовое значение таймера |
|
Movwf tmr0 |
; в tmr0 |
End_count |
return |
; возврат из процедуры |
Div |
movlw 10 |
; процедура деления n на 10 |
|
Movwf temp |
; записали делитель в temp |
|
Clrf a |
; обнулили вспомогательный регистр |
|
Clrf rez |
Обнулили регистр результата |
|
Movlw 8 |
; готовим цикл из 8 шагов (по числу бит) |
|
Movwf count |
; count – счетчик цикла |
L1 |
rlf n,1 |
; сдвигаем влево n |
|
Rlf a,1 |
; сдвигаем влево а ( перенос старшего разряда) |
|
Rlf rez,1 |
; сдвигаем влево регистр результата |
|
Movf temp,0 |
; вычитаем 10 |
|
Subwf a,0 |
; из вспомогательного регистра |
|
Btfss status,c |
; если результат меньше 0 |
|
Goto L2 |
; переходим на L2 |
|
Bsf rez,0 |
; в противном случае устанавливаем 0-й бит |
|
Movwf a |
; результат вычитания записываем в а |
L2 |
Decfsz count,1 |
; отсчитываем шаг цикла |
|
Goto L1 |
; если не 0, переходим на начало цикла |
В случае, если при вычислении скорости требуется не только деление, но и умножение, применяется следующая процедура двоичного умножения (множители находятся в регистрах op1 и op2, а результат – в регистрах h и l):
Пример программы умножения двух 8-разрядных чисел
|
Mult Clrf h |
; очистили старшую часть результата |
|
Clrf l |
; очистили младшую часть результата |
|
Movlw 8 |
; подготовили цикл |
|
Movwf count |
; из 8 шагов |
|
Movf op1, 0 |
; записали в аккумулятор первый операнд |
L1 |
btfsc op2, 0 |
; если 0-й бит 2-го операнда не 0 |
|
Addwf h, 1 |
; добавили первый операнд к старшей части результата |
|
Rrf h, 1 |
; сдвинули вправо старшую часть результата |
|
Rrf l, 1 |
; сдвинули вправо младшую часть результата |
|
Rrf op2, 1 |
; сдвинули вправо второй множитель |
|
Bcf status, c |
; сбросили флаг переноса |
|
Decfsz count, 1 |
; если не конец цикла |
|
Goto L1 |
; вернулись на начало |
3.5 Варианты заданий
Вариант |
f(МГц) |
t(мс) |
m(см) |
1 |
4 |
100 |
3 |
2 |
8 |
400 |
8 |
3 |
10 |
500 |
5 |
4 |
16 |
200 |
7 |
5 |
1 |
120 |
9 |
6 |
20 |
1500 |
2 |
7 |
2 |
300 |
4 |
8 |
12 |
1000 |
10 |
9 |
5 |
900 |
6 |
10 |
4 |
700 |
10 |
11 |
8 |
1100 |
2 |
12 |
10 |
800 |
5 |
13 |
16 |
1300 |
7 |
14 |
1 |
600 |
4 |
15 |
20 |
1100 |
8 |
16 |
2 |
180 |
9 |
17 |
12 |
1600 |
3 |
18 |
5 |
700 |
10 |
19 |
4 |
850 |
6 |
20 |
8 |
1250 |
7 |
21 |
10 |
750 |
8 |
22 |
16 |
1050 |
5 |
23 |
1 |
150 |
4 |
24 |
20 |
1700 |
3 |
25 |
2 |
600 |
9 |
26 |
12 |
900 |
7 |
27 |
5 |
400 |
6 |
28 |
4 |
500 |
11 |
Скачано с www.znanio.ru
Материалы на данной страницы взяты из открытых источников либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.