产品概述

单片机c语言定时器 单片机C语言函数之中断函数(中断服务程序)

小编 2024-10-10 产品概述 23 0

单片机C语言函数之中断函数(中断服务程序)

在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。

中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就不讲了,首先来回忆下中断系统涉及到哪些问题。

(1)中断源:中断请求信号的来源。(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个横杠不知道怎么加上去))

(2)中断响应与返回:CPU采集到中断请求信号,怎样转向特定的中断服务子程序,并在执行完之后返回被中断程序继续执行。期间涉及到CPU响应中断的条件,现场保护,现场恢复。

(3)优先级控制:中断优先级的控制就形成了中断嵌套(8051允许有两级的中断嵌套,优先权顺序为INT0,T0,INT1,T1,串行口),同一个优先级的中断,还存在优先权的高低。优先级是可以编程的,而优先权是固定的。

80C51的原则是①同优先级,先响应高优先权②低优先级能被高优先级中断③正在进行的中断不能被同一级的中断请求或低优先级的中断请求中断。

80C51的中断系统涉及到的中断控制有中断请求,中断允许,中断优先级控制

(1)3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1

(2)中断控制寄存器:定时和外中断控制寄存器TCON(包括T0、T1,INT0、INT1),串行控制寄存器SCON,中断允许寄存器IE,中断优先级寄存器IP

具体的是什么,包括哪些标志位,在这里不讲了,所有书上面都会讲。

在这里我们讲下注意的事项

(1)CPU响应中断后,TF0(T0中断标志位)和TF1由硬件自动清0。

(2)CPU响应中断后,在边沿触发方式下,IE0(外部中断INT0请求标志位)和IE1由硬件自动清零;在电平触发方式下,不能自动清楚IE0和IE1。所以在中断返回前必须撤出INT0和INT1引脚的低电平,否则就会出现一次中断被CPU多次响应。

(3)串口中断中,CPU响应中断后,TI(串行口发送中断请求标志位)和RI(接收中断请求标志位)必须由软件清零。

(4)单片机复位后,TCON,SCON给位清零。

C51语言允许用户自己写中断服务子程序(中断函数)

首先来了解程序的格式:

void 函数名() interrupt m [using n]

{}

关键字 interrupt m [using n] 表示这是一个中断函数

m为中断源的编号,有五个中断源,取值为0,1,2,3,4,中断编号会告诉编译器中断程序的入口地址,执行该程序时,这个地址会传个程序计数器PC,于是CPU开始从这里一条一条的执行程序指令。

n为单片机工作寄存器组(又称通用寄存器组)编号,共四组,取值为0,1,2,3

中断号 中断源

0 外部中断0

1 定时器0

2 外部中断1

3 定时器1中断

4 串行口中断

这5个中断源的中断入口地址为:(在上一篇文章中讲到的ROM前43个存储单元就是他们,这40个地址用来存放中断处理程序的地址单元,每一个类中断的存储单元只有8B,显然不是中断处理的程序,而是存放着中断处理程序的真正地址)

INT0:0003H 0

T0: 000BH 1

INT1:0013H 2

T1: 001BH 3

串口: 0023H 4

中断向量(中断入口地址)= 中断号x8 +3

前面m意思很清楚,不同的m值表示这个函数是针对不同的中断源,比如m为1是表示它是定时器0的中断函数,

如void time0() interrupt 1{}

那么后面的using n 又是什么意思呢?在正在执行一个特定任务时,有更紧急的事情需要CPU来处理,涉及到中断优先权。高优先权中断低优先权正在处理的程序,所以最好给每个优先程序分配不同的寄存器组。

CPU正在处理某个事件,突然另外一个事件需要处理,于是进入中断后,而你不想将现在执行的程序的各寄存器状态入栈,那么可以把这个中断程序放入另一个寄存器组,如切换到1组,然后退出中断时,再切回到0组(原来的程序在0组)。

为了更好的了解这里意思,你可以看看工作寄存器组的作用是什么。

下面的注意事项转自网络上其他朋友的文章(整理下,重复的去掉了,写的非常好):

(1)中断函数不能进行参数传递

(2)中断函数没有返回值

(3)在任何情况下都不能直接调用中断函数

(4)中断函数使用浮点运算要保存浮点寄存器的状态。

(5)如果在中断函数中调用了其它函数,则被调用函数所使用的寄存器必须与中断函数相同,被调函数最好设置为可重入的。

(6)C51编译器对中断函数编译时会自动在程序开始和结束处加上相应的内容,具体如下:在程序开始处对ACC、B、DPH、DPL和PSW入栈,结束时出栈。中断函数未加using n修饰符的,开始时还要将R0~R1入栈,结束时出栈。如中断函数加using n修饰符,则在开始将PSW入栈后还要修改PSW中的工作寄存器组选择位。

(7)C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。

(8)中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明。防止其它程序调用。

(9)在设计中断时,要注意的是哪些功能应该放在中断程序中,哪些功能应该放在主程序中。一般来说中断服务程序应该做最少量的工作,这样做有很多好处。首先系统对中断的反应面更宽了,有些系统如果丢失中断或对中断反应太慢将产生十分严重的后果,这时有充足的时间等待中断是十分重要的。其次它可使中断服务程序的结构简单,不容易出错。中断程序中放入的东西越多,他们之间越容易起冲突。简化中断服务程序意味着软件中将有更多的代码段,但可把这些都放入主程序中。中断服务程序的设计对系统的成败有至关重要的作用,要仔细考虑各中断之间的关系和每个中断执行的时间,特别要注意那些对同一个数据进行操作的ISR.

