//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单片机中断程序怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)