如何用c语言编写一个可中断的程序

如何用c语言编写一个可中断的程序,第1张

驻留程序

通俗点讲

就是

程序运行完了,

还要保留

临时数据

运行状态,

等下一次

调用时

继续

执行

和普通程序的

区别:

普通程序(如一个

函数

调用完了

临时数据

不需要了,

分配的

内存

空间

回收了,

驻留程序

要保留这些的

驻留

程序

主要

用于

中断函数

非中断函数

有应用,较少。分别举个例子:

1)用于

中断:

假设

一个

定时器

做的

时钟函数,定时器

设置为

1s一个中断。

main()

{

显示

时间

hour,min,sec;

//

循环

刷屏显示

}

中断函数

{

sec++

if(sec>=60)

{

sec=0

min++

}

if(min>=60)

{

min=0

hour++

}

if(hour>=24)

{

hour=0

}

}

这时候

就能看出,

中断程序

运行完的

时候

不能

3个

变量

清空,

因为

下次

中断

还要用到

上次的

值,

这个程序

一直

驻留

内存;

2)再来个

普通

函数的

假设

做了一个程序

,程序中

有一个

函数aa,而

函数

aa

我只能

让它执行

3次就得

关闭程序(这个

用在

密码

验证上)

aa()

{

密码验证次数n+1

返回n

验证结果

}

那这个

aa函数

密码

验证

阶段

就要

常驻

内存

给你上个较完整的程序,可以直接在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

}

}

}

DOS中断中断属于汇编层面的内容,可以用asm内联实现:

在windows visual c++下用__asm关世嫌并键字。

在gcc下用__asm__宏即可。

示例(vc):

#include <stdio.h>

int main()

{

__asm int 3h

return 0

}

这样就可以在C里面写入汇编代码了。

__asm 关键字用于调用内联汇编程序,并且可在 C 或 C++ 语句合法时出现。 它不能单独出现。 必须后跟汇编指令、一组在大括号中的命令、或者至少一对空大括号。 术语 “__asm 块”在此处指任何命令或命令组,不管是否在大括号内。

如果不与大括号一起使用,则 __asm 关键字表示此行的其余部分是一条汇编语言语搜迹句。 如果与大括号一起使用,则该关键字表示大括号之间的每一行都是一条汇编语言语句。为了与早期版本兼容,_asm 是 __asm 的同义词。

由于 __asm 关键字是语句分隔符,因此您可以将程序集指令者辩放在同一行中。

在 Visual C++ 2005 之前,指令

__asm int 3

不会导致在使用 /clr 编译时生成本机代码;编译器会将该指令转换为 CLR 中断指令。

__asm int 3 现在将导致为函数生成本机代码。 如果您希望函数导致代码中出现断点,还希望将函数编译为 MSIL,请使用 __debugbreak。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12505142.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存