Вы находитесь на странице: 1из 19

Лекция 6

Контроллер прерываний и
EEPROM

Олег Непомнящий
План лекции
1. Основные термины
2. Вектора прерываний ATMega32(L)
3. Организация системы прерываний
4. Внешние прерывания ATMega32(L)
5. Биты и регистры для управления прерываниями ATMega32(L)
6. Пример внешнего обработчика прерывания
7. Управление EEPROM.
8. Регистры EEPROM.
9. Пример обработчика EEPROM.

2
Основные термины
• Прерывание в однокристальной системе – это прерывание по внешнему
сигналу или по внутреннему сигналу от встроенного периферийного
контроллера (таймера, АЦП и пр.) оно обрабатывается подпрограммой
расположенной по строго фиксированному адресу.
• Вектор прерывания – код команды безусловного перехода (RJMP) и адрес
подпрограммы обработки прерывания, которая вызывается автоматически
при запросе извне или от внутреннего контроллера.. Для автоматического
вызова адреса этих векторов определены заводом-изготовителем для
каждого микроконтроллера, являются неизменными и сведены в таблицу
векторов прерываний которая размещается во FLASH – ПЗУ программ
начиная с адреса 0
• EEPROM (электрически стираемая программируемая постоянная память) -
это изменяемая пользователем постоянная память, которую можно стирать
и перепрограммировать многократно посредством приложения более
высокого, чем обычно, электрического напряжения.

3
Таблица векторов прерываний ATMega32(L)
• Address Labels Code Comments
• 0x0000 rjmp RESET ; Reset Handler
• 0x0002 rjmp EXT_INT0 ; IRQ0 Handler
• 0x0004 rjmp EXT_INT1 ; IRQ1 Handler
• 0x0006 rjmp EXT_INT2 ; IRQ2 Handler
• 0x0008 rjmp TIM2_COMP ; Timer2 Compare Handler
• 0x000A rjmp TIM2_OVF ; Timer2 Overflow Handler
• 0x000C rjmp TIM1_CAPT ; Timer1 Capture Handler
• 0x000E rjmp TIM1_COMPA ; Timer1 Compare A Handler
• 0x0010 rjmp TIM1_COMPB ; Timer1 Compare B Handler
• 0x0012 rjmp TIM1_OVF ; Timer1 Overflow Handler
• 0x0014 rjmp TIM0_OVF ; Timer0 Compare Handler
• 0x0016 rjmp TIM0_OVF ; Timer0 Overflow Handler
• 0x0018 rjmp SPI_STC ; SPI Transfer Complete Handler
• 0x001A rjmp USART_RXC ; USART RX Complete Handler
• 0x001C rjmp USART_UDRE ; UDR Empty Handler
• 0x001E rjmp USART_TXC ; USART TX Complete Handler
• 0x0020 rjmp ADC ; ADC Conversion Complete Handler
• 0x0022 rjmp EE_RDY ; EEPROM Ready Handler
• 0x0024 rjmp ACIaddr ; Analog Comparator
• 0x0026 rjmp TWIaddr ; 2-wire Serial Interface
• 0x0028 rjmp SPMRaddr ; Store Program Memory Ready 4
Организация системы прерываний
• Прерывания позволяют вам организовывать
запланированные события. Например, когда телефон
звонит, вы можете: 1. проигнорировать его, 2.
ответить или 3. перезвонить позже.
• В микроконтроллерах и системах на кристалле это
делается с помощью маски прерывания - бита I
(прерывание) в регистре состояния, например в SREG
для Atmel. Этот бит автоматически сбрасывается при
входе в прерывание, тем самым устраняя
возможность вложенных прерываний, которые могут
привести к переполнению стека, поскольку адрес
возврата (текущий счетчик программы)
автоматически сохраняется в стеке. Но этот бит
можно установить, то есть разрешить одно
вложенное прерывание.

5
Внешние прерывания ATMega32(L)
Для обработки прерываний нам понадобится:
1. Включить или выключить все прерывания. Это делается
установкой в 1 или сбросом в 0 флага I в регистре ldi r16,high(RAMEND)
состояния GREG командами SEI и CLI. out SPH,r16
ldi r16,low(RAMEND)
2. Настроить стек. Поскольку стек этого микроконтроллера out SPL,r16
«растет» снизу вверх, мы рекомендуем установить sei ; Enable interrupts
указатель стека на самый последний адрес в ОЗУ – он
имеет собственное имя RAMEND.
3. Настроить контроллер прерываний через регистр
управления GICR (General Interrupt Control Register) и
настроить процессор через регистр управления
процессором MCUCR (MCU Control register).
В лабораторном стенде кнопки 2 и 3 порта D подключены
к прерываниям (Int0 и int1 соответственно).
Вы можете отслеживать прерывания на программном
уровне через GIFT (General Interrupt Flag Register). 6
Регистры и биты управления прерыванием ATmega32

Регистр управления контроллером прерываний


