Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Применение прерываний в Nios II
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Alexey_Rostov
Здравствуйте. Только осваиваю Nios. Подскажите пожалуйста как решить следующую задачу.
Собрал в Qsys простейшую схему:
Нажмите для просмотра прикрепленного файла
В Quartus собрал счетчик. Со счетчика подаю сигнал на Nios и возвращаю из Nios на светодиоды.
Использование функций

Код
d10 = IORD_ALTERA_AVALON_PIO_DATA(DATA_PIO_BASE);
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE , d10);

приводит к тому, что при медленном счете Nios выводит на светодиоды один и тот же отсчет многократно.

Как сделать, чтобы сигнал из Nios на светодиоды выводился только один раз при приеме нового байта от счетчика?
Swup
Я как-то делал вот так.

1. на PIO заведены 4 тумблера.
Модуль вышлет прерывание при изменении любого разряда на регистре PIO. Это будет отражено в регистре pio_edge_cap(как-то так).
Нажмите для просмотра прикрепленного файла

2. функция прерывания выводящая код с 4 тумблеров на 4 светодиода.

Код
void handle_buttons_ISR()
{
    unsigned int led;
    led = IORD(BUTTONS_BASE, 0x00));    // захват данных из регистра pio
    IOWR(LED_BASE, 0, led );            // запись данных в регистр led
    IOWR(BUTTONS_BASE, 3, 0x00));        // обнуляется регистр pio_edge_cap
}


3. регистрируем прерывание по адресу в основной программе.
Примерно так.
Код
int main (void)
{
    IOWR(BUTTONS_BASE, 2, 0x0F);       //маска прерываний, разрешает прерывание при изменение всех 4х бит
    IOWR(BUTTONS_BASE, 3, 0x00);      // сбрасывается регистр pio_edge_cap
    alt_ic_isr_register( NULL, BUTTONS_IRQ, handle_buttons_ISR, NULL, 0x00 );

    while (1)
    {
    
    }

    return 0;
}


ПС если не хотите с этим морочиться, то перед записью просто проверяйте, что d10 изменился после записи.
Например так.
Код
d10 = IORD_ALTERA_AVALON_PIO_DATA(DATA_PIO_BASE);
if (d10_tmp != d10)
{
     IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE , d10);
}
d10_tmp= d10;
Alexey_Rostov
Большое спасибо за пример. Сразу не подумал, что можно обойтись и без прерываний. А как быть если в потоке входных данных содержатся два или более одинаковых числа? И их необходимо записать в массив внутри ниоса?
Как я понял входной регистр ядра PIo не обновиться и соответственно не будет сигнала захвата фронта (edge_capture)?
Swup
В моем примере это было не нужно, да и в вашем примере со счетчиком тоже.

Ну тут идея простая в принципе: для выделения данных из потока у вас должно быть событие символизирующее о новом слове в потоке. В примере выше это изменение числа на шине.
В более реальном варианте этим событием является известный темп следования данных (тактовая частота шины). С точки зрения системы это более сложный вопрос и не думаю, что PIO подходит для такого решения. Можно использовать например FIFO, DMA или написать что-то своё.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.