что такое прерывание в микроконтроллере

Прерывания

Прерывание (interrupt) – событие, требующие немедленной реакции со стороны процессора. Реакция состоит в том, что процессор прерывает обработку текущей программы ( прерываемой программы ) и переходит к выполнению некоторой другой программы ( прерывающей программы ), специально предназначенной для данного события. По завершении этой программы процессор возвращается к выполнению прерванной программы.

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

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

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

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере
tp – время реакции системы на прерывание;
tз – время запоминания состояния прерываемой программы;
tппр – время собственно прерывающей программы;
tв – время восстановления состояния прерванной программы

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Характеристиками системы прерывания являются:

Источник

Прерывание микроконтроллеров AVR

Прерывание микроконтроллеров AVR это специальный сигнал который говорит нам о том что произошло какое либо событие. К примеру если у нас переполнился счетчик у таймера, или аналого-цифровой преобразователь (АЦП) завершил свое преобразование, или на внешнем выводе МК появилось напряжение. Все это примеры некоторых прерываний, при наступлении такого события у нас прерывается выполнение последовательности команд, и управление передается обработчику прерываний, т. е. начинается выполнение другой последовательности команд. После выполнения команд прерывания управление передается в прерванный код.

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

Ниже представлена таблица возможных прерываний микроконтроллера ATmega16.

АдресИсточникОписание прерывания
2$0004INT1Внешнее прерывание 1
3$0006TIMER2 COMPСовпадение таймера/счетчика Т2
4$0008TIMER2 OVFПереполнение таймера/счетчика Т2
5$000ATIMER1 CAPTЗахват таймера/счетчика Т1
6$000CTIMER1 COMPAСовпадение «А» таймера/счетчика Т1
7$000ETIMER1 COMPBСовпадение «В» таймера/счетчика Т1
8$0010TIMER1OVFПереполнение таймера/счетчика Т1
9$0012TIMER0OVFПереполнение таймера/счетчика Т0
10$0014SPI, STCПередача по SPI завершена
11$0016USART,RXCUSART, прием завершен
12$0018USART,UDREРегистр данных USART пуст
13$001AUSART,TXCUSART, передача завершена
14$001CADCПреобразование АЦП завершено
15$001EEE_RDYEEPROM, готово
16$0020ANA_COMPАналоговый компаратор
17$0022TWIПрерывание от модуля TWI
18$0024INT2Внешнее прерывание 2
19$0026TIMER0 COMPСовпадение таймера/счетчика Т0
20$0028SPM_RDYГотовность SPM

Давайте рассмотрим внешние прерывание, у микроконтроллера ATmega16 есть 3 внешних прерывания:

Эти прерывания привязан к ножкам PD2,PD3, и PB2. Настроить эти прерывания на другие вывод нельзя, нужно использовать только эти.

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

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Для того чтобы разрешить прерывание на соответствующем выводе нужно установить состояние битов INT1, INT0, INT2.

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

Внешнее прерывание может случиться при наступлении следующего условия:

Для понимания низкого, высокого, нарастающего и спадающего фронта сигнала вот вам картинка.

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Установка прерывания на определенное условие срабатывание производится путем настройки регистра MCUCR для INT0 и INT1 и MCUCRS для INT2.

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Для того чтобы нам настроить прерывания INT0 на определенное условие срабатывание нам нужно записать следующие значения в управляющие разряды ISC01, ISC00.

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Настройки INT1 осуществляется аналогичным образом, только управляющие разряды ISC11, ISC10.
С прерыванием INT2 дела обстоят несколько иначе, для его настройки можно использовать только один бит — ISC2 который находиться в регистре MCUCS

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Нужно помнить, что в случае смены значения бита ISC2 может произойти прерывание INT2. Для того чтобы этого не случилось, следует осуществить изменение бита ISC2 следующим образом:
запретить внешнее прерывание > изменить значение бита ISC2 > произвести сброс флага прерывания (INTF2) > и далее опять разрешить прерывание INT2.

Идентификация или регистрация фронта сигнала на выводах INT0/INT1 происходит синхронно, т. е. синхронно с сигналом тактового генератора. Наименьшее значение продолжительности входного сигнала, которое обеспечит генерацию прерывания равно значение периода тактового сигнала генератора МК.

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

