\documentclass{article} \input{settings/common-preamble} \input{settings/bmstu-preamble} \input{settings/fancy-listings-preamble} \def\makeyear{2021} \def\grpNum{11М} \begin{document} \thispagestyle{empty} \makeBMSTUHeader \makeReportTitle{лабораторной}{1}{Создание простой системы в Platform Designer \\ в пакете Quartus Prime}{Программное обеспечение встроенных систем}{}{доцент кафедры ИУ-3 \\ Федоров С.В.} \newpage \blankpage \pagestyle{fancy} \tableofcontents \newpage \section*{Цель работы} \addcontentsline{toc}{section}{Цель работы} Изучить средства создания систем на кристалле на основе процессора Nios II фирмы Intel в средстве Platfrom Designer. Освоить методику создания и конфигурации систем на кристалле. Реализовать и отладить программное обеспечение системы на кристалле. Освоить методику отладки проекта с применением программных и аппаратных средств. Получить навыки работы с документацией производителя. \section*{Задания} \begin{enumerate} \item Модифицируйте исходную программу следующим образом: нажатие кнопки KEY3 должно зажигать все светодиоды, KEY0 -- гасить все светодиоды, нажатие центральных кнопок KEY2 и KEY1 должно гасить светодиоды по очереди слева и справа по одному на каждое нажатие. \item Реализуйте обработку нажатия кнопок и формирование значений на светодиодах по прерыванию. Используйте справочные материалы в каталоге лабораторной работы. \end{enumerate} \section*{Листинги программ} \textbf{Программа по заданию 1} (изменения выделены красным цветом, комментарии приведены и выделены зеленым). для сдвига влево или вправо используется оператор \code{>>}, а для наложения полученного значения на текущие обжуленные биты побитовая маска \& с последующим присваиванием обратно в переменную \code{led}: \begin{lstlisting}[language=C,style=CCodeStyle] #include #include #include "altera_avalon_pio_regs.h" #include "system.h" <@\texttt{\textcolor{codecomments}{// Value read from button PIO when no buttons pressed}}@> #define NONE_PRESSED 0xF <@\texttt{\textcolor{codecomments}{// Time in microseconds to wait for switch debounce}}@> #define DEBOUNCE 30000 int main(void) { #define KEY_3 0x7 #define KEY_2 0xB #define KEY_1 0xD #define KEY_0 0xE int buttons; int led = 0x01; IOWR_ALTERA_AVALON_PIO_DATA(GREEN_LED_BASE,led); while (1) { buttons = IORD_ALTERA_AVALON_PIO_DATA(BUTTONS_BASE); if (buttons != NONE_PRESSED) { <@\texttt{\textcolor{red}{switch(buttons) \{}}@> <@\texttt{\textcolor{red}{case KEY\_3:}}@> <@\texttt{\textcolor{red}{led = 0xFF;}\textcolor{codecomments}{ // all bits 1}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{case KEY\_2:}}@> <@\texttt{\textcolor{red}{led \&= led >> 1;}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{case KEY\_1:}}@> <@\texttt{\textcolor{red}{led \&= led << 1;}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{case KEY\_0:}}@> <@\texttt{\textcolor{red}{led = 0x00;}\textcolor{codecomments}{ // all bits 0}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{\}}}@> IOWR_ALTERA_AVALON_PIO_DATA(GREEN_LED_BASE,led); usleep (DEBOUNCE); while (buttons != NONE_PRESSED) buttons = IORD_ALTERA_AVALON_PIO_DATA(BUTTONS_BASE); usleep (DEBOUNCE); } } } // end \end{lstlisting} \textbf{Программа по заданию 2.} Структура программы: обработчик прерывания от кнопок (в нем считываются задетектированные нажатия кнопок), подпрограмма регистрации обработчика прерывания и главная программа, которая вызывает подпрограмму регистрации и управляет состоянием светодиодов. Во всех функциях использовались макроконстанты, объявленные в заголовочных файлах \code{system.h} и \code{altera_avalon_pio_regs.h}, хранящих адреса соответствующих инструкций и данных. Также был добавлен заголовочный файл \code{sys/alt_irq.h}. Адреса изменились, потому что теперь это не значения на кнопках (1 для свободной, 0 для нажатой), а значения в регистре прерываний (1 для места, где сработало прерывание). \begin{lstlisting}[language=C,style=CCodeStyle] #include #include #include "altera_avalon_pio_regs.h" #include "sys/alt_irq.h" #include "system.h" #define NONE_PRESSED 0xF <@\texttt{\textcolor{red}{\#define KEY\_3 0x8}}@> <@\texttt{\textcolor{red}{\#define KEY\_2 0x4}}@> <@\texttt{\textcolor{red}{\#define KEY\_1 0x2}}@> <@\texttt{\textcolor{red}{\#define KEY\_0 0x1}}@> #define DEBOUNCE 30000 volatile int edge_capture; //from docs void handle_button_interrupts(void* context, alt_u32 id) { volatile int* edge_capture_ptr = (volatile int*) context; *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(<@\texttt{\textcolor{red}{BUTTONS\_BASE}}@>); // Сбросили флажки зарегистрированного прерывания <@\texttt{\textcolor{red}{IOWR\_ALTERA\_AVALON\_PIO\_EDGE\_CAP}}@>(BUTTONS_BASE, 0x0); IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_BASE); } void init_button_pio() { // from docs void* edge_capture_ptr = (void*) &edge_capture; // для формирования передаваемого в прерывание контекста IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTONS_BASE, 0xf); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_BASE, 0x0); alt_ic_isr_register(BUTTONS_IRQ_INTERRUPT_CONTROLLER_ID, BUTTONS_IRQ handle_button_interrupts, edge_capture_ptr, 0x0); } int main(void) { int led = 0x01; printf("Simple\n"); IOWR_ALTERA_AVALON_PIO_DATA(GREEN_LED_BASE,led); init_button_pio(); <@\texttt{\textcolor{red}{edge\_capture = 0;} \textcolor{codecomments}{// инициализация}}@> <@\texttt{\textcolor{red}{while (1) \{}}@> <@\texttt{\textcolor{red}{if (edge\_capture != 0) \{} \textcolor{codecomments}{// Если переменная была изменена (случилось прерывание)}}@> <@\texttt{\textcolor{red}{switch(edge\_capture) \{}}@> <@\texttt{\textcolor{red}{case KEY\_3:}}@> <@\texttt{\textcolor{red}{led = 0xFF;}\textcolor{codecomments}{ // all bits 1}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{case KEY\_2:}}@> <@\texttt{\textcolor{red}{led \&= led >> 1;}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{case KEY\_1:}}@> <@\texttt{\textcolor{red}{led \&= led << 1;}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{case KEY\_0:}}@> <@\texttt{\textcolor{red}{led = 0x00;}\textcolor{codecomments}{ // all bits 0}}@> <@\texttt{\textcolor{red}{break;}}@> <@\texttt{\textcolor{red}{\}}}@> IOWR_ALTERA_AVALON_PIO_DATA(GREEN_LED_BASE,led); edge_capture = 0; <@\texttt{\textcolor{codecomments}{// сбросили глобальную переменную наличия данных от периферии}}@> } } } \end{lstlisting} \end{document}