|
Настройка прерываний в LPC1778, с полного нуля |
|
|
|
Jul 7 2014, 19:43
|
Местный
  
Группа: Участник
Сообщений: 234
Регистрация: 7-11-13
Пользователь №: 79 085

|
Листинг в общих чертах такой: Инициализация и настройка тактирования
1: U0IER|=0x4; //Разрешение прерывания по приёму байта в RX 2: __enable_irq(); //Разрешаем прерывания (CMSIS) 3: __set_BASEPRI(0xFFFFFFFF); //Разрешаем все прерывания (CMSIS) 4: NVIC_EnableIRQ(UART0_IRQn); //Разрешение прерывания UART0 (CMSIS) while(1) { Циклическая отправка данных на ПК }
5: __irq void UART0_IRQ1(void) { for (k=0; k<200; k++) { FIO1SET=0x2000000; //Подёргаем ножкой 200 раз FIO1CLR=0x2000000; } }Хочу сделать так, чтобы при появлении байта в буфере приёма UART вызывалось прерывание. Вот с этим вызовом прерывания проблема и пока не знаю, с какой стороны к ней подходить. Вопросы такие: 1. Правильно ли я выполнил настройки? (строки 1-4) в строке 4 в качестве параметра функции передаётся UART0_IRQ n. Что значит эта n? Её так и нужно оставлять или вместо n нужно какое-то число стаить? Хотя компилятор ругается. 2. Правильно ли я оформил обработчик прерывания? (строка 5). В этой строке пробовал писать название функции от UART0_IRQ 1 ло UART0_IRQ 10. Компилятор не ругался, но и толку никакого не было, на осциллографе не видел дёрганий ножки после отправки байта с ПК. На что влияет выделенное число? Данные в буфер приёма однозначно приходят правильные с ПК. На скрине моя программа в сыром виде. При нажатии кнопки "ТЕСТОВАЯ" с COM-порта отправляется 1 байт 0xAA, который я вижу принятым программой от МК (выделено). Т.е. с приёмом нормально всё, но не совсем удобно каждый раз смотреть на буфер, куда удобнее считывать из него байт по прерыванию. Ну и с настройкой прерываний разобраться нужно. И ещё имеется такой регистр //SETENA0=0xFFFFFFFF; В описании написано, что каждый бит этого регистра разрешает или запрещает соответствующее прерывание. Как понять, к какому прерыванию относится конкретный бит?
Сообщение отредактировал ДЕЙЛ - Jul 7 2014, 19:46
Эскизы прикрепленных изображений
|
|
|
|
|
 |
Ответов
|
Jul 16 2014, 06:12
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 13-09-12
Пользователь №: 73 530

|
Код NVIC_EnableIRQ(UART0_IRQn); //Enable IRQ UART0 (ISER0=32) Не вижу аналогичной конструкции для SysTick. Код NVIC_ClearPendingIRQ(UART0_IRQn); Это обычно добавляют в начало обработчика. Для SysTick наверное тоже надо добавить соответствующую конструкцию. И все же, как прерывания могут работать без extern "C" в cpp-файле? Если ты просто в настройках указал, чтобы cpp-файлы считались сишными, то это очень плохо. Не надо вводить людей в заблуждение, *.cpp - это C++, *.с - это C. Или пишешь на C, и тогда у тебя файлы имеют расширение *.c и не надо никаких extern, или пишешь на C++, при этом файлы у тебя *.cpp и в коде стоят extern "C".
Сообщение отредактировал menzoda - Jul 16 2014, 06:15
|
|
|
|
|
Jul 16 2014, 07:12
|
Местный
  
Группа: Участник
Сообщений: 234
Регистрация: 7-11-13
Пользователь №: 79 085

|
Цитата(menzoda @ Jul 16 2014, 10:12)  Код NVIC_EnableIRQ(UART0_IRQn); //Enable IRQ UART0 (ISER0=32) Не вижу аналогичной конструкции для SysTick. Данная функция нужна для разрешения исключений с номером 16 и выше, как я понял. К системному таймеру относится исключение №15. Чуть выше была картинка из даташита - http://electronix.ru/forum/index.php?act=a...st&id=85886 Судя по этому, аналогичное разрешение прерывания системного таймера не требуется в виде такой функции - его приоритет выше строжевого таймера. Цитата(menzoda @ Jul 16 2014, 10:12)  Код NVIC_ClearPendingIRQ(UART0_IRQn); Это обычно добавляют в начало обработчика. Для SysTick наверное тоже надо добавить соответствующую конструкцию. Пробовал вставлять такую же функцию для SysTick - cрабатывает прерывание Hard Fault. NVIC_ClearPendingIRQ(UART0_IRQn) - можно и в начало поставить, но насколько это принципиально? Это просто сброс бита прерывания, в данном случае прерывания от UART0, чтобы после завершения текущего обработчика он не вызвался снова. Цитата(menzoda @ Jul 16 2014, 10:12)  И все же, как прерывания могут работать без extern "C" в cpp-файле? Если ты просто в настройках указал, чтобы cpp-файлы считались сишными, то это очень плохо. Не надо вводить людей в заблуждение, *.cpp - это C++, *.с - это C. Или пишешь на C, и тогда у тебя файлы имеют расширение *.c и не надо никаких extern, или пишешь на C++, при этом файлы у тебя *.cpp и в коде стоят extern "C". Прерывания работают и вызываются в данном случае, чуть выше в этой теме была такая проблема. Если в низкоприоритетном обработчике IRQ_UART0 не ставить while(1){}, то всё нормально - таймер тикает, принятый байт тоже вызывает прерывание. Бесконечный пустой цикл поставил в обработчике IRQ_UART0 намеренно, чтобы посмотреть, как будет вести себя более высокоприоритетный обработчик IRQ_SysTick во время работы зависшего в бесконечном цикле while(1) обработчика IRQ_UART0.
Сообщение отредактировал ДЕЙЛ - Jul 16 2014, 07:22
|
|
|
|
|
Jul 16 2014, 11:40
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 13-09-12
Пользователь №: 73 530

|
Цитата(ДЕЙЛ @ Jul 16 2014, 11:12)  Данная функция нужна для разрешения исключений с номером 16 и выше, как я понял. Да, действительно. Исключения (внутренние прерывания) работают не так как внешние прерывания, то есть Enable делать не нужно... Цитата(ДЕЙЛ @ Jul 16 2014, 11:12)  Пробовал вставлять такую же функцию для SysTick - cрабатывает прерывание Hard Fault. ...и Clear Pend наверное тоже не нужно. Мне просто казалось, что там все однообразно делается. Цитата(ДЕЙЛ @ Jul 16 2014, 11:12)  NVIC_ClearPendingIRQ(UART0_IRQn) - можно и в начало поставить, но насколько это принципиально? В данном случае не принципиально, но вообще можно придумать такую ситуацию, когда прерывание начнет бесконечно вытеснять самого себя. Не знаю возможно ли такое именно с NVIC, но в других МК я нарывался на подобное поведение. Например в TMS32F28x от TI, заходишь в обработчик прерывания, при этом все прерывания автоматом запрещаются, и чтобы разрешить вытеснение нужно их заново разрешить. Так вот, разрешаешь прерывания и тут же срабатывает это же прерывание, флаг же не сброшен, и так до бесконечности. Конечно, это несколько притянуто за уши, но все же. Кроме того, в рекомендованном Keil'ом варианте реализации вложенных прерываний для старичка ARM7, настоятельно рекомендовалось первым делом сбросить флаг. В общем, перенос этой процедуры в начало хуже не сделает, а вот если она будет в конце, то в некоторых условиях возможны интересные эффекты. Если по делу, то идей почему не работает Sys Tick у меня нету. Включать прерывание, выходит, не надо, да оно по твоим словам уже и так работает, только вот не вытесняет. Хм, пока я смотрел действительно ли не нужно его включать, перед глазами промелькнул код в котором для него задавались приоритеты, а у тебя такого нету, но может я опять чего-то путаю. Во всяком случае поиск выдал кучу статей по настройке этого Sys Tick, можно и подсмотреть.
Сообщение отредактировал menzoda - Jul 16 2014, 11:43
|
|
|
|
Сообщений в этой теме
ДЕЙЛ Настройка прерываний в LPC1778 Jul 7 2014, 19:43 ДЕЙЛ Сегодня утром вчитался получше в описание регистра... Jul 8 2014, 05:58 menzoda Цитата(ДЕЙЛ @ Jul 7 2014, 23:43) Правильн... Jul 8 2014, 08:33 ДЕЙЛ Цитата(menzoda @ Jul 8 2014, 12:33) Никак... Jul 8 2014, 11:05  menzoda Цитата(ДЕЙЛ @ Jul 8 2014, 15:05) как тогд... Jul 8 2014, 12:50  mempfis_ Цитата(ДЕЙЛ @ Jul 8 2014, 14:05) как тогд... Jul 8 2014, 14:29   ДЕЙЛ Цитата(mempfis_ @ Jul 8 2014, 18:29) Вот ... Jul 8 2014, 20:54    menzoda Критиковать пока особо нечего, это же просто набро... Jul 9 2014, 05:43 ДЕЙЛ Прогнал в отладчике через JTAG пошагово.
Запусти... Jul 9 2014, 19:40 menzoda Все логично. Она застряла в бесконечном цикле обра... Jul 10 2014, 05:05  ДЕЙЛ Цитата(menzoda @ Jul 10 2014, 09:05) Эй, ... Jul 10 2014, 17:58 ДЕЙЛ Вечером попробую. Интересно узнать ещё мнение насч... Jul 10 2014, 06:36 ДЕЙЛ Продолжаю начинать осваивать LPC. Читаю про вложен... Jul 15 2014, 19:30   ДЕЙЛ Цитата(menzoda @ Jul 16 2014, 15:40) Хм, ... Jul 16 2014, 12:30 ДЕЙЛ На другом форуме сказали посмотреть регистры уровн... Jul 17 2014, 07:32 ДЕЙЛ С уровнями приоритетов разобрался. Ошибка была в т... Jul 17 2014, 17:45 menzoda В даташите про него ничего не будет, надо искать в... Jul 17 2014, 17:59  ДЕЙЛ Цитата(menzoda @ Jul 17 2014, 21:59) В да... Jul 18 2014, 03:26   menzoda Никакая. Точнее так, можно сообщить библиотеке вре... Jul 18 2014, 05:07
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|