Всем хорошего дня. Есть вопросик.... Есть у меня в программе обработчик прерывания на окончанию приема по UART Код (C++): ISR (USART0_RX_vect) { // че-то делаем ! } Если UART-ов несколько и я процессе выполнения программы захочу задействовать другой порт мне писать еще один обработчик ISR (USARTn_RX_vect) или есть какая-то возможность изменить этот ?
Камень с несколькими аппаратными 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)
А так ты не конкретно, а просто потрындеть. Ну, тогда, не вопрос. У некоторых "камней с несколькими аппаратными UART на борту" менять векторы на лету можно, а у других - нет. В любом случае выручит простой приём - обработчиков создаём сколько нужно (на каждый вектор свой) а в них тупо вызываем функцию для собственно обработки, можно одну и ту же во всех обработчиках.
Это просто кусок кода из будущей библиотеки для плат Ардуино и объявленный лишний обработчик, даже который ничего не делает, конфликтует со встроенным в Arduino IDE классом Serial - что печально.... т.е. идея в том чтобы на одном порту юзать UART библиотекой а на втором (или любом другом если есть) использовать стандартные функции Arduino IDE..... Директивы препроцессора типа #ifdef к сожалению в библиотеку не пробрасываются - и на этапе сборки код не пересобрать не влезая править код самой библиотеки.... отсюда и вопрос можно ли создать обработчик после инициализации пользователем нужного порта. Выстроенный в Ардуино класс Serial как то это делать умеет )))
Ну, я не понял, что именно нужно, но если класс Serial это умеет, то я не понимаю твоего вопроса "можно ли". Если кто-то делает, значит можно, зачем такие вопросы задавать?
Ничто так не приближает к истине, как разглядывание исходников взрослых дядей. Правда, иногда это приводит к запою.
Если ты пишешь свой код то там все можно, а когда твой код часть чужой системы - не факт. Вдруг на форуме найдется какой-нибудь библиотекарь-писатель.
ну, это опять какая-то философия на уровне "потрындеть". Если тебе нужно что-то сделать, но ты не знаешь как, но знаешь, что в Serial это сделано, просто посмотри как они это сделали, и сделай также.
ДА. Вектор обработчика прерывания ФИКСИРОВАН. Его невозможно сменить. Чтобы запретить обработку того или иного прерывания, необходимо запрещать или разрешать в соответствующих регистрах ПРЕРЫВАНИЯ. Но в данном случае я бы просматривал флаги - они взводятся всегда. Их запретить невозможно и разрешать также не нужно. Но как только мы разрешаем обработку того или иного прерывания, ОБЯЗАТЕЛЬНО нужен обработчик прерывания, иначе МК уйдет на перезагрузку (если речь про компилятор GCC - он вставляет переход на вектор сброса, если нет обработчика). ну так и задействуй. Здесь вопрос в чем?
и для чего это? Программа пишется ПОСЛЕ утверждения схемотехники. Схемотехника составляется исходя из аппаратных возможностей МК. Инициализация UART/USART - 3-4 строчки кода. Городить ради них монструозную библиотеку не вижу смысла. Проще даташит открыть и за полчаса выучить порядок действий, чем неделю сидеть на форумах и тягаться с непонятной библиотекой.