۱۴۰۱ بهمن ۲۲, شنبه

میکروکنترلر PIC - قسمت سوم : استفاده از وقفه خارجی

microchip 16f877

 

همانطور که قبلا هم گفته شد, دو روش برای اطلاع از تغییرات پریفرالهای سیستم وجود دارد؛ روش اول که بررسی شد ، روش Polling یا وارسی و انتظار برای تغییر یک رجیستر است و روش دوم ، وقفه نام دارد. با استفاده از وقفه میکروکنترلر مشغول کارهای روتین خود میباشد، به محض تغییر در یکی از رجیسترهای پریفرالهای میکرو ، سیستم آگاه شده، کارهای روتین به صورت موقت متوقف شده و به قسمتی که تقاضای وقفه داشته است رسیدگی میشود.در سیستمهای مختلف این عملیات با کمی تغییر ولی در حالت کلی به همین صورت انجام میپذیرد .

برای استفاده از وقفه خارجی در میکروکنترلر PIC16F877A تنها یک انتخاب استفاده از پایه RB0 وجود دارد. برای این منظور رجیسترهای مربوط به وقفه خارجی به شرح زیر باید اصلاح شوند.
رجیستر INTCON وظیفه کنترل وقفه را برعهده دارد. به محض ریست سیستم ، تمام وقفه ها غیرفعال خواهند شد . فعال کردن وقفه ها با دستکاری رجیسترهای کنترلی صورت میپذیرد. بیت ۷ از رجیستر INTCON وظیفه فعال کردن وقفه عمومی را برعهده دارد. در صورت ۱ بودن این بیت هر وقفه میتواند فعال شود وگرنه حتی اگر بیت مربوط به فعال کردن یک وقفه خاص ۱ باشد اما وقفه عمومی فعال نباشد وقفه ای فعال نخواهد شد.



GIE:وقفه عمومی را فعال میکند .
PEIE:جهت فعال سازی وقفه پریفرالهای داخلی باید این بیت فعال شود.
TMR0IE:وقفه سرریز کانتر ۰ را فعال میکند.
INTE:وقفه خارجی واقع در RB0 را فعال میکند.
RBIE:با فعال شدن این بیت به ازای تغییرات در وضعیت پینهای RB4,RB5,RB6,RB7 وقفه صورت میگیرد.
TMR0IF: در هنگام سرریز تایمر صفر این flag بلند میشود . در صورتیکه TMR0IE یک باشد با هربار سرریز وقفه صورت میپذیرد. در انتهای روتین وقفه باید بصورت نرم افزاری ۰ شود.
INTF:پرچم وقوع وقفه خارجی در RB0 است . در انتهای روتین وقفه باید بصورت نرم افزاری به ۰ تغییر پیدا کند.
RBIF:پرچم نشان دادن وقوع وقفه در پورت RB4 تا RB7.

برای فعال کردن وقفه خارجی باید بیتهای هفتم (وقفه عمومی) و چهارم (INTE) فعال شود . مابقی بیتهای رجیستر INTCON تغییر نمیکند. در برنامه در انتهای روتین وقفه باید بیت INTF بصورت نرم افزاری به صفر تغییر یابد.

	INTCON     |= 0x90;         // Enable Global + INT interrupt


بیت ششم در رجیستر Option تعیین میکند وقفه خارجی به لبه بالا رونده حساس باشد یا لبه پایین رونده.
اگر INTEDG=1 باشد به لبه بالارونده حساس است.
اکر INTEDG=0 باشد به لبه پایین رونده حساس است.



/*
 * File:   XC8.c
 * Author: Ali
 *
 * Created on July 13, 2017, 9:18 AM
 */

#define _XTAL_FREQ 16000000
#include < xc.h>

// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG
void InitExternal_INT(void);
void interrupt ISR(void);

int main()
{
	InitExternal_INT();	// Initialize external interrupts on RB0 pin

	TRISC = 0;   		// Make output
	PORTC = 0;   		// Make value zero

	while(1)
	{		
	}
    return 0;
}

void InitExternal_INT(void)
{
	TRISB0 = 1;                 // Make RB0 pin as input

	INTCON     |= 0x90;         // Enable Global + INT interrupt
	OPTION_REG |= 0x40;         // Make INT as posedge triggered
}

void interrupt ISR(void)
{
	if(INTF)  //If External Edge INT Interrupt
	{
		PORTC++; // Increase PortC value 
        __delay_ms(200);
		INTF = 0;   // clear the interrupt
	}
}

در برنامه فوق ابتدا وقفه تنظیم میشود . با قرار دادن TRISB0=1 پین RB0 را بصورت ورودی تعریف میکنیم . با قرار دادن INTCON |=0x90 مقدار وقفه عمومی و وقفه خارجی را برابر ۱ تعریف میکنیم و باقی رجیستر را بلا تغییر رها میکنیم. با OPTION_REG |= 0x40 بیت مربوط به تعیین لبه در وقفه خارجی را بصورت بالارونده تعریف کرده وباقی رجیستر را بدون تغییر رها میکنیم.
در روتین وقفه، ابتدا از وقوع وقفه جدید با چک کردن بیت INTF اطمینان حاصل میکنیم . سپس مقدار PORTC را یک واحد افزایش داده و برای اطمینان از عدم دخالت BOUNCING کلید، ۲۰۰ میلی ثانیه صبر کرده سپس مقدار INTF را صفر میکنیم. در صورت حذف تاخیر ۲۰۰ میلی ثانیه ای ، در لحظه فشار دادن کلید فشاری چند بار روتین وقفه اجرا شده و به جای افزایش یک واحدی در مقدارPORTC چند واحد افزایش خواهیم داشت.





هیچ نظری موجود نیست:

ارسال یک نظر