Обнаружение перепадов сигнала на выводе INT2 также происходит асинхронно. При это наименьшее значение длительности импульса, при которой гарантированно произойдет прерывание равно 50 нс. Внешние прерывание которые обнаруживаются асинхронно, можно использовать для того чтобы выводить МК из «спящего» режима — 6 состояний МК при котором у нас пониженное энергопотребление.

Помимо перечисленных выше регистров нам также понадобиться статусный регистр GIFR. В данном статусном регистре имеются флаги которые автоматически устанавливаются в случае формирования запроса на внешнее прерывание. Т.е. флаги сбрасываются аппаратно, когда вызывается обработчик прерывания. Их также можно сбросить программно, записав в данные регистр «1». Сброс регистра осуществляется перезаписью регистра GIFR,а не операцией «или».

Источник

Что такое прерывание в микроконтроллере

Задача: заставить микроконтроллер по нажатию кнопки издавать звуковой сигнал.
Схема для нашего примера здесь. Файлы проекта здесь.

Создаем в старом workspace проект ring.
Задаем настройки проекта для конфигурации Release:

Выбираем тип микроконтроллера.
General Options > Target > Processor configuration
У меня это ATmega8535.

Разрешаем использование имен битов определенных в хидер файле
В General Options > System ставим галочку Enable bit definitions in I/O-Include files
До сих пор мы не пользовались именами битов, но сегодня они нам понадобятся.

Меняем тип выходного файла.
Linker > Output.
B поле Output file cтавим галочку Override default и заменяем расширение d90 на hex
В поле Format выбираем Other и в выпадающем меню Output format выбираем тип файла intel-standart

Сохраняем проект и workspace.

______________________________ Прерывание ___________________________

Во-вторых:
— вы вполне могли бы послать начальника и никуда не идти
— уйдя за осциллографами, вы могли задержаться там надолго, а то и вовсе не вернуться
— вернувшись на рабочее место, вы могли бы уже позабыть свои гениальные идеи

_______________________________________________________________

Теперь о программе. Построчно писать программу уже не получится, поэтому я сразу приведу ее текст. Ниже мы последовательно разберем все ее строки, и все станет понятно. Макросы я намеренно не стал использовать, программа маленькая, не хочется ее загромождать.

//Подаем голос микроконтроллером AVR
#include
#include

