ايران ويج

نسخه‌ی کامل: وقفه PIO در SAM7
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
سلام
برنامه زیر اینتراپت PA.15 رو فعال میکنه که حساس به لبه بالارونده از صفر به یک میباشد به این صورت که اگر قبل از اتصال تغذیه به میکرو PA.15 رو گراند کنیم، با اتصال تغذیه، برنامه main اجرا شده و led متصل به PB.21 شروع به چشمک زدن میکند و در صورتیکه PA.15 رو از GND جدا کنیم برنامه وقفه اجرا میشود و led متصل به PB.19 به مدت 5 ثانیه روشن میشود و سپس خاموش میشود. اما مشکل اینجا است که روتین اینتراپت فقط یکبار اجرا میشود. و مشکل احتمالا در زیربرنامه وقفه میباشد و باید به رجیستر های AIC_EOICR و AIC_ICCR مقادیر مناسب رو اختصاص داد. در هر صورت کسی میتونه مشکل این برنامه رو حل کنه؟


#include "AT91SAM7X256.h"
#include "lib_AT91SAM7X256.h"
#include "delay.h"
//*************************interrupt rutine********************
void isr_pi_ob (void)
{

AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB19);
delay_s(5);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB19);

//AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_TC1->TC_SR;
//AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_AIC ->AIC_ISR;
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PIOA ->PIO_ISR;

//AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC1); /* Interrupt Ack*/
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_IRQ0 ); /* Interrupt Ack*/
//AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_PIOA); /* Interrupt Ack*/

*AT91C_AIC_EOICR = 0; /* End of Interrupt*/
}
//****************************************8
main(void){

// Setup interrupts
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_PIOA, AT91C_AIC_PRIOR_LOWEST, 0, isr_pi_ob);
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_PIOA);

// Setup PIO
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOA); // Enable clock
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOB); // Enable clock
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, AT91C_PIO_PA15); // Input on PA15
AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA, AT91C_PIO_PA15); // Interrupt on PA15


AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB19);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);
while(1){

AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);
delay_s(1);
AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB21);
delay_s(1);
}
}
من با arm کار نکردم ولی تو بقیه پروسسور ها وقتی اینتراپت رخ می ده بعد از اجرای برنامه باید پرچم مربوطه رو پاک کنی معمولا این کار با دستور return انجام می شه اینم احتمالا مشکلش همونه
سلام
شرمنده دیر شد

اما فکر کنم یادتون رفته از کد زیر آخر تعریف فانکشن استفاده کنید:
کد:
__irq

به help کیل مراجعه کنید ....
باید با خوندن رجیستر وضعیت پرچم ها (PIO_ISR) پرچم ها رو پاک کنید (با عمل خوندن خود به خود پاک میشن) پرچم ها که پاک شدن امکان تشخیص دوباره وقفه هست. منطق برنامه هم حکم میکنه برای اینکه تشخیص بدی چه وقفه ای از PIO اتفاق افتاده (کدوم پایه) حتما باید رجیستر وضعیت (در روتین وقفه) خونده بشه.

تا اونجایی که من می دونم تو keil باید __irq هم استفاده بشه

در نهایت اینکه پیشنهاد می کنم از توابع هدر lib_AT91SAM7X256.h استفاده نکنی. دستورات (مقداردهی رجیستر) اضافه به برنامه تحمیل میکنه. ضمن اینکه لذت برنامه نویسی ARM رو از دست میدی. خیلی بهتره با مطالعه کامل دیتاشیت همه کارا رو خودت بکنی. اوایل یکم وقت گیر اما...
سلام
ممنون از نظرهای شما دوستان
برنامه زیر اینتراپت FIQ رو که مختص پایه PA.29 است فعال میکنهHappy

[/align]
//Moazami 89.12.17

#include "AT91SAM7X256.h"
#include "lib_AT91SAM7X256.h"
#include "delay.h"
//*************************interrupt rutine********************
void Ext_FIQ_handler (void)__irq
{

AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB19);

delay_s(5);

AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB19);


*AT91C_AIC_EOICR = AT91C_BASE_AIC->AIC_ISR;
}
void FIQ_init()
{
AT91C_BASE_PMC->PMC_PCER |= (1<<AT91C_ID_FIQ);
AT91C_BASE_PIOA->PIO_PDR=1<<29; //disable PA29
AT91C_BASE_PIOA->PIO_ASR=1<<29; // PA29= mode A
AT91C_BASE_AIC ->AIC_SMR[AT91C_ID_FIQ]=0x0;
AT91C_BASE_AIC -> AIC_SVR[AT91C_ID_FIQ]=(unsigned int) Ext_FIQ_handler;
AT91C_BASE_AIC ->AIC_IECR=(1<<AT91C_ID_FIQ);
}

main(void){


AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB19);

AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);

AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);


FIQ_init();


AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB19);

AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);

AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);

while(1){

AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB21);

delay_s(1);

AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB21);

delay_s(1);
}
}