ايران ويج

نسخه‌ی کامل: وقفه ی متناوب با RTT در AT91
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
سلام
تابعی دارم که میخوام بطور متناوب بین بازه های زمانی یکسان اجرا بشه
دو تا راه داشتم:
استفاده از تایمر
استفاده از RTT (البته PIT هم بود، ولی مناسب کار من نیس)


برنامه ای برای RTT هم نوشتم
ولی....

بطور کاملا تصادفی، بعضی وقتا وقفه ایجاد میشه، بعضی وقتا نه...

اینم برنامه:

کد php:
    static void  interrupt_RTT() __irq    
    
{
        *
AT91C_AIC_IDCR 1<<AT91C_ID_SYS;
        
TRACE_DEBUG("*\n");
        
AT91C_BASE_RTTC->RTTC_RTMR |= (AT91C_RTTC_RTTRST);
        
RTT_SetAlarm(AT91C_BASE_RTTC,5);        
        
LED_Toggle(4);
        
        
        *
AT91C_AIC_IECR 1<<AT91C_ID_SYS;
        *
AT91C_AIC_EOICR 0xffff;
    }



int main()
            {     
            
                
TRACE_DEBUG("#######\n");
                
RTT_SetPrescaler(AT91C_BASE_RTTC,32768/2); // exactly 0.9765625 Hz    =     1.024 sec
                
RTT_EnableIT(AT91C_BASE_RTTC,1<<16 );
                
RTT_SetAlarm(AT91C_BASE_RTTC,5);
                
AT91C_BASE_AIC->AIC_IDCR << AT91C_ID_SYS;
                
// Configure mode and handler
                
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned intinterrupt_RTT;
                
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = 0x25//b10 : SRCType   | b101 : Priority                
                // Clear interrupt
                
AT91C_BASE_AIC->AIC_ICCR << AT91C_ID_SYS;                        
                
AT91C_BASE_AIC->AIC_IECR << AT91C_ID_SYS;        
                
            

                for(;;)
                {  
TRACE_DEBUG("#######\n");delay_ms(300);
                }

                
TRACE_DEBUG("\n\t**RTT...ok\n\r");
            } 
سلام.

صالح جان فعلا پنچرم ، اما كدهاي تابع زير و بقيه ي تابع هاي RTT هم رو بذار ، هر وقت شد چكش مي كنم.(البته اگر خودت تا اون موقع نفهميده بوديش :) )
کد php:
RTT_SetAlarm(AT91C_BASE_RTTC,5); 

PIT خاص اين كارهاست و ازش استفاده كردم ، RTT هم راهش انداخته بودم اما نمي دونم با وقفه بود يا نه!
بايد يه زماني پيدا كنم كه از نو رجيسترها رو چك كنم ببينم چيزي مي فهمم يا نه ... .

يه نكته ي ديگه !!
روتين وقفه ي ديگري هم برنامه دارهه؟
اگر اولويتش كمتر باشه ، در نتيجه ...
به اين ها دقت كردي؟
نقل قول: صالح جان فعلا پنچرم ، اما كدهاي تابع زير و بقيه ي تابع هاي RTT هم رو بذار ، هر وقت شد چكش مي كنم.(البته اگر خودت تا اون موقع نفهميده بوديش :) )
Biggrin
ناامید شدم ازش
حتی مثال کتاب at91 فارسی رو هم دقیقا کامپایل کردم، بازم همون مشکل رو داشت...
و وقفه ی دیگه ای نیست.... فقط RTT یه...

توی دیتاشیت اش نوشته که بخاطر سنکرون نبودن کلاک mck و sclk، رجیستر ها رو دو سه بار بخونید تا مقدار جدید از دست نرفته باشه...

ولی نمیدونم توی وقفه ها اصولا نباید مشکلی ایجاد کنه...