int main( void )
<
//настраиваем порты ввода-вывода
DDRD = (0
TCCR0 = (1 //разрешаем прерывания
__enable_interrupt();

//основной цикл программы – опрос кнопки
while (1) <
if ((PIND & (1 else
TIMSK = 0;
>
return 0;
>

//обработчик прерывания таймера Т0
#pragma vector = TIMER0_COMP_vect
__interrupt void Timer0CompVect( void )
<
PORTD ^= (1
>

Настройка портов

DDRD = (0 __enable_interrupt();

Опрос кнопки

Не забывайте == это не оператор присваивания =.

Обработка нажатия/отпускания кнопки

TIMSK = (1 // разрешаем прерывание таймера Т0 по событию совпадение

TIMSK = 0; //запрещаем прерывание

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

Функция прерывания

_____________________ Cинтаксис функции прерывания _____________________

Функция прерывания задается с помощью директивы #pragma vector= и служебного слова __interrupt. Функция должна иметь тип void и не должна принимать никаких параметров.

#pragma vector = Address
__interrupt void Name( void )
<
//здесь располагается наш код
>

Name – имя функции, выбираем на наше усмотрение
Address – адрес вектора прерывания, можно задавать числом, можно именами определенными в заголовочном файле микроконтроллера (iom8535.h – раздел Interrupt Vector Definitions)

______________________________________________________________

Для нашей задачи функция-обработчик прерывания выглядит так

#pragma vector = TIMER0_COMP_vect
__interrupt void Timer0CompVect( void )
<
PORTD ^= (1
>

Ну вот собственно и все. Надеюсь все понятно.
В следующий статье заставим микроконтроллер играть мелодию.

Источник

Прерывания

Прерывания – это специальный механизм, позволяющий остановить выполнение основной программы и переключить процессор на выполнение другой задачи по определенному внешнему или внутреннему событию. Фактически прерывания являются обыкновенными подпрограммами, которые в тот или иной момент времени микропроцессор может вызывать аппаратно. Такие подпрограммы принято называть обработчиками прерываний.

В большинстве случаев прерывания позволяют очень сильно разгрузить ЦПУ от той работы, которую самостоятельно могут выполнять отдельные его модули. Например, любой таймер-счетчик, отсчитав необходимое число тактов генератора, может сгенерировать прерывание и вызвать подпрограмму, в которой будет находиться код для отчета различных временных интервалов. Точно таким же образом при наступлении определенного события (отсылка или прием слова данных, изменение состояния на линии и мн. др.) способны оповещать процессор модули USART, SPI, TWI, ADC и т.д. Различные модели AVR могут содержать от 4 до 56 таких источников прерываний.

Табл.5. Таблица векторов прерываний:

Номер

Адрес в памяти программ

Бит разрешение прерывания

Флаг прерывания

Описание события

Внешнее прерывание 0

Внешнее прерывание 1

Cовпадение TCNT2 и OCR2

Совпадение TCNT1 и OCR1A

Совпадение TCNT1 и OCR1B

Прерывание от модуля SPI

Получение байта по USART

Опустошение UDR в USART

Передача байта по USART

Завершение записи в EEPROM

Прерывание от компаратора

Прерывание от модуля TWI

Завершение выполнения spm

За каждым обработчиком прерывания жестко закреплен определенный адрес (вектор прерывания) в начале памяти программ. Положения векторов прерываний для ATmega8 сведены табл.5. Обычно по адресу вектора прерывания находится инструкция перехода, которая передает управление подпрограмме обработчика:

В моделях AVR с объемом FLASH ≤8 кбайт, для векторов отводится по 1 слову памяти программ, как раз для инструкций rjmp. Во всех остальных микроконтроллерах каждый вектор прерывания занимает уже 2 слова, а в качестве инструкции перехода используются jmp.

Управление прерываниями производится индивидуально. За разрешение каждого из них отвечают специальные разряды соответствующих РВВ, а о наступлении события микроконтроллер может судить по состоянию флагов прерывания (см. табл.5). Например, если прерывание по переполнению таймера-счетчика 2 разрешено (установлен бит TOIE2 из TIMSK), то при изменении содержимого счетного регистра TCNT2 c 0xFF на 0x00 в регистре TIFR аппаратно будет установлен флаг прерывания TOV2 и микроконтроллер вызовет подпрограмму по адресу 0x0004.

За общее управление прерываний у AVR отвечает флаг I из регистра SREG. При I=0 все прерывания, независимо от состояния битов разрешения, запрещены.

При вызове обработчика прерывания адрес текущей команды в основной программе копируется в стек, как и при обычном вызове подпрограммы. Но вместе с этим микроконтроллер аппаратно сбрасывает на нуль флаг I и флаг, который явился источником прерывания. Обработчик должен заканчиваться командой возврата из прерывания reti. После ее выполнения адрес возврата восстанавливается в PC и при этом одновременно устанавливается флаг I.

Ниже рассмотрен пример использования обработчика внешнего прерывания INT0.

Инструкция перехода, размещенная по нулевому адресу (вектор сброса у всех моделей AVR), передает управление на начало основной программы main, где и происходит инициализация микроконтроллера. В качестве условия возникновения прерывания выбрано изменение состояния вывода INT0 с уровня лог.1 на лог.0 (момент нажатия кнопки). При возникновении указанного события произойдет вызов подпрограммы по адресу 0x0001 (вектор прерывания INT0) и, далее, обработчика service_INT0. В обработчике нужно сохранить содержимое SREG и, если это необходимо, остальных регистров, которые используются в контексте основной программы.

Возможна такая ситуация, что в процессе работы одновременно возникнут сразу несколько запросов на прерывания (одновременно будут установлены несколько флагов прерывания). В этом случае первым будет вызван тот обработчик, чей адрес в таблице векторов прерывания находится выше. Например, при возникновении запросов от АЦП (адрес 0x000E) и компаратора (адрес 0x0010), первым будет обработан запрос от АЦП. Таким образом, каждое прерывание у AVR имеет свой собственный неизменный приоритет, который зависит от его местоположением в таблице векторов.

Здесь возможны две проблемы. Во-первых, обработка отдельных прерываний может быть достаточно длительной процедурой и другие запросы окажутся отложенными на недопустимо большой срок. А во-вторых, прерывание с низким приоритетом может иметь намного большее значение для данного устройства. В обоих случаях можно выйти из положения, если допустить в программе вложенные прерывания. Для этого после сохранения контекста в обработчике прерывания нужно вручную установить флаг I командой sei:

Вложенные прерывания могут оказаться недопустимыми при малом размере стека.

Перейти к следующей части: Порты ввода-вывода

Источник

AVR Урок 10. Таймеры-счетчики. Прерывания

Урок 10

Таймеры-счетчики. Прерывания

Сегодня мы узнаем, что такое таймеры-счётчики в микроконтроллерах и для чего они нужны, а также что такое прерывания и для чего они тоже нужны.

Таймеры-счётчики – это такие устройства или модули в микроконтроллере, которые, как видно из названия, постоянно что-то считают. Считают они либо до определённой величины, либо до такой величины, сколько они битности. Считают они постоянно с одной скоростью, со скоростью тактовой частоты микроконтроллера, поправленной на делители частоты, которые мы будем конфигурировать в определённых регистрах.

И вот эти таймеры-счётчики постоянно считают, если мы их инициализируем.

Таймеров в МК Atmega8 три.

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Два из них – это восьмибитные таймеры, то есть такие, которые могут максимально досчитать только до 255. Данной величины нам будет маловато. Даже если мы применим максимальный делитель частоты, то мы не то что секунду не отсчитаем, мы даже полсекунды не сможем посчитать. А у нас задача именно такая, чтобы досчитывать до 1 секунды, чтобы управлять наращиванием счёта светодиодного индикатора. Можно конечно применить ещё наращивание переменной до определенной величины, но хотелось бы полностью аппаратного счёта.

Но есть ещё один таймер – это полноправный 16-битный таймер. Он не только 16-битный, но есть в нём ещё определённые прелести, которых нет у других таймеров. С данными опциями мы познакомимся позже.

Вот этот 16-битный таймер мы и будем сегодня изучать и использовать. Также, познакомившись с данным таймером, вам ничего не будет стоить самостоятельно изучить работу двух других, так как они значительно проще. Но тем не менее 8-битные таймеры в дальнейшем мы также будем рассматривать, так как для достижения более сложных задач нам одного таймера будет недостаточно.

Теперь коротко о прерываниях.

Прерывания (Interrupts) – это такие механизмы, которые прерывают код в зависимости от определённых условий или определённой обстановки, которые будут диктовать некоторые устройства, модули и шины, находящиеся в микроконтроллере.

В нашем контроллере Atmega8 существует 19 видов прерываний. Вот они все находятся в таблице в технической документации на контроллер

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Какого типа могут быть условия? В нашем случае, например, досчитал таймер до определённой величины, либо например в какую-нибудь шину пришёл байт и другие условия.

На данный момент мы будем обрабатывать прерывание, которое находится в таблице, размещённой выше на 7 позиции – TIMER1 COMPA, вызываемое по адресу 0x006.

Теперь давайте рассмотрим наш 16-битный таймер или TIMER1.

Вот его структурная схема

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Мы видим там регистр TCNTn, в котором постоянно меняется число, то есть оно постоянно наращивается. Практически это и есть счётчик. То есть данный регистр и хранит число, до которого и досчитал таймер.

А в регистры OCRnA и OCRnB (буквы n – это номер таймера, в нашем случае будет 1) – это регистры, в которые мы заносим число, с которым будет сравниваться чило в регистре TCNTn.

Например, занесли мы какое-нибудь число в регистр OCRnA и как только данное число совпало со значением в регистре счёта, то возникнет прерывание и мы его сможем обработать. Таймеры с прерываниями очень похожи на обычную задержку в коде, только когда мы находимся в задержке, то мы в это время не можем выполнять никакой код (ну опять же образно «мы», на самом деле АЛУ). А когда считает таймер, то весь код нашей программы в это время спокойно выполняется. Так что мы выигрываем колоссально, не давая простаивать огромным ресурсам контроллера по секунде или даже по полсекунды. В это время мы можем обрабатывать нажатия кнопок, которые мы также можем обрабатывать в таймере и многое другое.

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

Также у таймера существует несколько режимов, с которыми мы также познакомимся немного позденее.

Он состоит из двух половинок, так как у нас конотроллер 8-битный и в нем не может быть 16-битных регистров. Поэтому в одной половинке регистра (а физически в одном регистре) хранится старшая часть регистра, а в другом – младшая. Можно также назвать это регистровой парой, состоящей из двух отдельных регистров TCCR1A и TCCR1B. Цифра 1 означает то, что регистр принадлежит именно таймеру 1.

Даный регист TCCR отвечает за установку делителя, чтобы таймер не так быстро считал, также он отвечает (вернее его определённые биты) за установку определённого режима.

За установку режима отвечают биты WGM

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Мы видим здесь очень много разновидностей режимов.

Normal – это обычный режим, таймер считает до конца.

PWM – это ШИМ только разные разновидности, то есть таймер может играть роль широтно-импульсного модулятора. С данной технологией мы будем знакомиться в более поздних занятиях.

CTC – это сброс по совпадению, как раз то что нам будет нужно. Здесь то и сравнивются регистры TCNT и OCR. Таких режима два, нам нужен первый, второй работает с другим регистром.

Все разновидности режимов мы в данном занятии изучать не будем. Когда нам эти режимы потребуются, тогда и разберёмся.

Ну давайте не будем томить себя документацией и наконец-то попробуем что-то в какие-нибудь регистры занести.

Код, как всегда, был создан из прошлого проекта. Для протеуса также код был скопирован и переименован с прошлого занятия, также в свойствах контроллера был указан путь к новой прошивке. Проекты мы назовем Test07.

Попробуем как всегда скомпилировать код и запустить его в протеусе. Если всё нормально работает, то начинаем добавлять новый код.

Добавим ещё одну функцию, благо добавлять функции мы на прошлом занятии научились. Код функции разместим после функции segchar и до функции main. После из-за того, что мы будем внутри нашей новой функции вызывать функцию segchar.

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

Поэтому первую функцию мы назвовём timer_ini

void timer_ini ( void )

Также давайте наши функции, а также какие-то законченные блоки с объявлением глобальных переменных, с прототипами функций будем отделять друг от друга вот такими чёрточками, которые за счет наличия двух слешей впереди компилятор обрабатывать не будет и примет их за комментарии. За счёт этих отчерчиваний мы будем видеть, где заканчивается одна функция и начинается другая.

Данная функция, как мы видим не имеет ни каких аргументов – ни входных, не возвращаемых. Давайте сразу данную функцию вызовем в функции main()

unsigned char butcount=0, butstate=0;

timer_ini ();

Теперь мы данную функцию начнём потихонечку наполнять кодом.

Начнем с регистра управления таймером, например с TCCR1B. Используя нашу любимую операцию «ИЛИ», мы в определённый бит регистра занесём единичку

void timer_ini ( void )

TCCR1B |= (1 WGM12 ); // устанавливаем режим СТС (сброс по совпадению)

Из комментария мы видим, что мы работает с битами режима, и установим мы из них только бит WGM12, остальные оставим нули. Исходя из этого мы сконфигурировали вот такой режим:

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Также у таймера существует ещё вот такой регистр – TIMSK. Данный регистр отвечает за маски прерываний – Interrupt Mask. Доступен данный регистр для всех таймеров, не только для первого, он общий. В данном регистре мы установим бит OCIE1A, который включит нужный нам тип прерывания TIMER1 COMPA

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

TCCR1B |= (1 WGM12 ); // устанавливаем режим СТС (сброс по совпадению)

TIMSK |= (1 OCIE1A ); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)

Теперь давайте поиграемся с самими регистрами сравнения OCR1A(H и L). Для этого придётся немного посчитать. Регистр OCR1AH хранит старшую часть числа для сравнения, а регистр OCR1AL – младшую.

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

TIMSK |= (1 OCIE1A ); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)

OCR1AH = 0b10000000; //записываем в регистр число для сравнения

OCR1AL = 0b00000000;

TCCR1B |= ( ); //установим делитель.

Пока никакой делитель не устанавливаем, так как мы его ещё не посчитали. Давайте мы этим и займёмся.

Пока у нас в регистре OCR1A находится число 0b1000000000000000, что соответствует десятичному числу 32768.

Микроконтроллер у нас работает, как мы договорились, на частоте 8000000 Гц.

Разделим 8000000 на 32768, получим приблизительно 244,14. Вот с такой частотой в герцах и будет работать наш таймер, если мы не применим делитель. То есть цифры наши будут меняться 244 раза в секунду, поэтому мы их даже не увидим. Поэтому нужно будет применить делитель частоты таймера. Выберем делитель на 256. Он нам как раз подойдёт, а ровно до 1 Гц мы скорректируем затем числом сравнения.

Вот какие существуют делители для 1 таймера

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Я выделил в таблице требуемый нам делитель. Мы видим, что нам требуется установить только бит CS12.

Так как делитель частоты у нас 256, то на этот делитель мы поделим 8000000, получится 31250, вот такое вот мы и должны занести число в TCNT. До такого числа и будет считать наш таймер, чтобы досчитать до 1 секунды. Число 31250 – это в двоичном представлении 0b0111101000010010. Занесём данное число в регистровую пару, и также применим делитель

OCR1AH = 0b01111010; //записываем в регистр число для сравнения

OCR1AL = 0b00010010;

TCCR1B |= (1 CS12 ); //установим делитель.

С данной функцией всё.

Теперь следующая функция – обработчик прерывания от таймера по совпадению. Пишется она вот так

ISR ( TIMER1_COMPA_vect )

И тело этой функции будет выполняться само по факту наступления совпадения чисел.

Нам нужна будет переменная. Объявим её глобально, в начале файла

unsigned char i ;

Соответственно, из кода в функции main() мы такую же переменную уберём

Также закомментируем весь код в бесконечном цикле. Его роль теперь у нас будет выполнять таймер, и, я думаю, он с этим справится не хуже, а даже лучше, «никому» при этом не мешая.

while (1)

// for(i=0;i

// while (butstate==0)

// if (!(PINB&0b00000001))

// if(butcount

// butcount++;

// else

// butstate=1;

// else

// if(butcount > 0)

// butcount–;

// else

// butstate=1;

// segchar(i);

// _delay_ms(500);

// butstate=0;

Теперь, собственно, тело функции-обработчика. Здесь мы будем вызывать функцию segchar. Затем будем наращивать на 1 переменную i. И чтобы она не ушла за пределы однозначного числа, будем её обнулять при данном условии

if ( i >9) i =0;

segchar ( i );

Теперь немного исправим код вначале функции main(). Порт D, отвечающий за состояние сегментов, забьём единичками, чтобы при включении у нас не светился индикатор, так как он с общим анодом. Затем мы здесь занесём число 0 в глобавльную переменную i, просто для порядка. Вообще, как правило, при старте в неициализированных переменных и так всегда нули. Но мы всё же проинициализируем её. И, самое главное, чтобы прерывание от таймера работало, её недостаточно включить в инициализации таймера. Также вообще для работы всех прерываний необходимо разрешить глобальные прерывания. Для этого существует специальная функция sei() – Set Interrupt.

Теперь код будет вот таким

PORTD = 0b11111111;

sei ();

Также ещё мы обязаны подключить файл библиотеки прерываний вначале файла

Также переменные для кнопки нам пока не потребуются, так как с кнопкой мы сегодня работать не будем. Закомментируем их

//unsigned char butcount=0, butstate=0;

Соберём наш код и проверим его работоспособность сначала в протеусе. Если всё нормально работает, то проверим также в живой схеме

что такое прерывание в микроконтроллере. Смотреть фото что такое прерывание в микроконтроллере. Смотреть картинку что такое прерывание в микроконтроллере. Картинка про что такое прерывание в микроконтроллере. Фото что такое прерывание в микроконтроллере

Всё у нас работает. Отлично!

Вот такой вот получился секундомер. Но так как у нас даже нет кварцевого резонатора, то данный секундомер нельзя назвать точным.

Тем не менее сегодня мы с вами много чему научились. Мы узнали о прерываниях, также научились их обрабатывать, Научились работать с таймерами, конфигурировать несколько новых регистров микроконтроллера, до этого мы работали только с регистрами портов. Также за счёт всего этого мы значительно разгрузили арифметическо-логическое устройство нашего микроконтроллера.

Купить программатор можно здесь (продавец надёжный) USBASP USBISP 2.0

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *