Изменение процедуры прерывания в процессе выполнения программы

Тема в разделе "Arduino & Shields", создана пользователем issaom, 15 авг 2019.

  1. issaom

    issaom Гуру

    Всем хорошего дня. Есть вопросик....
    Есть у меня в программе обработчик прерывания на окончанию приема по UART

    Код (C++):
    ISR (USART0_RX_vect) {
    // че-то делаем !
    }
    Если UART-ов несколько и я процессе выполнения программы захочу задействовать другой порт
    мне писать еще один обработчик ISR (USARTn_RX_vect) или есть какая-то возможность изменить этот ?
     
  2. Asper Daffy

    Asper Daffy Иксперд

    Блин, ну вот какого ответа Вы ждёте, если Вы не указали даже на каком камне Всё это делается?
     
  3. issaom

    issaom Гуру

    Камень с несколькими аппаратными UART на борту - например 328PB
    фор екзампл

    Код (C++):

    #define  SetBit(reg, bita)         reg |= (1<<bita)

    ISR (USART0_RX_vect)  //ПРОЦЕДУРА ОБРАБОТКИ ПРЕРЫВАНИЙ ОТ UART0
    {
    uint8_t dat;
    dat = UDR0;
    while ( !( UCSRnA & (1<<UDRE0)) );
    UDR0 = dat;
    }

    #ifdef UDR1
    ISR (USART1_RX_vect) { //ПРОЦЕДУРА ОБРАБОТКИ ПРЕРЫВАНИЙ ОТ UART1
    uint8_t dat;
    dat = UDR1;
    while ( !( UCSRnA & (1<<UDRE0)) );
    UDR1 = dat;
    }
    #endif

    void Serial34b::USART_Init(uint32_t baud, uint8_t serNumber)

    {

    uint32_t FOSC = 16000000;                // Clock Speed
    uint16_t ubrr = FOSC/16/baud-1;
    if (baud == 115200) ubrr =8;           // Глюк с округлением

    if (serNumber == 0) {
    // Устанавливаем скорость передачи !!! Порт Serial есть всегда
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    // Включаем передатчик
    SetBit(UCSR0B, TXEN0);
    // Включаем приемник
    SetBit(UCSR0B, RXEN0);
    // Включаем запрос на прерывание по окончанию передачи
    SetBit(UCSR0B, RXCIE0);
    // Устанавливаем формат кадра 8 data 1 stop bit
    SetBit(UCSR0C, 1);
    SetBit(UCSR0C, 2);  
    }

    if (serNumber == 1) {
        #ifdef UDR1
    // Устанавливаем скорость передачи !!! Порт Serial1 не_всегда
    UBRR1H = (unsigned char)(ubrr>>8);
    UBRR1L = (unsigned char)ubrr;
    // Включаем передатчик
    SetBit(UCSR1B, TXEN1);
    // Включаем приемник
    SetBit(UCSR1B, RXEN1);
    // Включаем запрос на прерывание по окончанию передачи
    SetBit(UCSR1B, RXCIE1);
    // Устанавливаем формат кадра 8 data 1 stop bit
    SetBit(UCSR1C, 1);
    SetBit(UCSR1C, 2);
        #endif  
    }
    }
     
    Этот код будет компилироваться и для камня 328P и для камня 328PB
    Только для камня 328PB будет 2 процедуры обработки прерываний а планируется использовать только один из аппаратных UART
    Код (C++):
    USART_Init(9600,0) или USART_Init(9600,1)
     
  4. Asper Daffy

    Asper Daffy Иксперд

    А так ты не конкретно, а просто потрындеть.

    Ну, тогда, не вопрос. У некоторых "камней с несколькими аппаратными UART на борту" менять векторы на лету можно, а у других - нет. В любом случае выручит простой приём - обработчиков создаём сколько нужно (на каждый вектор свой) а в них тупо вызываем функцию для собственно обработки, можно одну и ту же во всех обработчиках.
     
    DetSimen нравится это.
  5. issaom

    issaom Гуру

    Это просто кусок кода из будущей библиотеки для плат Ардуино и объявленный лишний обработчик, даже который ничего не делает, конфликтует со встроенным в Arduino IDE классом Serial - что печально....
    т.е. идея в том чтобы на одном порту юзать UART библиотекой а на втором (или любом другом если есть) использовать стандартные функции Arduino IDE.....
    Директивы препроцессора типа #ifdef к сожалению в библиотеку не пробрасываются - и на этапе сборки код не пересобрать не влезая править код самой библиотеки.... отсюда и вопрос можно ли создать обработчик после инициализации пользователем нужного порта. Выстроенный в Ардуино класс Serial как то это делать умеет )))
     
  6. Asper Daffy

    Asper Daffy Иксперд

    Ну, я не понял, что именно нужно, но если класс Serial это умеет, то я не понимаю твоего вопроса "можно ли". Если кто-то делает, значит можно, зачем такие вопросы задавать?
     
  7. DetSimen

    DetSimen Guest

    Ничто так не приближает к истине, как разглядывание исходников взрослых дядей. Правда, иногда это приводит к запою.
     
    Asper Daffy и issaom нравится это.
  8. issaom

    issaom Гуру

    Если ты пишешь свой код то там все можно, а когда твой код часть чужой системы - не факт. Вдруг на форуме найдется какой-нибудь библиотекарь-писатель.
     
  9. Asper Daffy

    Asper Daffy Иксперд

    ну, это опять какая-то философия на уровне "потрындеть".

    Если тебе нужно что-то сделать, но ты не знаешь как, но знаешь, что в Serial это сделано, просто посмотри как они это сделали, и сделай также.
     
  10. parovoZZ

    parovoZZ Гуру

    ДА. Вектор обработчика прерывания ФИКСИРОВАН. Его невозможно сменить.
    Чтобы запретить обработку того или иного прерывания, необходимо запрещать или разрешать в соответствующих регистрах ПРЕРЫВАНИЯ. Но в данном случае я бы просматривал флаги - они взводятся всегда. Их запретить невозможно и разрешать также не нужно. Но как только мы разрешаем обработку того или иного прерывания, ОБЯЗАТЕЛЬНО нужен обработчик прерывания, иначе МК уйдет на перезагрузку (если речь про компилятор GCC - он вставляет переход на вектор сброса, если нет обработчика).

    ну так и задействуй. Здесь вопрос в чем?
     
  11. parovoZZ

    parovoZZ Гуру

    и для чего это? Программа пишется ПОСЛЕ утверждения схемотехники. Схемотехника составляется исходя из аппаратных возможностей МК. Инициализация UART/USART - 3-4 строчки кода. Городить ради них монструозную библиотеку не вижу смысла. Проще даташит открыть и за полчаса выучить порядок действий, чем неделю сидеть на форумах и тягаться с непонятной библиотекой.