Полная версия этой страницы:
Прерывания в Keil
Пытаюсь разобраться с этими прерываниями, но ни одно не работает. В качастве примера использую прерывания по совпадению MR3 TIMER0 LPC2103. Книга по LPC2000 чет не очень помогает. Собственно вопрос - что нужно чтоб выполнился обработчик прерываний IRQ? FIQ? Спасибо.
Читал UM10161, AN10414, книгу Мартина по LPC2000, Help Keil-а, поиск на этом форуме... Ну не получается сделать так чтоб выполнился обработчик прерывания. Суть проста - при совпадении с MR3 происходит обнуление T0TC и прерывание. Выполняется обработчик в котором переменная value увеличивается на 1. Остальное дрыгание ногами просто поленился выкинуть, надеюсь не помешает. Научите правильно описывать прерывания так чтоб работало. Исходные тексты прикрепляю. Спасибо.
Цитата(smk @ Mar 5 2009, 16:47)

Ну не получается сделать так чтоб выполнился обработчик прерывания.
Не говоря много:
http://www.keil.com/support/docs/3229.htm
Код
// function prototypes:
void __swi(0xFE) disable_isr (void);
void __swi(0xFF) enable_isr (void);
/*
* Sample 'main' Function
*/
void main (void) {
func_a(); // func_a executes with standard interrupt setting
disable_isr (); // disable interrupts for the following function
func_b(); // func_b executes with disable interrupts
enable_isr (); // interrupts are now enabled again
}
в этом дело?
Цитата(smk @ Mar 5 2009, 17:36)

в этом дело?
Да. Не разрешили прерывания
Спасибо. Теперь разрешил. Обработчик как прежде не выполняется и остальная программа тоже. Если закомментровать enable_isr (); начинает выполняться программа, но без прерываний. Что не так?
Цитата(smk @ Mar 5 2009, 17:57)

Обработчик как прежде не выполняется и остальная программа тоже.
Выложите кусок с последними изменениями.
Не совсем кусок... а полностью. Извините, если много.
CODE
#include <LPC21xx.H> /* LPC21xx definitions */
//#include <stdio.h> /* standard I/O .h-file */
void PLL_Initialization (void);
void Peripherals_Initialization (void);
void Interupt_Init (void);
void TIMER0_Init (void);
void T0isr(void) __irq;
void __swi(0xFF) enable_isr (void);
volatile unsigned int a;
volatile unsigned int value;
void PLL_Initialization (void)
{
//Настройка тактирования
PLLCFG = 0x23; //Fosc=14.7456; M=4; P=2
PLLCON = 0x1; //включить ФАПЧ
PLLFEED= 0xAA;
PLLFEED= 0x55;
while(!(PLLSTAT & 0x400)){} //Ждем стабилизации ФАПЧ
PLLCON=0x3; //Разрешаем тактирование ЦПУ после стабилизации ФАПЧ
PLLFEED=0xAA;
PLLFEED=0x55;
}
void Peripherals_Initialization (void)
{
//Настройка тактирования периферии
VPBDIV = 0x2;
//Настройка блока ускорения обращения к памяти
MAMTIM = 0x3;
MAMCR = 0x2;
//Конфигурация I/O выводов
PINSEL0 = 0x0;
PINSEL1 = 0x0;
IODIR0 = 0xFFFFFFFF; //все выводы - выходы
//Часы реального времени
CCR=0x11; //Включить, тактировать от часового кварца
}
void Interupt_Init (void)
{
//VICIntSelect = 0; //все прерывания IRQ
//VICIntEnable |= 0x10;//разрешить в VIC прерывание от TIMER0
//VICIntEnable = 0x10;
//VICVectCntl0= 0x24; /* Address of the ISR */
//VICVectAddr0=(unsigned long)T0isr;
VICVectAddr4=(unsigned)T0isr;
VICVectCntl0= 0x00000024;
VICIntEnable = 0x00000010;
//VICIntSelect |= 0x10;//подключить канал VIC (TIMER0) к линии FIQ
}
void TIMER0_Init (void)
{
//T0IR = 0; //Interrupt flag for match channel 3.
T0TCR = 1;//Включить (2 - сбросить TIMER0)
//T0CTCR = 0;//таймер, переключает таймер или счетчик, вход счетчика и тип перепада для счета
//T0TC
T0PR = 100000;//значение, которое достигается предделителем для сброса и проходит импульс на таймер
T0PC = 5000;
T0MCR = 0x03;//прерывание при совпадении MR0 (и сброс)
//T0CCR
//T0EMR
//T0MR3=100;
//T0MR2=100;
//T0MR1=100;
T0MR0=2;
}
void T0isr(void) __irq
{
value++;
//T0IR |= 0x00001000;
T0IR |= 0x00000001;
VICVectAddr = 0x00000000;
//VICSoftIntClear = 0x10;
}
int main (void)
{
PLL_Initialization();
Peripherals_Initialization ();
Interupt_Init();
TIMER0_Init();
enable_isr ();
while(1)
{
if(a<50){a++;}
else {a=0;}
if(a<25)
{IOSET0=0xFF00FF00;}
if(a>=25)
{IOCLR0=0xFF00FF00;}
if(value>1000) {value=0;}
// VICSoftInt = 0x10;
}//while
}//main
Код
VICVectAddr4=(unsigned)T0isr;
VICVectCntl0= 0x00000024;
Адрес один, а контрол - другой.
А как правильно записать строчку VICVectCntl0= 0x00000024; ? Я не уверен, что правильно понима что должно быть в Bit 4:0.
Я пробовал 0х00000020 но не помогает.
Цитата(smk @ Mar 5 2009, 18:06)

