新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 单片机C语言教程:C51函数

单片机C语言教程:C51函数

作者:时间:2013-03-04来源:网络收藏

三.中断

中断服务是编写应用程序不可缺少的。中断服务只有在中断源请求响应

中断时才会被执行,这在处理突发事件和实时控制是十分有效的。例如:电路中一个按钮, 要求按钮后 LED 点亮,这个按钮何时会被按下是不可预知的,为了要捕获这个按钮的事件, 通常会有三种方法,一是用循环语句不断的对按钮进行查询,二是用定时中断在间隔时间内 扫描按钮,三是用外部中断服务函数对按钮进行捕获。在这个应用中只有单一的按钮功能, 那么第一种方式就能胜任了,程序也很简单,但是它会不停的在对按钮进行查询浪费了

CPU 的时间。实际应用中一般都会还有其它的功能要求同时实现,这个时候能根据需要选用第 二或第三种方式,第三种方式占用的 CPU 时间最少,只有在有按钮事件发生时,中断服务函 数才会被执行,其余的时间则是执行其它的任务。

如果你学习过汇编的话,刚开始写汇编的中断应用程序时,你一定会为出入堆栈的 问题而困扰过。c 扩展了函数的定义使它能直接编写中断服务函数,你能不必考 虑出入堆栈的问题,从而提高了工作的效率。扩展的关键字是 interrupt,它是函数定义时 的一个选项,只要在一个函数定义后面加上这个选项,那么这个函数就变成了中断服务函数。

在后面还能加上一个选项 using,这个选项是指定选用 51 芯片内部 4 组工作寄存器中的

那个组。开始学习者能不必去做工作寄存器设定,而由编译器自动选择,避免产生不必要的错 误。定义中断服务函数时能用如下的形式。

函数类型 函数名 (形式参数) interrupt n [using n]

interrupt 关键字是不可缺少的,由它告诉编译器该函数是中断服务函数,并由后面的

n 指明所使用的中断号。n 的取值范围为 0-31,但具体的中断号要取决于芯片的型号,像 AT89c51 实际上就使用 0-4 号中断。每个中断号都对应一个中断向量,具体地址为 8n+3, 中断源响应后处理器会跳转到中断向量所处的地址执行程序,编译器会在这地址上产生一个 无条件跳转语句,转到中断服务函数所在的地址执行程序。下表是 51 芯片的中断向量和中 断号。

表 9-1 AT89c51 芯片中断号和中断向量
 AT89c51 芯片中断号和中断向量

使用中断服务函数时应注意:中断函数不能直接调用中断函数;不能通过形参传速参数; 在中断函数中调用其它函数,两者所使用的寄存器组应相同。限于篇幅其它与函数相关的知 识这里不能一一加以说明,如变量的传递、存储,局部变量、全部变量等,有兴趣的朋友可 以访问笔者的网站 阅读更多相关文章。

下面是简单的例子。首先要在前面做好的实验电路中加多一个按钮,接在 P3.2(12 引脚外 部中断 INT0)和地线之间。把编译好后的程序烧录到芯片后,当接在 P3.2 引脚的按钮接下 时,中断服务函数 Int0Demo 就会被执行,把 P3 当前的状态反映到 P1,如按钮接下后 P3.7

(之前有在这脚装过一按钮)为低,这个时候 P1.7 上的 LED 就会熄灭。放开 P3.2 上的按钮后,

P1LED 状态保持先前按下 P3.2 时 P3 的状态。

#include

unsigned char P3State(void); //函数的说明,中断函数不用说明

void main(void)

{

IT0 = 0; //设外部中断 0 为低电平触发

EX0 = 1; //允许响应外部中断 0

EA = 1; //总中断开关

while(1);

}

//外部中断 0 演示,使用 2 号寄存器组

void Int0Demo(void) interrupt 0 using 2

{

unsigned int Temp; //定义局部变量

P1 = ~P3State(); //调用函数取得 p2 的状态反相后并赋给 P1

for (Temp=0; Temp50; Temp++); //延时 这里只是演示局部变量的使用

}

//用于返回 P3 的状态,演示函数的使用

unsigned char P3State(void)

{

unsigned char Temp;

Temp = P3; //读取 P3 的引脚状态并保存在变量 Temp 中

//这样只有一句语句实在没必要做成函数,这里只是学习函数的基本使用方法

return Temp;

}


上一页 1 2 下一页

评论


相关推荐

技术专区

关闭