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

请详细说明

标准c语言没有中断调用机制,但是不同编译器都有相应的中断处理方式,可以使用户实现中断功能。
解决方案:
1、采取轮询的方式解决,就是每10毫秒检查一下是否有键盘请求,总的来说,这样基本上可以解决问题,而且简单易行,但每10毫秒都要检查,系统消耗太大。
2、采取中断的方式:
(1)用高级语言调用中断来处理问题。中断是cpu响应一个中断外围设备8259A的一个过程,当键盘敲击,cpu保存断点暂停执行并且跳到相应的中断处理程序继续执行,结束后根据断点再跳回来。通过这种方式可以轻松+愉快地解决这个问题。但是需要用到高级语言调用汇编,根据编译器的不同而有所差别。
(2)自己模拟中断。可以另外建立一个线程专门响应键盘的敲击,如果有敲击则打断主线程。这样做实现起来很复杂,而且涉及到不少复杂的关键技术,比如信号量之类的东西。
3、强大的vc
vc采取了消息映射的机制来处理外部设备的请求,比如时钟中断、键盘中断等等。通过此可以灰常灰常容易的处理外部中断。
温馨提示:内容为网友见解,仅供参考
第1个回答  2011-09-19
给你上个较完整的程序,可以直接在KEIL中运行并观察输出

/******************************************************************************
功能: 本程序在12M晶振模式下,通过定时器中断精确实现数字时钟计时操作,并在KEIL
中实现输出。时、分、秒的变化在定时中断里处理。
说明: 因采用工作方式2,自动装入初值,所以此程序计时很精确,只是在KEIL中模拟输
出显示的变化速度很快,这点可不理会
******************************************************************************/
#include <reg52.h>
#include <stdio.h>

#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
}
}
}
第2个回答  推荐于2017-09-08
void c51int_0(void) interrupt 0 using 0
{
cpl p1_1;
}
如此,C51INT_0是中断函数名,0是外部中断0的序号(其他依次类推),USING 后面是选寄存器组。追问

总共到interrupt 5是吗?USING后面是选编码器组是什么意思

追答

interrupt 0:INT0
interrupt1:T0
interrupt2:INT1
interrupt3:T1
interrupt4:串口
interrupt5:T2

选编码器组是打错了,应该是“寄存器组”,是为了在子程序里面保护寄存器的。
共四组,
0组R0-R7:00H-07H;
1组R0-R7:08H-0FH;
2组R0-R7:10H-17H;
3组R0-R7:18H-1FH.

本回答被提问者采纳
第3个回答  2011-09-19
外部中断(INT0):
I0(void) interrupt 0//interrupt 0用于外部中断INT0
{//中断执行的内容}

定时器/计数器中断(T0):
T0(void) interrupt 1//interrupt 1用于定时器/计数器T0
{//中断执行的内容}

外部中断(INT1):
I1(void) interrupt 2//interrupt 2用于外部中断INT1
{//中断执行的内容}

定时器/计数器中断(T1):
T1(void) interrupt 3//interrupt 3用于定时器/计数器T1
{//中断执行的内容}追问

那么串口中断呢

追答

串口中断(serial):
serial(void) interrupt 4//interrupt 4用于串口中断
{//中断执行的内容}

如果用的IC是52的话,还有个定时器T2中断,51的没有
定时器中断(T2):
T2(void) interrupt 5//interrupt 5用于定时器T2
{//中断执行的内容}

第4个回答  2011-09-19
中断有好几种,格式都比较类似:

中断号
调用中断处理子程序

子程序入口:
...
返回
相似回答