教你玩单片机之定时器(附程序)

80c51的定时器

80c51单片机内有两个可编程的定时/计数器T0、T1。它们是一个16位计数器,分别由一个高8位和一个低8位的寄存器组成的。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

定时/计数器的工作原理

定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

工作方式寄存器TMOD

GATE:门控制

0时:仅有运行控制位TRx来控制定时/计数器的开启

1时:由TRx和外部中断脉冲计数(用于计算外部中断负跳变 的次数)

C/T:计数器模式和定时器模式选择

0时:选择定时器模式

1时:选择为计数器模式

M1和M0:选择定时/计数器的工作方式

定时器/计数器控制寄存器TCON

IT0和IT1是设置外部中断的触发方式

当其为0时,为低电平触发方式

当其为1时,为负跳变触发方式

IE0和IE1是外部中断标志位

TF0和TF1是定时器的中断标志

TR1和TR0是打开相应的定时器

其他的是定时/计数器的控制

定时/计数器的工作方式

方式1

方式1为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。

方式2

方式2的计数位数是16位,由TL0作为低8位、TH0作为高8位,组成了16位加1计数器 。

方式3

方式3为自动重装初值的8位计数方式。

方式4

方式4只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。

定时器操作步骤:

选择工作方式(设置M1,M0)

选择控制方式(设置GATE)

选择定时器还是计数器模式(设置C/T)

给定时/计数器赋初值(设置THx和TLx)

开启定时器中断(设置ET0或ET1)

开启总中断(设置EA)

打开计数器(设置TR1或TR0)

定时器小程序

void TimerConfiguration()

{

TMOD = 0x01; //定时器0选择工作方式1

TH0 = 0x3C; //设置初始值

TL0 = 0xB0;

EA = 1; //打开总中断

ET0 = 1; //打开定时器0中断

TR0 = 1; //启动定时器0

}

单片机之定时器LED程序

实验效果 :LED每隔500ms左移一次

void main(void)

{

Time=0;

GPIO_LED=0XFE;

TimerConfiguration();

while(1)

{

if(Time==10)

{

GPIO_LED=_crol_(GPIO_LED,1);

Time=0;

}

}

}

void TimerConfiguration()

{

TMOD = 0x01; //选择工作方式1

TH0 = 0x3C; //设置初始值,定时50MS

TL0 = 0xB0;

EA = 1; //打开总中断

ET0 = 1; //打开定时器0中断

TR0 = 1; //启动定时器0

}

void Timer0() interrupt 1

{

TH0 = 0x3C; //设置初始值

TL0 = 0xB0;

Time++;

}

相关问答

C语言 单片机 定时器 输出3KHz方波的程序 - 叫我万颂伊 的回...

#includesbita=P1^0;main(){a=1;TMOD=0X02;//定时器0自动重装载TH0=256-167;TL0=256-167;ET0=1;//定时器0允许TR0=1;//打开...

单片机 汇编 语言 定时器 如何定义和调用使用?

TMOD定时器/计数器模式控制寄存器写入模式TH0,TL0写入初值一般为中断调用要使能计时器0时间中断,还要使能中断有效这样开中断,就可以了TMOD定时器/计数...

定时器 单片机 中程序的运行过程 - 懂得

我觉得是这样的,单片机的定时器,它的计数过程是相当于电脑里面一个后台运行的东东一样。在计数时单片机同时在执行其他程序,计数周期就是单片机的一...

如何把 单片机 里面的 C语言 做成像PLC里的 定时器 那么方便好用?

你用定时器做一个时标,比如100ms、1S,在中断程序中设置相应标志,这样在主程序中就可以判断相应的标志并象PLC一样应用了。你用定时器做一个时标,比如100ms、1...

51 单片机 C语言 或者汇编程序如何实现定时1秒?如何设定初始值?如何计算?如何输出方波?如何对外部?

使用定时器实现1秒定时;初始值要看单片机配置的晶振频率了,若12M晶振,初始值为TH0=0x3c;TL0=0xb0;这才是50ms,还要一个单元做计数器,计数20次才是1秒方波...

单片机 怎么用 定时器 控制蜂鸣器?

要使用定时器控制蜂鸣器,首先需要选择一个合适的定时器模块,并设置其工作模式和计数值。然后,根据需要设置定时器的中断使能位,以便在定时器计数完成时触发...

mcs-51系列 单片机 定时器 T1用做定时方式时,采用工作方式1,则工作方式控制字为?

让我来告诉你答案!答案应该是ATMOD=01100000GC/TM1M0T1T0让我来告诉你答案!答案应该是ATMOD=01100000GC/TM1M0T1T0

C语言 单片机 的时候,怎么写定时中断?

//写了个测试程序,希望对你有帮助#include//写了个测试程序,希望对你有帮助 #include#defineucharunsignedchar ucharm=0,i=0;...

单片机定时器 中断程序怎么写?

在单片机中,定时器中断程序通常需要先初始化定时器的计数值和工作模式,然后编写中断服务程序。在中断服务程序中,需要清除中断标志位、处理需要执行的操作,最...

stc89 c 52 单片机定时器 结构?

STC89C52单片机的定时器结构包括两个定时器,分别为定时器0和定时器1。每个定时器都有一个16位的计数器和一个控制寄存器,用来设置定时器的工作模式、计数器的...

猜你喜欢