General Interrupt Control Register
GICR
Bit 7 — INT1, external interrupt mask INT1;
Bit 6 — INT0, external interrupt mask INT0;
Bit 5 — INT2, external interrupt mask INT2;
Bit 1 — IVSEL (Interrupt Vector Select);
Bit 0 — IVCE (Interrupt Vector Change Enable).

INT1 INT0 INT2 - - - IVSEL IVCE

7 0
7
Регистры и биты управления прерыванием ATmega32

Регистр управления процессором


MCU Control register
MCUCR
Bit 7 — SM2 (Sleep Mode bit 2); Bit 3 — ISC11 (Interrupt Control 1 bit 1);
Bit 6 — SE (Sleep Enable); Bit 2 — ISC10 (Interrupt Control 1 bit 0);
Bit 5 — SM1 (Sleep Mode bit 1); Bit 1 — ISC01 (Interrupt Control 0 bit 1);
Bit 4 — SM0 (Sleep Mode bit 0); Bit 0 — ISC00 (Interrupt Control 0 bit 0).

SM2 SE SM1 SM0 ISC11 ISC10 ISC01 ISC00

7 0
8
Регистры и биты управления прерыванием ATmega32
Регистр флагов процессора
Status register
SREG
Bit 7 — I (Interrupt) interrupt; Bit 3 — V (oVerflow) Overflow Flag;
Bit 6 — Т (sTorage) loading; Bit 2 — N (Negative) Negative Flag;
Bit 5 — Н (Half) Half Carry Flag; Bit 1 — Z (Zero) Zero Flag;
Bit 4 — S (Sign) Sign Bit; Bit 0 — C (Carry) Carry Flag.

I T H S V N Z C

7 0

9
Регистры и биты управления прерыванием ATmega32

Регистр флагов прерываний


General Interrupt Flag Register
GIFR
Bit 7 — INTF1, external interrupt flag INT1;
Bit 6 — INTF0, external interrupt flag INT0;
Bit 5 — INTF2, external interrupt flag INT2.

INTF1 INTF0 INTF2 - - - - -

7 0

10
Пример настройки и обработки прерывания
.include “m32Adef.inc” ; продолжение программы
.org $000 rjmp Init ;Вектора ldi r20,0b11111111 ; выключить
.org $002 rjmp P_Int0 sei ;разрешить все прерывания
.org $004 rjmp P_Int1

Init: ;Сюда попадаем по сбросу main: ; вывести на светодиоды r20


ldi r16,high(RAMEND) ;Настоим указатель стека out PORTB,r20
out SPH,r16 ; rjmp main
ldi r16,low(RAMEND)
out SPL,r16 ;Где то в памяти программ
ser r20 ;Настроим порт В ;расположены эти две процедуры
out DDRB,r20 ;на вывод P_Int0:
out PORTB,r20 ;Там светодиоды ldi r20,0b00001111
ldi r20,0b00001011 ;int0 - нарастающим Reti ;команда выход из прерывания
out MCUCR,r20 ;int1 - падающим фронтом
ldi r20,0b11000000 ;и Int 0 и 1 оба разрешены P_Int1:
out GICR,r20 ldi r20,0b01010101
Reti ;возврат точку прерывания
11
Основы работы с EEPROM
EEPROM (Electronically Erasable Read-Only Memory) -
энергонезависимая память с довольно большим количеством циклов
записи. Данные, записанные в эту память, не будут потеряны даже при
выключении питания, что очень удобно, например, для хранения
настроек или каких-то идентификационных данных. EEPROM в AVR
имеет ограниченное количество циклов записи - 100000. Количество
циклов чтения не ограничено.
Есть два способа получить записать данные в EEPROM
микроконтроллера AVR: Первый - использовать внешний программатор,
например STK500. Готовый к записи файл через Microchip Studio может
быть записан в EEPROM. Для этого в программе имеется отдельная
вкладка. Второй – записать данные прямо в процессе выполнения
программы в AVR. Это делается с помощью специальных регистров,
которые отвечают за адрес, данные для записи (или считывание
информации) и выполняемое действие (запись / чтение).
Использование STK500

1. Подготовьте файл, который Вы


хотите записать в EEPROM.
Файл должен иметь
специальный формат *.EEP
2. На вкладке программирования
EEPROM выберите файл и
нажмите кнопку <Program>.
3. Если Вы хотите считать данные
из EEPROM – нажмите кнопку
<Read>. Данные сохранятся в
файле с указанным именем
Регистры адреса и данных EEPROM
8-ми разрядные регистры адреса EEARH и EEARL (вместе они – это регистр адреса
EEPROM) служат для задания адреса ячейки памяти EEPROM. Все адресное
пространство EEPROM составляет 512 байт. Поэтому значение этого регистра должно
быть в пределах от 0 до 511. После сброса содержимое этих регистров неопределенно,
поэтому перед доступом к EEPROM в них необходимо записать требуемый адрес.

EEARH --- --- --- --- --- --- --- EEARH0

