|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 6:22 am
|
Страница 1 от 1
|
[ 11 мнения ] |
|
проблем с прекъсване при LPC2124
| Автор |
Съобщение |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
 проблем с прекъсване при LPC2124
Здравейте, проблемът е следният:
серийня порт работи, но не може да предизвика прекъсване. Ето част от кода:
Използвах примерния код, но не тръгва с порта, иначе с таймера работеше.
|
| Сря Юли 16, 2008 9:05 pm |
|
 |
|
БатеВаньо
Ранг: Новодошъл
Регистриран на: Чет Яну 04, 2007 12:43 am Мнения: 178
|
Има две възможности - или прекъсванията не са разрешени глобално, или приеманите символи не съответстват на конфигурацията на LPC-порта - скорост, четност и т.н. При грешка по четност или frame error портът генерира Line Status Interrupt, който както се вижда от кода не е разрешен.
Може да добавиш:
U0IER_bit.RXLSIE = 1;
и да опиташ отново.
И една корекция:
VICDefVectAddr = (U16)&DefDummyInterrupt;
Този оператор преобразува адреса на вектора по подразбиране в 16-битово число. Ако DefDummyInterrupt е извън първите 64К, адресът, зареден във VICDefVectAddr ще е погрешен. Би тябвало да бъде:
VICDefVectAddr = (U32)&DefDummyInterrupt;
|
| Чет Юли 17, 2008 10:03 am |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Всъщност възможностите са много:
1. Глобално забранени прекъсвания към ядрото;
2. Некоректен IRQ вектор в таблицата с ексепшъните;
3. Некоректно ремапване на горната таблица;
4. Некоректно конфигуриране на VIC или в последствие някой бърника по него;
5. Некоректно конфигуриране на PINSEL0 или в последствие някой бърника по него;
6. Некоректно конфигуриране на периферния модул. В случая мисля че конфигурирането на UxLCR трябва да става при DLAB=0, а записа в UxDLL и UxDLM при DLAB=1. За нормалната работа на UART-a след конфигурацията трябва да оставиш DLAB=0.Прекъсванията от този UART не работят коректно ако си забранил FIFO!!!
7. Некоректно конфигуриране на указателя на IRQ стека;
8. Некоректно запомняне/незапомняне на контекста от функцията която обработва прекъсването;
9. Некоректно обработване на прекъсването от горната функция. При този UART обработката има доста особености. Няма да минеш само с празна функция.
10. Сгрешена дефиниция на някой от регистрите в хедър файла.
...
Може бъговете да са повече от един. В твоя случай първо провери точка 6 и 9. Но намери начин да провериш дали средата която ползваш е подсигурила всички останали точки по реда по който са подредени. Списъка не претендира за изчерпателност.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Чет Юли 17, 2008 10:27 am |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
Мерси, сега ще действам. Празната функция беше така в примера, всъщност даже не знам за какво служи  , сега ще прочета по-внимателно.
|
| Чет Юли 17, 2008 10:48 am |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
Модулът е коректно конфигуриран, защото в главната програма приемам символ и след това го изпращам обратно и всико е наред.
|
| Чет Юли 17, 2008 12:02 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Това добре. Но, ако не си разрешил FIFO може да имаш проблем с прекъсванията. Въпреки, че модулът ще работи с полиране. UART при LPC прави проблеми с вдигането на флагове за прекъсвания, когато не е разрешен FIFO. Не е свързано с времена и пропускане на събития от CPU. Просто модула има бъгове/фийчъри.
Аз бих проверил първо две неща. Целия път на сигнала за прекъсване от периферния модул до CPU-то. Дали е конфигуриран правилно в софтуера и дали състоянието на регистрите, при работа на програмката ти, когато чакаш влизане в прекъсване, а то не идва, съответстват на тази конфигурация. И това след като си направил корекциите, които БатеВаньо посочи
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Чет Юли 17, 2008 12:44 pm |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
Не мога да открия проблема и реших да не използвам прекъсване от серийния модул  Първоначалната ми идея се оказа сложна за реалзиране и сега реших да опростя нещата, ще проверявам през определено време дали има получен символ или дали е изпратен предишния, така става по-сигурно и просто. Това, което правя е за дипломна работа, обаче не е много просто, особено като се използва ARM.
Мерси все пак за помощтта, сигурно по-нататък ще ми се наложи да се боря сериозно с тази архитектура.
|
| Чет Юли 17, 2008 2:36 pm |
|
 |
