реклама на сайте
подробности

 
 
> AT91sam7s64 tc1 tc2 interrupt, вопрос знатокам
D!m@
сообщение Jun 28 2010, 18:17
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 74
Регистрация: 10-04-07
Пользователь №: 26 901



Здравствуйте!

Пишу под AT91sam7s64.

Столкнулся с такой проблемой:
Я пользуюсь 2 таймерами TC1 и TC2 в режиме захвата.
Таймера настроены на захват регистра А и рестарт по сравнению с регистром С .
Таймера запущены синхронно и значения регистра С одинаковы.

На таймера есть прерывания по захвату А и сравнению С, по сравнению прерывания возникают одновримено.

Все вроде работает неоприледен время, а потом тупо перестает заходить в обработчик прерываний одного из таймеров (рас 1 рас 2 ..) .

Не заходит, пока не поставлю в дебаге точку останова, непосредственно в том обработчике.
После чего все начинает снова работать не оприделеное время и так по колу.

Код
static void ISR_TC1(void)
{
   unsigned int uiSR = AT91C_BASE_TC1->TC_SR;
    if( (uiSR & AT91C_TC_CPCS) )
   {
       uiOverTC1++;
   }
   if( uiSR & AT91C_TC_LDRAS )
   {
       unsigned int uiRA = AT91C_BASE_TC1->TC_RA;  
       if (uiStartT1 <3 )
         {
             Timer1[uiStartT1].uiRA = uiRA;
             Timer1[uiStartT1].uiOver = uiOverTC1;
             Timer1[uiStartT1].bZap = true;
             uiStartT1++;
         }
   }
  
}
void InitTC1ForFreq()
{
  
    //AIC configure.
    AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_TC1;     // Disable the interrupt first
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC1] = AT91C_AIC_SRCTYPE_POSITIVE_EDGE | AT91C_AIC_PRIOR_HIGHEST;
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC1] = (unsigned int) ISR_TC1;
    AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_TC1;     // Clear interrupt
    AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_TC1;     // Enables interrupts
    
  
    
    // Enable PWMC peripheral clock
    AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC1;
    
    // Disable TC clock
    AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;

    // Disable interrupts
    AT91C_BASE_TC1->TC_IDR = 0xFFFFFFFF;

    // Clear status register
    AT91C_BASE_TC1->TC_SR;

    // Set mode
    AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | // MCK/2
                             AT91C_TC_BURST_NONE |
                             AT91C_TC_EEVTEDG_NONE |
                             AT91C_TC_CPCTRG |
                             AT91C_TC_ABETRG |    
                             AT91C_TC_LDRA_RISING; // each edge of TIOA
                        
    AT91C_BASE_TC1->TC_RC = 0xffff;
    
    // Enable interrpt
    AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS | // Counter compare CR
                             AT91C_TC_LDRAS;  // RA Loading
    
    // Start TC1  
    AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
    
    // Atach to PIO for TIOA1
    AT91C_BASE_PIOA->PIO_BSR = AT91C_PA15_TIOA1;
    AT91C_BASE_PIOA->PIO_PER = AT91C_PA15_TIOA1;
}
////////////////////////////////////////////////////////////////////////////////
// Timer 2  IntL
////////////////////////////////////////////////////////////////////////////////