Не совсем кусок... а полностью. Извините, если много.
Moderator:
Пожалуйста, пользуйтесь тэгами для оформления кода.
Правильно так:
Код
VICVectAddr0=(unsigned)T0isr;
VICVectCntl0= 0x00000024;
Попробовал. Опять зацикливается.
А что у Вас с Vectors in RAM/ROM и Remap? ничего там не накосячили?
Я их не трогал. Даже не уверен, что точно знаю что это.
Цитата(smk @ Mar 5 2009, 18:58)

Я их не трогал. Даже не уверен, что точно знаю что это.
Я не разбираюсь в кейле, но знаю, что там эти опции задаются в визарде. Если каким-то макаком задана опция Vectors in RAM, то должен быть код, который эти векторы туда поместит. Кода не видно. Во-вторых, не совсем понятно, где clear_bss и прочая подобная инициализирующая требуха. Если я чего-то не понимаю ( по незнанию кейла), меня исправят.
"Инициализирующая требуха" не нужна, а вот выполнение
Код
void __swi(0xFF) enable_isr (void);
моментально завесит процессор, т.к. вектор SWI не определен.
Цитата(aaarrr @ Mar 5 2009, 19:18)

моментально завесит процессор, т.к. вектор SWI не определен.
Я полагал, что автор темы дочитал-таки от начала до конца приведенную ссылку и вставил код оттуда в стартап
Это я до конца не дошел
Впрочем, прерывания включены в стартапе, поэтому дергаться не стоит.
Цитата(aaarrr @ Mar 5 2009, 18:29)

Впрочем, прерывания включены в стартапе, поэтому дергаться не стоит.
void __swi(0xFF) enable_isr (void); - это с enable_isr (); лишнее?
Цитата(aaarrr @ Mar 5 2009, 19:57)

Лишнее.
Тогда что? Есть пример рабочего кода для Keil? Что нужно чтоб описать прерывание?
Ой. Прошу прощения, посмотрел не туда. В стартапе было-таки
Код
MSR CPSR_c, #Mode_USR
Забил Вам мозги...
Цитата(smk @ Mar 5 2009, 21:09)

Тогда что? Есть пример рабочего кода для Keil? Что нужно чтоб описать прерывание?
Ладно, пойдем на второй круг. Что у Вас сейчас сделано и как себя ведет?
Сейчас нормально работает код внутри while(1) и таймер. Проблема в том, что не выполняется обработчик прерываний. Опыта маловато чтоб разобраться в чем дело. Вот если бы хоть раз заработало как надо... тогда другое дело.
Ну вроде бы заработало. Плохо перевел функции регистров VIC с англицкого, отсюда и ошмбки.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.