Ну я за С не первый раз сел, чтобы глюкодромы писать. Вот ловлю этих блох, ибо понятное дело где-то накосячил. Начал осваивать с банального - помигать светодиодами :). Вот какой обработчик прерывания от первого канала таймера получился, другие не задействованы. Прерывания раз в 1 мсек. Fpba=32,5МГц
В прерывании крутится динамическая индикация(2 светодиода и 2 семисегментных индикатора) и обработчик клавиатуры из 2 кнопок. С выводом результата на эту самую динамическую индикацию. Вылетает прога всегда именно в нем. Если кто баг мой увидит тыкните меня плиз лицом, где копать. На рисунке то, что выдает отладчик IAR, когда падает программа.
Это предисловие. h-файлик мой.
typedef struct Dynamic_Leds_t{
unsigned int :12;
unsigned int blink :1;
unsigned int blink_en :1;
unsigned int vd16 :8;
unsigned int vd17 :8;
unsigned int rate :1;
unsigned int addr :1;
} Dynamic_Leds_t;
typedef struct _Time{
unsigned long msec ;
unsigned long calendar ;
} _Time;
#define PORTA AVR32_GPIO.port[0]
#define PORTB AVR32_GPIO.port[1]
это сам обработчик
#pragma handler=AVR32_TC_IRQ_GROUP,3
__interrupt void TC_handler(void)
{
static unsigned char i=0, j=0,j300=0,jm=0, js=0, old_pin_mode=0;
static unsigned char temp_addr=1, temp_rate=0;
while(AVR32_TC.channel[0].SR.cpcs); // ждем пока не сбросится флаг прерывания
if(j++>50) // раз в 50 мсекунд обработка клавиатуры
{
j=0;
// обработчик клавиатуры
// кнопка MODE --------------
if((PORTA.pvr)&(1<<18))
{
jm++;
if(!old_pin_mode&&(jm>1)) // поймали фронт и нажатая кнопка держится 50 мсек ?
{ // да
old_pin_mode=0x01;
if(Dynamic_Leds.addr)
{
Dynamic_Leds.addr=0;
Dynamic_Leds.rate=1;
temp_rate=ST_rate;
Dynamic_Leds.vd16=Convert_DtoSEG((temp_rate)&0x0F);
Dynamic_Leds.vd17=Convert_DtoSEG(((temp_rate)>>4)&0x0F);
}
else
{
Dynamic_Leds.addr=1;
Dynamic_Leds.rate=0;
temp_addr=ST_addr;
Dynamic_Leds.vd16=Convert_DtoSEG((temp_addr)&0x0F);
Dynamic_Leds.vd17=Convert_DtoSEG(((temp_addr)>>4)&0x0F);
}
}
}
else
{
jm=0;
old_pin_mode=0;
}
// кнопка SET --------------
if((PORTA.pvr)&(1<<19))
{
js++;
if(js>40)
{ // больше 2 секунд держится кнопка
Dynamic_Leds.blink_en=0;
Dynamic_Leds.blink=1;
ST_addr=temp_addr;
ST_rate=temp_rate;
}
}
else
{
if(js>1&&js<=40)
{
Dynamic_Leds.blink_en=1;
if(Dynamic_Leds.rate)
{
if(++temp_rate>7)
temp_rate=0;
Dynamic_Leds.vd16=Convert_DtoSEG(temp_rate&0x0F);
Dynamic_Leds.vd17=Convert_DtoSEG((temp_rate>>4)&0x0F);
}
else
{
temp_addr++;
Dynamic_Leds.vd16=Convert_DtoSEG(temp_addr&0x0F);
Dynamic_Leds.vd17=Convert_DtoSEG((temp_addr>>4)&0x0F);
}
}
js=0;
}
// ----------
if(Dynamic_Leds.blink_en)
{
if(j300++>6)
{
Dynamic_Leds.blink=(Dynamic_Leds.blink)^0x01;
j300=0;
}
}
}
// динамическая индикация
PORTB.ovrs=(3<<17); // выключили все светодиоды
PORTB.oders=(3<<17)|(0xff<<21);
switch(i++)
{
case 0: //светодиод ADDR
PORTB.oderc=(1<<16); // включаем управление светодиодами rate и addr
if(Dynamic_Leds.addr)
PORTB.ovrc=(1<<18);
break;
case 1: //светодиод RATE
PORTB.oderc=(1<<16); // включаем управление светодиодами rate и addr
if(Dynamic_Leds.rate)
PORTB.ovrc=(1<<17);
break;
case 2: //семисегментный индикатор VD17
PORTB.oders=(1<<16); // выключаем управление светодиодами rate и addr
if(Dynamic_Leds.blink)
PORTB.oderc=(Dynamic_Leds.vd17)<<21;
PORTB.ovrc=(1<<17);
break;
case 3: //семисегментный индикатор VD16
i=0;
PORTB.oders=(1<<16); // выключаем управление светодиодами rate и addr
if(Dynamic_Leds.blink)
PORTB.oderc=(Dynamic_Leds.vd16)<<21;
PORTB.ovrc=(1<<18);
break;
}
// счетчик мсекунд от начала суток
Time.msec ++;
}