48043
[i] Работа с прерываниями в микроконтроллерах серии К1986ВЕ1x при исполнении из ОЗУ
Дата последнего изменения: 10.02.2026 12:35:16
Таблица векторов прерываний в микроконтроллерах серии К1986ВЕ1x всегда расположена с нулевого адреса и не может быть перенесена. При разработке программного обеспечения, исполняющегося из ОЗУ, нужно это учитывать и для возможности использования прерываний применять следующие методы:
1. Во Flash-памяти расположить программу, в которой описать функции-подпрограммы обработки прерываний, например, для Timer 1 это может выглядеть так:
Эта функция описана в файле startup (startup_MDR32F1QI.S для микросхем К1986ВЕ1QI, startup_K1986VE1xI.S для микросхем К1986ВЕ1FI, К1986ВЕ1GI, и startup_MDR1986VE1T.S для микросхем К1986ВЕ1(А)Т). А уже внутри этой функции (TIMER1_IRQHandler) должен вызываться реальный обработчик прерываний, расположенный в памяти ОЗУ.
2. Обработчики прерываний расположены в ОЗУ, а во Flash-памяти, в таблице векторов прерываний указать верные адреса этих обработчиков. Тогда при возникновении прерывания процессор обратится к таблице во Flash память, в которой возьмёт адрес обработчика прерывания, расположенного в ОЗУ.
В качестве примера работы возьмем проект для отладочной платы К1986ВЕ1Т из этой статьи для IDE Keil. Этот проект будет загружаться в ОЗУ и использоваться, как основа: прерывания в проекте возникают по приёму данных через ИК-порт (отправить данные можно со второй такой же платы или со смартфона). По аналогии можно настроить работу с любыми прерываниями.
Дополнительно для скачивания в конце статьи доступен проект, загружаемый во Flash-память, чтобы наладить корректную работу прерываний.
Нужно не забыть прикрепить к основному проекту файл Setup.ini для запуска из ОЗУ согласно этой статье. Для удобства запуск производится с начального адреса 0x2010_0000.
После первичного запуска проекта из ОЗУ и отправки на отладочную плату данных прерывания не возникают. Обработчик в программе называется UART1_Handler.
Теперь во Flash-память необходимо записать программу, которая будет считывать значение адреса этого прерывания и "прыгать" на него после его возникновения.
Программа исполняется в микроконтроллере К1986ВЕ1Т с адресов 0x2010_0000, для UART1_IRQHandler необходимо считать значение памяти по адресу 0x2010_0058 (адрес высчитывается согласно таблице "Принцип формирования прерываний" из спецификации на микросхему), а затем перейти по полученному адресу. Таким образом произойдет выполнение обработчика прерывания из ОЗУ.
Код программы, записываемой во Flash-память:
Внесём следующие изменения в проект для Flash-памяти:
Сохранить статью в PDF
1. Во Flash-памяти расположить программу, в которой описать функции-подпрограммы обработки прерываний, например, для Timer 1 это может выглядеть так:
TIMER1_IRQHandler(void); Фрагмент кода 1Эта функция описана в файле startup (startup_MDR32F1QI.S для микросхем К1986ВЕ1QI, startup_K1986VE1xI.S для микросхем К1986ВЕ1FI, К1986ВЕ1GI, и startup_MDR1986VE1T.S для микросхем К1986ВЕ1(А)Т). А уже внутри этой функции (TIMER1_IRQHandler) должен вызываться реальный обработчик прерываний, расположенный в памяти ОЗУ.
2. Обработчики прерываний расположены в ОЗУ, а во Flash-памяти, в таблице векторов прерываний указать верные адреса этих обработчиков. Тогда при возникновении прерывания процессор обратится к таблице во Flash память, в которой возьмёт адрес обработчика прерывания, расположенного в ОЗУ.
1. Реализация первого метода
В качестве примера работы возьмем проект для отладочной платы К1986ВЕ1Т из этой статьи для IDE Keil. Этот проект будет загружаться в ОЗУ и использоваться, как основа: прерывания в проекте возникают по приёму данных через ИК-порт (отправить данные можно со второй такой же платы или со смартфона). По аналогии можно настроить работу с любыми прерываниями.Дополнительно для скачивания в конце статьи доступен проект, загружаемый во Flash-память, чтобы наладить корректную работу прерываний.
Нужно не забыть прикрепить к основному проекту файл Setup.ini для запуска из ОЗУ согласно этой статье. Для удобства запуск производится с начального адреса 0x2010_0000.
После первичного запуска проекта из ОЗУ и отправки на отладочную плату данных прерывания не возникают. Обработчик в программе называется UART1_Handler.
Теперь во Flash-память необходимо записать программу, которая будет считывать значение адреса этого прерывания и "прыгать" на него после его возникновения.
Программа исполняется в микроконтроллере К1986ВЕ1Т с адресов 0x2010_0000, для UART1_IRQHandler необходимо считать значение памяти по адресу 0x2010_0058 (адрес высчитывается согласно таблице "Принцип формирования прерываний" из спецификации на микросхему), а затем перейти по полученному адресу. Таким образом произойдет выполнение обработчика прерывания из ОЗУ.
Код программы, записываемой во Flash-память:
#include <MDR32F9Qx_port.h> // Здесь и далее - при использовании микросхем в пластмассовых корпусах названия драйверов изменить с MDR32F9Qx_... на MDR32FxQI_...
#include <MDR32F9Qx_rst_clk.h>
#define HWREG(x) (*((volatile uint32_t *)(x))) // Макрос для считывания значения по определенному адресу
void UART1_IRQHandler(void);
int main()
{
NVIC_EnableIRQ(UART1_IRQn); //Enable UART1 interrupt
while(1) {
UART1_IRQHandler();
}
}
//--- UART1 interrupt routine ---
void UART1_IRQHandler()
{
int A;
A = HWREG(0x20100058); // Занести в переменную А значение памяти по адресу 0x20100058 (UART1_IRQHandler), чтобы корректно прыгнуть в обработчик прерывания в программе ОЗУ
typedef void (*funcptr)();
funcptr funcInRAM = (funcptr) (A);
funcInRAM(); // Прыжок
}
Фрагмент кода 22. Реализация второго метода
Второй метод менее мобильный, но тоже имеет право на жизнь.Внесём следующие изменения в проект для Flash-памяти:
- Необходимо в main.c оставить только следующие строки кода:
#include <MDR32F9Qx_port.h>Фрагмент кода 3
#include <MDR32F9Qx_rst_clk.h>
void UART1_IRQHandler(void);
int main()
{
NVIC_EnableIRQ(UART1_IRQn); //Enable UART1 interrupt
while(1) {
UART1_IRQHandler();
}
}
- В файле startup*.S (стартовый файл) необходимо изменить строчку "DCD UART1_IRQHandler" на "DCD address", где address - значение адреса, которое нужно считать в режиме отладки проекта под ОЗУ по адресу 0x2010_0058. Теперь программа из Flash-памяти будет отправлять процессор на выполнение обработчика прерывания в ОЗУ. Подробнее на рисунке 1:
Рисунок 1 - Значение address в окне Memory
Сохранить статью в PDF
Файлы для скачивания
Теги
Особенности применения "Know-How"