|
БатеВаньо
Ранг: Новодошъл
Регистриран на: Чет Яну 04, 2007 12:43 am Мнения: 178
|
Прекъсванията на LPC2124 работят и при забранен FIFO. Единственият ефект (бъг/фийчър) е, че VIC не "вижда" прекъсването от THRE веднага след инициализация. За да преодолея това се наложи да изпращам първия символ извън функцията за обработка на прекъсването. След него всичко върви наред.
Не съм проверявал изрично, но навярно това го има и при разрешен FIFO.
А по отношение на U0LCR_bit.DLAB - той трябва да е 0, за да са достъпни U0RBR, U0THR и U0IER. U0LCR е достъпен при всички случаи. Въобще, '550-архитектурата, избрана от NXP, е друга дискусионна тема - ама това имали хората, това сложили  .
Между другото, добра практика при побитово установяване на регистрите е да се зареждат и тези полета, в които трябва да има 0 (U0LCR_bit.PE, например), а не да се разчита на "стойности по подразбиране".
|
| Чет Юли 17, 2008 2:53 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Честно да ти кажа това ми е в графата смътен спомен. Веднъж за една дребна задачка се бях натъкнал на него. Докато не разреших FIFO увисвах в чакане на данни от UART-a. Това беше с LPC2214 на 60 MHz и без допълнителни задачи, с код който бях използвал и преди. Така че тогава го свързах с няколко съобщения за подобни проблеми в нета. В търсене на проблема бях орязал кода отвсякъде и накрая дори направих тест - със и без FIFO. И в документацията при описанието на UxFCR има нещо което навежда на тази мисъл. Може пък да е било фийчър на някои от първите ревизии чипове.
Като се замисля MidNighT_SpiRiT ти получаваш вероятно единични байтове. При тази ситуация прекъсването, което ще се получи е CTI, а не RDA. В функцията която идентифицира прекъсването трябва да го предвидиш. Но отдруга страна това
ми подсказва, че следиш дали влизаш в прекъсване с някакъв LED. И явно в случая проблема е че въобще не се стига до идентификация на прекъсването.
В void IRQ_Handler(void) също имаш прочитане на VICVectAddr в U16. Трябва да е U32. Това да не са го направили щото с безплатната версия не можеш да компилираш повече от 16К код?
Въобще този void IRQ_Handler(void) малко усложнява нещата. Предполагам, че средата която ползваш поставя на IRQ вектора код за извикване на тази функция. Още едно нещо което трябва да провериш.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Чет Юли 17, 2008 5:20 pm |
|
 |
|
MidNighT_SpiRiT
Ранг: Напреднал
Регистриран на: Нед Сеп 17, 2006 12:00 pm Мнения: 450 Местоположение: Plovdiv
|
Ползвам средата на IAR systems, защото само с нея работи jtag-a(през паралелния порт) на olimex. Ако техническият в Пловдив беше нормален университет щяха да са купили нещо по-нормално за програмиране и дебъгване, но да не навлизам в подробности...
Да, наистина се получава CTI прекъсване, но то не се разрешава отделно, така, че според мен би трябвало да се получава прекъсване. Буфера го разрешавам, но интересно защо ми дава, че последните два бита, с които се определя при колко байта в буфера да се получи прекъсване са 11, т.е за 14 байта. Опитах да ги нулирам в началото, но без ефект.
|
| Чет Юли 17, 2008 7:39 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Имах впредвид че в switch-case вътре в UART0Interrupt(), където правиш идентификация на прекъсването нямаш default case, нямаш и case за CTI. При това положение няма да прочиташ байтовете от UxRBR ако имаш прекъсване по CTI. Дори и ако всичко по получаването на прекъсването е наред. Иначе е ясно че няма отделно разрешаване на CTI прекъсването. Ако обърнеш внимание при този UART '550. Някои от регистрите споделят общи адреси например при запис на адрес 0xE000C008 пишеш в регистър U0FCR, но това е write only регистър. При четене от адрес 0xE000C008 всъщност четеш регистър U0IIR най старшите два бита на който показват дали са разрешени Rx/Tx FIFO. Няма как да прочетеш на какво ниво са конфигурирани FIFO. Трябва да си го помниш в променлива ако ти е необходимо.
Ако не си се отказал още да подкараш прекъсванията от UART. Постави в междинната функция IRQ_Handler() код за светване на някой LED по платката и провери дали се извиква тази функция поне веднъж. Ако не светва LED-a провери какво е поставил IAR на адрес 0x00000018 или 0x40000018 според това къде е мапната таблицата с ексепшън векторите. Предполагам е нещо от сорта ldr pc, [pc, #xx], където (0x18 + 8 + #xx) трябва да сочи константа в литерал пуула с адреса на IRQ_Handler().
Ако това не е така не чакай да ти се извика обработчика на прекъсванията.
Ако искаш да шунтираш междинната функция IRQ_Handler(), която от IAR са поставили за твое добро, постави на адрес 0x00000018(0x40000018) ето този ред:
Това ще насочи IRQ вектора директно към адреса подаван от VICVectAddr.
В този случай обаче трябва да не забравиш да сложиш в края на UART0Interrupt() eдин фиктивен запис в VICVectAddr за ъпдейтване на приоритетите на VIC. Щото иначе всичко от приоритета на UART-a включително и надолу ще остане маскирано в VIC след първия интеръпт от UART-a.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Чет Юли 17, 2008 10:39 pm |
|
|
|
Страница 1 от 1
|
[ 11 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 2 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|