c语言c51外部中断函数 c语言中外部中断程序怎么写

C51中断函数在什么情况下被调用?

一、中断函数的调用

创新互联长期为上1000家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为上杭企业提供专业的成都网站设计、网站制作、外贸营销网站建设上杭网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。

中断函数是硬件或者操作系统自动调用的,也就是说只要满足触发条件,就会自动调用中断函数(此时主函数是停止的)。当中断函数执行完毕,又返回主函数继续执行主函数。然后这样不断的循环,反正只要是触发中断的条件一满足。就会自动进入中断(前提是你的中断的配置是正确的)

二、中断函数的定义

1、中断函数定义的格式为:

函数类型 函数名 interrupt n using n

其中: Interrupt后面的n是中断号。

关键字using后面的n是所选择的寄存器组,取值范围是0-3.

定义中断函数时,using是一个选项,可以省略不用。如果不用则由编译器选择一个寄存器组作为绝对寄存器组。

2、8051的中断过程通过使用interrupt关键字和中断号来实现,中断号告诉编译器中断程序的入口地址。中断号对应着IE寄存器中的使能位,换句话说,IE寄存器中的0位对应着外部中断0,相应的外部中断0的中断号是0. IE寄存器中的使能位与外部中断对应关系:

中断号 中断源

0 外部中断0

1 定时器0

2 外部中断1

3 定时器1中断

4 串行口中断

5 定时器2中断

c51中断函数如何定义,在使用时应注意哪些

C51的中断函数的格式为:

void FuncIr(void) interrupt x [using y]

以下是梦游的一些分析:

一、中断函数是一个特殊的函数,没有参数,也没有返回值;但是程序中允不允许使用return呢?答案是允许的,不过

只能用"return;",不能用"return(z);";用在一些需要快速返回的地方,对应的汇编会有多个ret语句,相对效率会高一

些。

二、using的用法,using可以修饰任何函数,不过个人建议只用来修饰中断函数;简单的说,“using”会指定工作寄存

器组,由于中断函数一般都是比较紧急的事情,有时一条语句都会斤斤计较,所以使用using切换寄存器组可以省去一些压栈

的动作,由于51只有两级中断,同级中断不能被打断,因此,我们可以同级中断设成同样的寄存器组,从某种意义上来说,

有一组寄存器是多余的。同时个人建议中断函数应该使用using这个关键字。

三、中断中调用函数,首先要讨论中断函数中调用函数的必要性,前天在论坛上我和别人争论过这个问题,现在我还是

这个观点:有些情况中断中调用函数还是必要的,这个时候是不是该调用函数,其实和普通函数差不多,首先是这个函数如

果调用多次,或者要带一些参数什么的就更加必要的;前天有人跟我叫劲,说假如只调用一次且无参数无返回的函数要直接

写,因为如果用函数,至少会增加CALL和RET两条语句,我不敢苟同,我是实际调试发现的,当你程序比较复杂时,你将那部

分单独拉出来做成函数,可能代码和时间都会更好

四、中断中调用的函数最好不要被中断外的其它函数调用,因为会出现“重复调用”的警告,有时这种调用是很致命

的,有人说这个函数可以用reentrant来修饰,是的,的确可以这样解决,不过个人不建议这么做,也许这样会跟你减少很多

堆栈空间,并且整个程序的优化要差很多,个人建议出现这种情况就把这个函数写两遍,分成两个函数分别调用。

五,中断调用了函数,会出现一些莫名其妙的问题,一些数据不对。其实一般是因为汇编中使用了绝对寄存器引起的,有人说中断函数使用那个寄存器组,被中断调用的

函数就使用哪个寄存器组,我认为这样不好:

这样会增加额外的消耗,使用using会增加一下语句:

PUSH PSW

MOV PSW, #XX

....

POP PSW

更重要的是,使用using的函数不能有返回值,这是致命伤

个人推荐的方法有两种:

1、使用“#pragma NOAREGS”禁止使用绝对寄存器

2、使用“#pragme RB(x)”来指定本文件的工作寄存器组

六、一般说来,要求中断函数尽可能的短,但也有特殊情况,有些前/后台的系统中,就会把很多相对重要的事情放到定

时中断(这个定时中断类似实时操作系统中的时钟节拍)去做,而且程序很长。我单独提出来这点是想告诉大家,中断函数

也是一个函数而已,只要系统有必要,可以做一些看似不合理的事情,该出手时就出手,就像goto语句一样。

c语言怎么编写单片机的中断

给你上个较完整的程序,可以直接在KEIL中运行并观察输出

/******************************************************************************

功能:

本程序在12M晶振模式下,通过定时器中断精确实现数字时钟计时操作,并在KEIL

中实现输出。时、分、秒的变化在定时中断里处理。

说明:

因采用工作方式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;

//秒计数,计数达到4000时1s,4000*0.25ms

=1000ms

=

1s

bit

bSecChanged;

//秒发生变化标志,每秒送一次输出显示,送显完成后清0,提高主程序效率

//==============================================================================

//T0定时器中断服务程序,12M晶振下每0.25ms产生中断,本程序执行一次

//==============================================================================

void

Timer0()

interrupt

1

{

iCount++;

//秒计数值+1

if(iCount==4000)

{//时间计数达到1S

iCount

=

0;

//重新开始下一秒计数

cSec++;

//时钟:秒+1

bSecChanged

=

1;

//置秒发生变化标志

if(cSec==60)

{//计够60s

cSec

=

0;

//重新开始下一分计数

cMin++;

//时钟:分+1

}

if(cMin==60)

{//计够60分钟

cMin

=

0;

//重新开始下一小时计数

cHour++;

//时钟:小时+1

}

if(cHour==24)

{//计够24小时

cHour

=

0;

//重新开始第二天计数

}

}

}

//==============================================================================

//主程序

//==============================================================================

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;

//秒计数

bSecChanged

=

0;

outstr[2]

=

':';

//时分分隔符

outstr[5]

=

':';

//分秒分隔符

outstr[8]

=

0;

//字符串结束符

EA=1;

//开总中断

ET0=1;

//允许T0中断

TR0=1;

//启动T0

while(1)

{

if(bSecChanged==1)

{//秒发生变化,将时间值转换为可显示字符串准备送显示

bSecChanged

=

0;//清除标志,节省CPU资源

outstr[0]

=

cHour/10

+

0x30;

//将秒转换为ASCII码

outstr[1]

=

cHour%10

+

0x30;

outstr[3]

=

cMin/10

+

0x30;

//将分转换为ASCII码

outstr[4]

=

cMin%10

+

0x30;

outstr[6]

=

cSec/10

+

0x30;

//将小时转换为ASCII码

outstr[7]

=

cSec%10

+

0x30;

#ifdef

TEST

printf("

%s\r",outstr);

//在KEIL中显示时钟

#endif

}

}

}

c51 外部中断0用做暂停,按下暂停 在按起动程序继续运行 C语言的

全局变量处设置unsigned char a,bj;

void Outside_Int0(void) interrupt 0 //中断函数

{if(!(a%2)) bj=1;

else bj=0;

a++;

}

利用a奇偶数改变bj状态

利用bj状态在程序中判断是否暂停或继续


新闻标题:c语言c51外部中断函数 c语言中外部中断程序怎么写
标题链接:http://scyanting.com/article/doehsoh.html