Источник
Приоритет
Описание
PSMI 1(Наивысший) Монитор источника питания ADuC812
IE0 2
Внешние прерывание INT0
ADCI 3
Конец преобразования АЦП
TF0 4
Переполнение Таймера/Счетчика 0
IE1 5
Внешние прерывание INT1
TF1 6
Переполнение Таймера/Счетчика 1
I2CI+ISPI 7
Прерывание от I2C/SPI
RI+TI 8
Прерывание от UART
TF2+EXF2 9
(Низший)
Переполнение Таймера/Счетчика 2
4.5.7 Особенности обработки прерываний в стенде SDK-1.1
Прерывания ADuC812 имеют вектора в диапазоне 0003h-0043h, которые
попадают в область младших адресов памяти программ. Это пространство
соответствует 8Кб (0000h-2000h) Flash-памяти.
FLASH
0000h
004Ah
2000h
SRAM
204Ah
mov
P0, #0
ljmp
20XXh
ljmp UserIntVector
Рисунок 80. Использование прерываний в SDK-1.1
В стенде SDK-1.1 пользователь не имеет возможности записи во Flash-
память (запись программ осуществляется во внешнюю память программ и
данных), следовательно, не может подставить свои процедуры обработки
прерываний (точнее, команды перехода к процедурам) по адресам,
соответствующим векторам прерываний.
203
Проблема использования прерываний в пользовательских программах
решается следующим образом:
1. По адресам (0003h-0043h) векторов прерываний во Flash-памяти
SDK-1.1
располагаются
команды
переходов
на
вектора
пользовательской таблицы, размещенной в адресах 2003h-2043h.
2. По адресам векторов пользовательской таблицы пользователем
указываются команды переходов на процедуры обработки прерываний.
Приведем пример помещения собственного вектора в пользовательскую
таблицу. Пусть требуется осуществить обработку прерываний от таймера 0
(прерывание 0Bh). В программу на языке Си (компилятор SDCC) можно
вставить следующий код:
// Обработчик прерывания от таймера 0
void T0_ISR(void) __interrupt (1)
{
// Действия, выполняемые обработчиком
}
//////////////////////// SetVector //////////////////////////
// Функция, устанавливающая вектор прерывания в пользовательской таблице
// прерываний.
// Вход: Vector - адрес обработчика прерывания,
// Address - вектор пользовательской таблицы прерываний.
// Выход: нет.
// Результат: нет.
//////////////////////////////////////////////////////////////
void SetVector(unsigned char xdata * Address, void * Vector)
{
unsigned char xdata * TmpVector; // Временная переменная
// Первым байтом по указанному адресу записывается
// код команды передачи управления ljmp, равный 02h
*Address = 0x02;
// Далее записывается адрес перехода Vector
TmpVector = (unsigned char xdata *) (Address + 1);
*TmpVector = (unsigned char) ((unsigned short)Vector >> 8);
++TmpVector;
*TmpVector = (unsigned char) Vector;
// Таким образом, по адресу Address теперь
// располагается инструкция ljmp Vector
}
void main(void)
{
/*…*/
// Установка вектора в пользовательской таблице
SetVector(0x200B, (void *) T0_ISR);
// Разрешение прерываний от таймера 0
ET0=1; EA=1;
/*…*/
Примеры программ для стенда SDK-1.1, демонстрирующие работу с
прерываниями, таймерами приведены в подразделе 6.4.
204
Do'stlaringiz bilan baham: |