C51中斷函數(shù)格式
創(chuàng)新互聯(lián)建站主營昌邑網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,App定制開發(fā),昌邑h5微信小程序開發(fā)搭建,昌邑網(wǎng)站營銷推廣歡迎昌邑等地區(qū)企業(yè)咨詢
Keil C51編譯器中斷函數(shù)語法定義如下:
(C語言不用處理現(xiàn)場保護了) interrupt n ----這個是重點
void 函數(shù)名() interrupt n
{
}
//定時器T0中斷
void 函數(shù)名() interrupt 1
{
}
C51編譯器允許0~31個中斷,下列中斷及其相關(guān)地址為8051控制器所提供的中斷:
0:EXTERNAL 0 地址:0003H
1:TIMER/COUNTER 0 地址:000BH
2:EXTERNAL 1 地址:0013H
3:TIMER/COUNTER 1 地址:001BH
4:SERIAL PORT 地址:0023H
編寫中斷函數(shù)時應(yīng)遵循下列規(guī)則:
·不能進行參數(shù)傳遞。如果中斷過程包括任何參數(shù)聲明,則編譯器將產(chǎn)生一個錯誤信息。
·無返回值。如果想定義一個返回值將產(chǎn)生錯誤,但是,如果返回整型值,編譯器將不產(chǎn)生
錯誤信息,因為整型值是默認值,編譯器不能清楚識別。
·在任何情況下,不能直接調(diào)用中斷函數(shù),否則編譯器會產(chǎn)生錯誤。由于退出中斷過程是由
指令RETI完成的,該指令影響MCS-51單片機的硬件中斷系統(tǒng),直接調(diào)用中斷函數(shù)時,硬件
上沒有中斷請求存在,因而這個指令的結(jié)果是不定的,并且通常是致命的。
·編譯器從絕對地址8n+3處產(chǎn)生一個中斷向量,其中n為中斷號,該向量包括一個中斷過
程的跳轉(zhuǎn),向量的產(chǎn)生可由編譯器控制指令NOINTVECTOR壓縮,因而程序員可以從獨立的匯
編模塊中提供中斷向量。
·可以在中斷函數(shù)定義中使用using指定當前使用的寄存器組。格式如下:
void 函數(shù)名([形式參數(shù)])interrupt n [using m]
MCS-51單片機有四組寄存器R0~R7,程序具體使用哪一組寄存器由程序狀態(tài)字PSW中
的兩位RS1和RS0來確定。在中斷函數(shù)定義時,可以用using指定該函數(shù)具體使用哪一組寄
存器,m在0,1,2,3這4個數(shù)中取值,對應(yīng)四組寄存器組。例如:
void delay() interrupt 3 using 2
·在中斷函數(shù)中調(diào)用的函數(shù)所使用的寄存器組必須與中斷函數(shù)相同。當沒有使用using指令
時,編譯器會選擇一個寄存器組作為絕對寄存器訪問。程序員必須保證按要求使用相應(yīng)寄存
器組,C編譯器不會對此檢查。
·如果在中斷函數(shù)中執(zhí)行浮點運算,必須保存浮點寄存器狀態(tài),當沒有其他程序執(zhí)行浮點運
算時,可以不保存。
駐留程序
通俗點講
就是
程序運行完了,
還要保留
臨時數(shù)據(jù)
和
運行狀態(tài),
等下一次
調(diào)用時
繼續(xù)
執(zhí)行
和普通程序的
區(qū)別:
普通程序(如一個
子函數(shù))
調(diào)用完了
,
臨時數(shù)據(jù)
就
不需要了,
分配的
內(nèi)存
空間
就
回收了,
而
駐留程序
是
要保留這些的
駐留
程序
主要
用于
中斷函數(shù)
,
非中斷函數(shù)
也
有應(yīng)用,較少。分別舉個例子:
1)用于
中斷:
假設(shè)
一個
用
定時器
做的
時鐘函數(shù),定時器
設(shè)置為
1s一個中斷。
main()
{
顯示
時間
hour,min,sec;
//
循環(huán)
刷屏顯示
}
中斷函數(shù)
{
sec++;
if(sec=60)
{
sec=0;
min++;
}
if(min=60)
{
min=0;
hour++;
}
if(hour=24)
{
hour=0;
}
}
這時候
就能看出,
中斷程序
在
運行完的
時候
不能
把
3個
變量
清空,
因為
下次
中斷
還要用到
上次的
值,
這個程序
要
一直
駐留
內(nèi)存;
2)再來個
普通
函數(shù)的
假設(shè)
做了一個程序
,程序中
有一個
函數(shù)aa,而
函數(shù)
aa
我只能
讓它執(zhí)行
3次就得
關(guān)閉程序(這個
用在
密碼
驗證上)
aa()
{
密碼驗證次數(shù)n+1
返回n
和
驗證結(jié)果
}
那這個
aa函數(shù)
在
密碼
驗證
階段
就要
常駐
內(nèi)存
形式如下:
void 中斷名(void) inerrupt 中斷號 using 工作寄存器組
比如外部中斷0
void ext0(void) interrupt 0 using 1 //后面的using 1可以省略,缺省為0
定時器1
void t1isr() interrupt 3
擴展資料:
單片機內(nèi)部結(jié)構(gòu)
1、CPU
它的名字沒有改,還是稱為CPU(Central Processing Unit)。它是單片機的核心部件,包括運算器和控制器。
運算器既是算術(shù)邏輯單元ALU(Arithmetic logic Unit),其功能是進行算術(shù)運算和邏輯運算。
控制器一般由指令寄存器、指令譯碼器、時序電路和控制電路組成。其作用是完成取指令、將指令譯碼形成各種微操作并執(zhí)行指令,同時控制計算機的各個部件有條不紊地工作。
2、單片機內(nèi)部結(jié)構(gòu)之一ROM
“硬盤”,改了名字,稱為程序存儲器,也叫只讀存儲器。用ROM(Read only memery)表示。其作用和計算機的硬盤差不多,用來存放用戶編寫的程序。特點是:掉電后不會丟失數(shù)據(jù)(程序)。
對于C51單片機,其內(nèi)部總共有五級中斷源
分別為外部中斷0、定時器0、外部中斷1、定時器1及串行中斷。
C51單片機的中斷使用時,主要是通過中斷服務(wù)號來決定的。
如你定義一個中斷服務(wù)函數(shù):
void KEY(void) intterrupt 0
{
}
當外部中斷0申請中斷時
會自動根據(jù)interrupt后面的0,找到上面定義的這個中斷服務(wù)函數(shù)。
對于其他四個中斷源,其對應(yīng)的中斷號分別為1、2 、3、4
首先你要寫中斷函數(shù)
然后在主程序中像調(diào)用子函數(shù)一樣調(diào)用就可以了
舉個例子吧
#define uchar unsigned char
#define uchar unsigned char
sbit D1=P1^0;
uchar aa;
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void main()
{
init();
while(1)
{
if(aa==20)
{
D1=~D1;
aa=0;
}
}
}
void T0time()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
給你上個較完整的程序,可以直接在KEIL中運行并觀察輸出
/******************************************************************************
功能:
本程序在12M晶振模式下,通過定時器中斷精確實現(xiàn)數(shù)字時鐘計時操作,并在KEIL
中實現(xiàn)輸出。時、分、秒的變化在定時中斷里處理。
說明:
因采用工作方式2,自動裝入初值,所以此程序計時很精確,只是在KEIL中模擬輸
出顯示的變化速度很快,這點可不理會
******************************************************************************/
#include
#include
#define
TEST
//此行用于KEIL輸出顯示,如果不需要顯示可將其刪除
typedef
unsigned
char
uchar;
typedef
unsigned
int
uint;
#define
TH0TL0_INIT
(256-250)
//定時器8位自動裝入模式下寄存器初值,0.25ms中斷一次
char
cHour;
//時
char
cMin;
//分
char
cSec;
//秒
uint
iCount;
//秒計數(shù),計數(shù)達到4000時1s,4000*0.25ms
=1000ms
=
1s
bit
bSecChanged;
//秒發(fā)生變化標志,每秒送一次輸出顯示,送顯完成后清0,提高主程序效率
//==============================================================================
//T0定時器中斷服務(wù)程序,12M晶振下每0.25ms產(chǎn)生中斷,本程序執(zhí)行一次
//==============================================================================
void
Timer0()
interrupt
1
{
iCount++;
//秒計數(shù)值+1
if(iCount==4000)
{//時間計數(shù)達到1S
iCount
=
0;
//重新開始下一秒計數(shù)
cSec++;
//時鐘:秒+1
bSecChanged
=
1;
//置秒發(fā)生變化標志
if(cSec==60)
{//計夠60s
cSec
=
0;
//重新開始下一分計數(shù)
cMin++;
//時鐘:分+1
}
if(cMin==60)
{//計夠60分鐘
cMin
=
0;
//重新開始下一小時計數(shù)
cHour++;
//時鐘:小時+1
}
if(cHour==24)
{//計夠24小時
cHour
=
0;
//重新開始第二天計數(shù)
}
}
}
//==============================================================================
//主程序
//==============================================================================
void
main()
{
uchar
outstr[10];
//輸出字符串,我的編譯器可能有問題,直接輸出有錯
TMOD
=
0X02;//工作方式2,8位自動重裝計時模式
TH0
=
TH0TL0_INIT;
//0.25ms中斷一次
TL0
=
TH0TL0_INIT;
//0.25ms中斷一次
#ifdef
TEST
SCON
=
0x50;
/*
SCON:
mode
1,
8-bit
UART,
enable
rcvr
*/
TMOD
|=
0x20;
/*
TMOD:
timer
1,
mode
2,
8-bit
reload
*/
TH1
=
221;
/*
TH1:
reload
value
for
1200
baud
@
16MHz
*/
TR1
=
1;
/*
TR1:
timer
1
run
*/
TI
=
1;
/*
TI:
set
TI
to
send
first
char
of
UART
*/
#endif
cHour
=
0;
//時
cMin
=
0;
//分
cSec
=
0;
//秒
iCount
=
0;
//秒計數(shù)
bSecChanged
=
0;
outstr[2]
=
':';
//時分分隔符
outstr[5]
=
':';
//分秒分隔符
outstr[8]
=
0;
//字符串結(jié)束符
EA=1;
//開總中斷
ET0=1;
//允許T0中斷
TR0=1;
//啟動T0
while(1)
{
if(bSecChanged==1)
{//秒發(fā)生變化,將時間值轉(zhuǎn)換為可顯示字符串準備送顯示
bSecChanged
=
0;//清除標志,節(jié)省CPU資源
outstr[0]
=
cHour/10
+
0x30;
//將秒轉(zhuǎn)換為ASCII碼
outstr[1]
=
cHour%10
+
0x30;
outstr[3]
=
cMin/10
+
0x30;
//將分轉(zhuǎn)換為ASCII碼
outstr[4]
=
cMin%10
+
0x30;
outstr[6]
=
cSec/10
+
0x30;
//將小時轉(zhuǎn)換為ASCII碼
outstr[7]
=
cSec%10
+
0x30;
#ifdef
TEST
printf("
%s\r",outstr);
//在KEIL中顯示時鐘
#endif
}
}
}
名稱欄目:c語言中斷函數(shù)如何編寫 c語言怎么中斷程序
本文來源:http://chinadenli.net/article12/dodejgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司、營銷型網(wǎng)站建設(shè)、微信小程序、自適應(yīng)網(wǎng)站、搜索引擎優(yōu)化、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)