unsigned int uiOverTC2 = 0;       //  ïåðåïîâíåííÿ òàéìåðà
unsigned int uiTC2LastRA = 0;
static void ISR_TC2(void)
{
   unsigned int uiSR = AT91C_BASE_TC2->TC_SR;
    if( (uiSR & AT91C_TC_CPCS) )
   {
       uiOverTC2++;
   }
   if( (uiSR & AT91C_TC_LDRAS) )
   {
       unsigned int uiRA = AT91C_BASE_TC2->TC_RA;  
       if (uiStartT2 <3 )
       {
           Timer2[uiStartT2].uiRA = uiRA;
           Timer2[uiStartT2].uiOver = uiOverTC2;
           Timer2[uiStartT2].bZap = true;
           uiStartT2++;
       }
   }
  
}
void InitTC2ForFreq()
{
  

    //AIC configure.
    AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_TC2;     // Disable the interrupt first
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC2] = AT91C_AIC_SRCTYPE_POSITIVE_EDGE | AT91C_AIC_PRIOR_HIGHEST;
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned int) ISR_TC2;
    AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_TC2;     // Clear interrupt
    AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_TC2;     // Enables interrupts
    
  
    
    // Enable PWMC peripheral clock
    AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC2;
    
    // Disable TC clock
    AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS;

    // Disable interrupts
    AT91C_BASE_TC2->TC_IDR = 0xFFFFFFFF;

    // Clear status register
    AT91C_BASE_TC2->TC_SR;

    // Set mode
    AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | // MCK/2
                             AT91C_TC_BURST_NONE |
                             AT91C_TC_EEVTEDG_NONE |
                             AT91C_TC_CPCTRG |
                             AT91C_TC_ABETRG |    
                             AT91C_TC_LDRA_RISING; // each edge of TIOA
                        
    AT91C_BASE_TC2->TC_RC = 0xffff;
                        
    // Enable interrpt
    AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS | // Counter
                            AT91C_TC_LDRAS;  // RA Loading
    
    // Start TC1  
    AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
    
    //synhron timers
    AT91C_BASE_TCB->TCB_BCR = AT91C_TCB_SYNC;
    
    // Atach to PIO for TIOA2
    AT91C_BASE_PIOA->PIO_BSR = AT91C_PA26_TIOA2;
    AT91C_BASE_PIOA->PIO_PER = AT91C_PA26_TIOA2;
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Waso
сообщение Aug 10 2010, 12:46
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470



Да. Точно. За основу то взял пример стандартный... Когда не знаешь, да еще и забудешь.. таких делов можно наворотить. =P
И все-таки после брейкпоинта прерывания иногда умирают. Хотя флаги в AIC_IPR и AIC_IMR стоят. CPSR_I=0. Ну ладно, это не критично - отлажусь на осциллографе и консоли.
Go to the top of the page
 
+Quote Post
EugenB2
сообщение Aug 11 2010, 07:42
Сообщение #3





Группа: Участник
Сообщений: 13
Регистрация: 14-01-10
Пользователь №: 54 820



Цитата(Waso @ Aug 10 2010, 15:46) *
Да. Точно. За основу то взял пример стандартный... Когда не знаешь, да еще и забудешь.. таких делов можно наворотить. =P
И все-таки после брейкпоинта прерывания иногда умирают. Хотя флаги в AIC_IPR и AIC_IMR стоят. CPSR_I=0. Ну ладно, это не критично - отлажусь на осциллографе и консоли.

Еще раз стандартный startup посмотреть надо, там была ошибка, не восстанавливались флаги после выхода из прерывания.
IRQ_Handler_Entry:

;- Manage Exception Entry
;- Adjust and save LR_irq in IRQ stack
sub lr, lr, #4
stmfd sp!, {lr}
;- Save and r0 in IRQ stack
stmfd sp!, {r0}
mrs r0, spsr
stmdb sp!,{r0} ; Save the context of the current task. !!!!!!

;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
ldr r14, =AT91C_BASE_AIC
ldr r0 , [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]

;- Enable Interrupt and Switch in Supervisor Mode
msr CPSR_c, #ARM_MODE_SVC

;- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r11, r12, r14}

;- Branch to the routine pointed by the AIC_IVR
mov r14, pc
bx r0

;- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r11, r12, r14}

;- Disable Interrupt and switch back in IRQ mode
msr CPSR_c, #I_BIT | ARM_MODE_IRQ

;- Mark the End of Interrupt on the AIC
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_EOICR]

ldmia sp!,{r0} ; и здесь вот так !!!!!!!!
msr SPSR_cxsf,r0 ; и здесь вот так !!!!!!!!
;- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r0}

;- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 10:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01408 секунд с 7
ELECTRONIX ©2004-2016