سلام
تابعی دارم که میخوام بطور متناوب بین بازه های زمانی یکسان اجرا بشه
دو تا راه داشتم:
استفاده از تایمر
استفاده از 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 = 1 << AT91C_ID_SYS;
// Configure mode and handler
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int) interrupt_RTT;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = 0x25; //b10 : SRCType | b101 : Priority
// Clear interrupt
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_SYS;
AT91C_BASE_AIC->AIC_IECR = 1 << 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 هم رو بذار ، هر وقت شد چكش مي كنم.(البته اگر خودت تا اون موقع نفهميده بوديش :) )
ناامید شدم ازش
حتی مثال کتاب 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 *rtt, unsigned 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 *rtt, unsigned 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 *pRtt, unsigned int time)
{
SANITY_CHECK(time > 0);
pRtt->RTTC_RTAR = time - 1;
}
راستی قضیه این *AT91C_AIC_EOICR چیه؟
آخر هر وقفه باید یه مقدار دلخواه تو *AT91C_AIC_EOICR بنویسیم دیگه؟
درسته؟
تو هیچکدوم از مثال های اتمل این قسمت نبود!
حتی تو مثال هایی که برای وقفه گذاشته، آخر تعریف تابع وقفه irq__ رو ننوشته..
بجاش تو options پروژه، tab هه C/C++ ، تو تکست باکس misc controlls، عبارت gnu-- رو نوشته...
من امتحان کردم، حین کامپایل هزار تا ارور داد(برای at91sam7x512.h )
کسی تجربه ای داره؟
كدوم كتاب فارسي رو گرفتي؟ همون 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 نمي ذاشتم ، اولش مي ذاشتم
فرم هاي نوشتاريه متفاوتي دارن ، در كل زياد مهم نيست
يه كار رو انجام مي دن
در مورد دستورات داخل 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 long) pit_int;
pAIC->AIC_IECR = (1 << 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; }
}
موفق باشي.