بجای TRACE_DEBUG("#######\n" توی حلقه ی بینهایت main، وقتی مقادیر rtt_status و rtt_vr رو میخونم، برنامه درست کار میکنه!

الان یا میخوام با pit بنویسم یا با timer ها ....


کد php:
#include "rtt.h"
#include <utility/assert.h>

//------------------------------------------------------------------------------
//         Exported functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Changes the prescaler value of the given RTT and restarts it. This function
/// disables RTT interrupt sources.
/// \param rtt  Pointer to a AT91S_RTTC instance.
/// \param prescaler  Prescaler value for the RTT.
//------------------------------------------------------------------------------
void RTT_SetPrescaler(AT91S_RTTC *rttunsigned short prescaler)
{
    
rtt->RTTC_RTMR = (prescaler AT91C_RTTC_RTTRST);
}

//------------------------------------------------------------------------------
/// Returns the current value of the RTT timer value.
/// \param rtt  Pointer to a AT91S_RTTC instance.
//------------------------------------------------------------------------------
unsigned int RTT_GetTime(AT91S_RTTC *rtt)
{
    return 
rtt->RTTC_RTVR;
}

//------------------------------------------------------------------------------
/// Enables the specified RTT interrupt sources.
/// \param rtt  Pointer to a AT91S_RTTC instance.
/// \param sources  Bitmask of interrupts to enable.
//------------------------------------------------------------------------------
void RTT_EnableIT(AT91S_RTTC *rttunsigned int sources)
{
    
ASSERT((sources 0x0004FFFF) == 0,
           
"RTT_EnableIT: Wrong sources value.\n\r");
    
rtt->RTTC_RTMR |= sources;
}

//------------------------------------------------------------------------------
/// Returns the status register value of the given RTT.
/// \param rtt  Pointer to an AT91S_RTTC instance.
//------------------------------------------------------------------------------
unsigned int RTT_GetStatus(AT91S_RTTC *rtt)
{
    return 
rtt->RTTC_RTSR;
}

//------------------------------------------------------------------------------
/// Configures the RTT to generate an alarm at the given time.
/// \param pRtt  Pointer to an AT91S_RTTC instance.
/// \param time  Alarm time.
//------------------------------------------------------------------------------
void RTT_SetAlarm(AT91S_RTTC *pRttunsigned int time)
{
    
SANITY_CHECK(time 0);

    
pRtt->RTTC_RTAR time 1;

راستی قضیه این *AT91C_AIC_EOICR چیه؟
آخر هر وقفه باید یه مقدار دلخواه تو *AT91C_AIC_EOICR بنویسیم دیگه؟
درسته؟



تو هیچکدوم از مثال های اتمل این قسمت نبود!Amaze

حتی تو مثال هایی که برای وقفه گذاشته، آخر تعریف تابع وقفه irq__ رو ننوشته..

بجاش تو options پروژه، tab هه C/C++ ، تو تکست باکس misc controlls، عبارت gnu-- رو نوشته...

من امتحان کردم، حین کامپایل هزار تا ارور داد(برای at91sam7x512.h ) Biggrin


کسی تجربه ای داره؟
كدوم كتاب فارسي رو گرفتي؟ همون IAR هه؟! ( اون وقفه اي نبود و كار مي كرد فكر كنم ، كدش رو تو يه تاپيك گذاشته بودم )

نقل قول: ولی نمیدونم توی وقفه ها اصولا نباید مشکلی ایجاد کنه...

بجای TRACE_DEBUG("#######\n" توی حلقه ی بینهایت main، وقتی مقادیر rtt_status و rtt_vr رو میخونم، برنامه درست کار میکنه!
خوب وقتي status رو مي خوني چند رو بر مي گردونه؟ بيت 0 اش هشدار رو نشون مي دهه كه پيش اومدهه يا نه ،‌ البته از آخرين باري كه اين رجيستر رو خوندي ،‌ممكنه هشدار ايجاد بشه و به همين دليل روتين وقفه اجرا نشه ، چون اين بيت 1 بودهه ... ، ونياز باشه بخونيش تا اين بيت مجدد 1 بشه و و رفتن به وقفه هم بلامانع! ( البته در حد احتمال هست!)
البته رجيستر وقفه رو اين كتاب ندارهه ، اگر هنوز برات مهم هست و مي خواي با اين واحد كارت رو راه بندازي ، بگو تا ديتاشيتش رو در مرحله ي بعدي براي رجيسترهاي وقفه چك كنم.

نقل قول: راستی قضیه این *AT91C_AIC_EOICR چیه؟
آخر هر وقفه باید یه مقدار دلخواه تو *AT91C_AIC_EOICR بنویسیم دیگه؟
درسته؟

براي اكثرشون آرهه ،‌يه مقدار دلخواه مي نويسي ،‌اما تا جايي كه يادمه بايد باشه!

نقل قول: حتی تو مثال هایی که برای وقفه گذاشته، آخر تعریف تابع وقفه irq__ رو ننوشته..
بجاش تو options پروژه، tab هه C/C++ ، تو تکست باکس misc controlls، عبارت gnu-- رو نوشته...
من امتحان کردم، حین کامپایل هزار تا ارور داد(برای at91sam7x512.h ) Biggrin

والا منم آخرش irq نمي ذاشتم ، اولش مي ذاشتم Biggrin
فرم هاي نوشتاريه متفاوتي دارن ، در كل زياد مهم نيست Biggrin يه كار رو انجام مي دن
در مورد دستورات داخل c/c++ اش منم سر در نمي يارم چي به چيه.

من اينطوري استفاده مي كردم.
کد php:
__irq void pit_int (void

اين براي پيكربندي pit
کد php:
void init_pit (void) {                      /* Setup PIT with Interrupt */
  
AT91S_AIC pAIC AT91C_BASE_AIC;

  *
AT91C_PITC_PIMR AT91C_PITC_PITIEN |    /* PIT Interrupt Enable */
                     
AT91C_PITC_PITEN  |    /* PIT Enable */
                    // PIV;                   /* Periodic Interval Value */
                    
2702702;
  
/* Setup System Interrupt Mode and Vector with Priority 7 and Enable it */
  
pAIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE 1;
  
pAIC->AIC_SVR[AT91C_ID_SYS] = (unsigned longpit_int;
  
pAIC->AIC_IECR = (<< AT91C_ID_SYS);


اينم روتين وقفه اش:
کد php:
__irq void pit_int (void) {                 /* System Interrupt Handler */
  
AT91S_PITC pPIT AT91C_BASE_PITC;

  if (
pPIT->PITC_PISR AT91C_PITC_PITS ) {  /* Check PIT Interrupt */

// كدهاي روتين وقفه


  
*AT91C_AIC_EOICR pPIT->PITC_PIVR;
}else {*
AT91C_AIC_EOICR 0; }                 


موفق باشي.