51单片机中断程序怎么写

51单片机中断程序怎么写,第1张

//unsigned char a;

void main(void)//主函数{TCON=0x01;EX0=1; //外部中断允许

EA=1;//开总中断while(1){//其他程序}}

void int0(void) interrupt 0 //外部中断0 中断子程序{//这里面可以写中断子程序/a++;if(a==2) a=0;while(!zd)if(a) TR0=1; //开关计时器

else TR0=0;/}

由于对你的要求“按下INTO接的按键,使单片机执行间隔四灯轮流闪烁的中断子程序”不够理解,只能给你这样一个程序框架了

进入中断要执行中断子程序,不同的中断源要进入不同的中断子程序。对于51的C编程,可以用中断标号,如‘interrupt 0’来使中断进入不同的中断。

中断标号与它们的中断优先级一致,即

发生中断时CPU在中断允许的情况下,强制跳转至中断处理程序对该中断进行响应。

中断处理程序需要注意:

若是改写系统中断,尽量保存系统中断的原地址;

如果是自定义中断,需要注意是否允许多重中断,即能否被另一个中断(包括同一个中断号的相同中断)打断,若不希望被打断,应当在中断处理程序开始时关闭中断允许位IF(用CLI指令),并且在程序结束时开启中断位(用STI指令)。

另外,中断处理程序本身也是一个过程,也有可能出错,所以尽量不要在中断处理程序中产生错误,以免程序不可控。

主函数:

EX0=1;

//外部中断0

IT0=1;

//

1:下降沿触发、0:低电平触发

EA=1;

//开启总中断

中断子程序:

void

inter0()

interrupt

0

{}

外部中断1将0换成1。

我告诉你思路,例子就不举了,很简单:

1、定义一个dword变量xxx用以存储原来的中断向量(所谓中断向量即中断发生时执行的子程序入口地址)

2、编写自己的中断处理过程(yyy proc far),该处理过程内应保存所有可能修改的寄存器,并在返回前恢复原状;一般情况下,如果还需要执行原有中断处理过程,那么调用jmp far xxx链接到原来的中断过程;如果不需要执行原有过程,那么直接以iret返回即可

3、在主程序开始时,先调用int 35h,获取指定中断号的中断向量,将返回的中断向量存储在xxx变量中

4、调用int 25h,将指定的中断号的中断向量指向自己的过程yyy

5、当前程序在退出前,应再次调用int 25h,将被修改掉的中断号的中断向量恢复为xxx变量的值

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

/

功能:

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

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

说明:

因采用工作方式2,自动装入初值,所以此程序计时很精确,只是在KEIL中模拟输

出显示的变化速度很快,这点可不理会

/

#include

#include

#define

TEST

//此行用于KEIL输出显示,如果不需要显示可将其删除

typedef

unsigned

char

uchar;

typedef

unsigned

int

uint;

#define

TH0TL0_INIT

(256-250)

//定时器8位自动装入模式下寄存器初值,025ms中断一次

char

cHour;

//时

char

cMin;

//分

char

cSec;

//秒

uint

iCount;

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

=1000ms

=

1s

bit

bSecChanged;

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

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

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

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

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;

//025ms中断一次

TL0

=

TH0TL0_INIT;

//025ms中断一次

#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

}

}

}

1从数据线上读取中断类型号,将其存入内部暂存器

2将标志寄存器PSW值入

3将PSW中的中断允许标志IF和单步标志TF清0,以屏蔽外部其他中断请求,以及避免CPU以单步方式执行中断处理程序

4保护断点,将当前指令下面一条指令的段地址CS和指令指针IP的值入栈,使中断处理完毕后,能正确返回到主程序继续执行

5根据中断类型号到中断向量表中找到中断向量,转入相应的中断服务子程序;

6中断服务子程序结束后,从堆栈中依次d才出IP,CS和平时外,然后返回主程序断点处,继续执行原来的程序

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

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

在gcc下用__asm__宏即可。

示例(vc):

#include <stdioh>

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。

程序流程图中断有以下表示方式:

1、执行框(矩形框)

执行框中写明某一段程序或某一个模块的功能,其特点是有一个人口一个出口。

2、判别框(菱形框)

可用菱形或尖角形框表示。框内写明比较、判断的条件。条件较长时,用尖角框表示较合适。它可有一个入口和两个出口,在每个出口处都要写明条件判断的结果。

若条件成立,一般写“是”或“Y”,也有写明具体条件的内容,如判断开关的状态,判断框如写明:“开关是处于开通状态否”,若条件成立可写明“开”;若条件不成立,则写成“否”或“N”。

3、起始框和终止框(圆圈)

表示程序段的起始和终止。起始框有个出口起始标号或地址,也可简单写为“开始”。终止框有一个入口。框中可写入“暂停”、“结束”、“返回”等等。

4、指向线(箭头线)

指向线由带箭头的线段表示,它表示程序执行的顺序和去向。

扩展资料:

程序流程图的作用程序流程图的作用程序流程图的作用 程序流程图是人们对解决问题的方法、思路或算法的一种描述。

流程图优点:

1、采用简单规范的符号,画法简单;

2、结构清晰,逻辑性强;

3、便于描述,容易理解。

以上就是关于51单片机中断程序怎么写全部的内容,包括:51单片机中断程序怎么写、什么是中断处理程序编写中断处理程序时要注意哪些问题、51单片机中断程序怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10639100.html

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

发表评论

登录后才能评论

评论列表(0条)

保存