while (1) цикл блокирует программу для ввода прерывания

Я хочу создать программу на C, которая включает /отключает отображение пассивной матрицы. Но моя проблема возникает, прежде чем я могу даже реализовать одну функцию этого дисплея.

У меня есть простой коммутатор, подключенный к контакту 24 порта C, который сконфигурирован как INPUT с подтягивающим резистором и отлаживающим входным фильтром. Когда я переключаю переключатель, код вводит прерывание и переключает «отображение» на или в зависимости от состояния коммутатора.

Все работает нормально, пока не вводится простой цикл while(1), который должен обрабатывать все, что я хочу сделать. Но каждый раз, когда я пишу функцию под названием run, которая содержит только один while(1) и одна фиктивная операция __asm__("nop"), цикл while не позволяет коду вводить прерывание.

Это мой код:

void display_init(void) {
    sysclk_init();
    delay_init(sysclk_get_cpu_hz());
    pmc_set_writeprotect(false);
    pmc_enable_periph_clk(ID_PIOC);
    NVIC_EnableIRQ(PIOC_IRQn);
    REG_PIOC_PER = SWITCH;
    REG_PIOC_ODR = SWITCH;
    REG_PIOC_OWDR = SWITCH;
    REG_PIOC_PUER = SWITCH;
    REG_PIOC_IFER = SWITCH;
    REG_PIOC_DIFSR = SWITCH;
    REG_PIOC_LSR = SWITCH;
    REG_PIOC_REHLSR = SWITCH;

    //Clear input change register to avoid immediate interrupt
    REG_PIOC_ISR;
    REG_PIOC_IER = SWITCH;
    run();
}

void run() {
    while(1) {
        __asm__("nop"); //Dummy operation for debugging
    }
}

void PIOC_Handler(void) {
    REG_PIOC_ISR;
    if(REG_PIOC_PDSR & PIO_PC24) {
        __asm__("nop"); //Breakpoint
    } else {
        __asm__("nop"); //Breakpoint
    }
}

Насколько я знаю, прерывание останавливает все выполняемые в текущее время и начинает работать с кодом прерывания. Мой вопрос: почему прерывание не останавливает цикл while?

Прежде чем я узнал эту проблему, у меня было простое условие в цикле while, которое проверяет, равен ли 1 или 0 равным 1, когда я устанавливаю это состояние в 0, поэтому условие было 1 == 0, который должен равняться false. Цикл не останавливался и продолжал работать, даже если условие для этого цикла было ложным ... Возможно ли, что, хотя петли не любят использоваться параллельно с прерываниями?

EDIT:

void main(void) {
    board_init();
    display_init();
}

У меня нет функции Arduino setup (), потому что я использую Atmel Studio для обеспечения работы на низком уровне, чтобы избежать ненужного кода и как можно меньше использовать память.

2 голоса | спросил Fabian Fahrenholz 31 SatEurope/Moscow2016-12-31T16:05:15+03:00Europe/Moscow12bEurope/MoscowSat, 31 Dec 2016 16:05:15 +0300 2016, 16:05:15

1 ответ


3

Цикл while не должен влиять на прерывания. Где вызов run()? Нам нужно увидеть код, который устанавливает и вызывает код, который вы указали. Но в качестве проверки на работоспособность вы можете попробовать заменить все содержимое run () на ;, что делает его пустой функцией. Затем добавьте пустой цикл while (содержит только код ;, no __asm__) и повторите попытку. Затем замените тело цикла while на __asm ​​("nop") __ и повторите попытку. На каком из приведенных выше шагов прерывание прерывается? Это должно привести вас в правильном направлении.

Обновление:
Что делает ваша функция main () после отображения display_init ()? Потому что этого никогда не произойдет, когда run () работает вечно.

Задача main () - создать среду выполнения C /C ++. Возможно, это не было выполнено (например, включение прерываний), когда display_init () и run () вызываются, но завершаются вскоре после их возврата - , если run () разрешено завершать.

Не видя вашего основного (), мы не можем знать достаточно, чтобы быть более конкретным, но я бы предложил вам переместить весь свой код из main () и вниз в функцию Arduino setup (), потому что время, которое будет вызвано, среда выполнения будет завершена.

Обновление 2:

  

, чтобы избежать ненужного кода

Если это ваша функция main (), вы не указали настройку среды выполнения, и неудивительно, что ваш код ведет себя странно. Вы попросили о помощи, и мы внесли некоторые предложения: показать весь ваш код, а не только отдельные его фрагменты; и запустите свой код стандартным образом и сообщите нам результат. Тогда вы можете оптимизировать свой код, если считаете, что это того стоит. Когда вы сделали этот тест, и у вас все еще есть вопросы, спросите еще раз. До тех пор вы просто просите нас угадать. Мы это сделали. Один раз.

ответил JRobert 31 SatEurope/Moscow2016-12-31T16:38:06+03:00Europe/Moscow12bEurope/MoscowSat, 31 Dec 2016 16:38:06 +0300 2016, 16:38:06

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132