EEARL EEARL7 EEARL6 EEARL5 EEARL4 EEARL3 EEARL2 EEARL1 EEARL0

7 0

EEDR (EEPROM Data Register) Во время операции записи или чтения регистр EEDR
содержит данные, записываемые или считываемые в / из EEPROM.

D7 D6 D5 D4 D3 D2 D1 D0

7 0
Регистр управления EEPROM
EERE: чтение EEPROM. Если этот бит установлен в 1, то данные будут считаны из
EEPROM в регистр EERD, по адресу, указанному в EEAR. После того как данные считаны
установите этот бит в 0, - стоп чтения.
EEWE: запись в EEPROM. Если этот бит установлен в 1, то данные будут записаны в
EEPROM из регистра EERD, по адресу, указанному в EEAR. После того как данные
запишутся установите этот бит в 0, - стоп записи.
EEMWE: Это бит защиты от случайной записи в память EEPROM. Он разрешает 1 или
запрещает 0 запись в память при установке бита EEWE в 1. Если бит EEMWE установлен
в 1, установка бита EEWE приведет к записи в EEPROM по указанному адресу. Если бит
EEMWE установлен в 0, установка бита EEWE не будет иметь никакого эффекта.
Предварительно установленный в 1 бит EEMWE сбрасывается аппаратно после четырех
тактов.
EERIE: Разрешение прерывания по готовности EEPROM к обмену данными. Разрешает (1)
или отключает (0) генерацию прерывания, когда запись завершена и бит EEWE равен 0.

EECR --- --- --- --- EERIE EEMWE EEWE EERE

7 0
Запись в EEPROM
Чтобы записать данные в EEPROM, нужно поместить LDI R16,0 ; EEPROM адрес 0
адрес ячейки, в которую мы хотим записать байт, в LDI R17,0 ;
регистры адреса EEARH и EEARL (регистр адреса LDI R21,45 ; Хотим записать 45
EEPROM). После этого нужно дождаться готовности RCALL EEWrite ; Вызов подпрограммы
памяти к записи, поскольку EEPROM - штука ; записи
довольно медленная. Флаг EEWE (разрешение ; -------
записи EEPROM) регистра управления состоянием EEWrite:
EECR сообщит о готовности к записи, когда он равен SBIC EECR,EEWE ; Бит готовности EEPROM
1, память готова к следующей записи. Сам байт для ; EEPROM Готова?
записи помещается в регистр EEDR (EEPROM Data RJMP EEWrite ; нет еще - EEWE очищен
Register). После этого устанавливается бит CLI ; выключим все прерывания
безопасности EEMWE (разрешение основной записи OUT EEARL,R16 ; установка адреса EEROM
EEPROM), а затем, в течение четырех тактовых OUT EEARH,R17 ; младшй и старший
циклов, вам нужно установить бит EEWE, и байт OUT EEDR,R21 ; загрузка данных
будет записан. Если в течение четырех тактовых SBI EECR,EEMWE ; разрешить запись
циклов у вас не будет времени установить бит EEWE, SBI EECR,EEWE ; записать данные
то бит безопасности EEMWE будет очищен, и его SEI ; разрешить все прерывания
придется установить снова. Это сделано для защиты RET ; выход из подпрограммы
от случайной записи в память EEPROM.
Чтение из EEPROM
Чтение происходит примерно так же, сначала LDI R16,0 ; EEPROM адрес 0
дожидаемся готовности памяти, затем LDI R17,0 ;
вводим желаемый адрес в регистры, затем RCALL EERead ; Вызов процедуры
устанавливаем бит EERE (EEPROM Read ; считывания
Enable) и следующей командой считываем ; R21 будет содержать
наше число из EEPROM в регистр данных ;результат
EEDR/ После чего переносим их в любой ; ------------
общий регистр для последующей обработки. EERead:
На предыдущем примере слева SBIC EECR,EEWE ; Ждем готовности
универсальная процедура записи, а в этом ; иначе читаем
примере процедура чтения. Чтобы записать RJMP EERead ;
байт, нужно ввести младший и старший OUT EEARL, R16 ; загрузить адрес
байты адреса нужной ячейки в регистры R16 OUT EEARH, R17 ; в EEPROM который
и R17, а также байт, который мы хотим ; нам нужен
записать в регистр R21. Затем вызовите эту SBI EECR,EERE ; начать чтение
процедуру записи. Аналогично с чтением - IN R21, EEDR ; забрать результат
адрес находится в регистрах R16 и R17, а RET
считываемое значение будет в регистре R21.
Полезные ссылки
• https://exploreembedded.com/wiki/AVR_External_Interrupts
• https://embedds.com/accessing-avr-eeprom-memory-in-avrgcc/
• https://www.youtube.com/watch?v=GX8_5PggFLs
• https://www.youtube.com/watch?v=5losxTzxK1w

18
Спасибо за Внимание

Олег Непомнящий

Вам также может понравиться