单片机中断服务函数写法
- 格式:docx
- 大小:20.09 KB
- 文档页数:4
几种单片机的中断函数写法写单片机程序,中断是免不了的。
我比较喜欢用C写单片机程序,简单而且可读性高,当然程序效率没有汇编的高。
目前写过51单片机跟AVR单片机的C程序,最近在看MSP430的书。
用C写不同的单片机程序其实都是大同小异,因此能对不熟悉的单片机也能很快上手写程序。
不过中断函数的写法,各个编译器往往都会有些差别。
最早写的C程序是51单片机的,用的编译器自然是大名鼎鼎的keil c了。
Keil的功能还是非常强劲的,不仅能编译,还有软件仿真调试与硬件调试的功能。
由于条件简陋,没用过什么仿真器,一直都是靠软件仿真调试程序的。
Keil 中的中断函数一般格式如下:void 函数名() interrupt n using n{…….}其中函数名可以任意取,关键字interrupt用来指明这是一个中断服务函数,后面的n 表示中断号,关键字using加后面的n表示使用哪一组寄存器。
后然接触到AVR的单片机,该单片机开发环境一般用ICC或者是GCC。
由于ICC是商用软件,而GCC是免费的,因此我一般用GCC来写AVR的C程序。
现在版本的GCC for AVR有了一些改进,对于中断函数支持两种关键字ISR与SIGNAL,其格式如下:ISR(vect){………}与SIGNAL(vect){……..}其中的vect就是中断向量名,根据不同的型号的AVR单片机的不同的中断源都会有相对应的中断向量名,比如外部中断0对于ISR格式的中断向量名为INT0_vect,对SIGNAL则为SIG_INTERRUPT0。
最近在看TI的MSP430系列单片机的资料,看到该单片机采用C430写的中断服务函数有点像前两种的综合,其格式如下:interrupt [vect] void 函数名(void){…….}其中vect也是中断向量名,函数名可以任取。
比较这几种中断函数写法,本人更倾向于AVR的GCC的写法。
首先对于中断函数来说即不能有输入参数又没有返回值,没必要再给它加个“void 函数名(void)”的形式的函数。
C语言的中断服务函数中断服务函数是一种特殊的函数,用于处理系统或外设发生的中断事件。
在C语言中,中断服务函数常用于嵌入式系统的开发中,用于实现硬件的响应和处理。
下面是关于C语言中断服务函数的详细介绍,包括定义、注册、实现和应用等方面。
一、中断服务函数的定义中断服务函数(Interrupt Service Routine,ISR)是一段特殊的代码,用于响应和处理中断事件。
它与普通的函数不同,不是由程序主动调用的,而是由系统或硬件触发的。
中断事件一般包括硬件的输入、定时器的溢出、软件触发等。
在C语言中,中断服务函数的定义方式与普通的函数类似,但需要使用特殊的关键字和参数。
如下是一个C语言中断服务函数的定义示例:```void interrupt_service_functio//中断处理代码```在上述示例中,`void`表示中断服务函数不返回值,`interrupt_service_function`是函数的名称。
根据不同的开发平台和编译器,中断服务函数的定义可能有所不同。
二、中断服务函数的注册要使用一个中断服务函数,需要将其注册到相应的中断源中。
中断源可以是系统的中断控制器,也可以是外设的中断引脚。
注册中断服务函数的目的是告诉系统,在相应中断事件发生时调用该函数。
以8051单片机为例,注册中断服务函数的方式如下所示:```void mairegister_interrupt_service_function(interrupt_service_functi on);//其他代码```在上述示例中,`register_interrupt_service_function`是用于将中断服务函数`interrupt_service_function`注册到系统中断控制器的函数。
在实际开发中,不同平台和配置会有不同的注册方式。
三、中断服务函数的实现中断服务函数的实现主要包括对中断事件的处理和相应操作。
中断服务函数的实现需要了解特定硬件的中断机制和相关的寄存器操作。
中断函数的使用:《单片机C语言编程与实例》中断函数通过使用interrupt关键字和中断编号0-4来实现。
使用该扩展属性的函数声明语法如下:返回值函数名interrupt nN对应中断源的编号中断编号告诉编译器中断程序的入口地址,它对应者IE寄存器中的使能位,即IE寄存器中的0位对应着的外部中断0,相应的外部中断0的中断编号是0。
当正在执行一个特定任务是,可能有更紧急的事情需要CPU处理,这就涉及到终端优先级,搞优先级的中断可以中断正在处理的底有限级中断程序,因而最好给每种优先级分配不同的寄存器组。
在c51中可以使用using制定的寄存器组,using后的变量为0-3的长整数,分别表示51单片机内的四个寄存器组。
中断函数的完整语法及实例如下:返回值函数名(【参数】)【模式】【重入】interrupt n [using n] Unsigned int interruptent;Unsigned char second;V oid time0(void)interrupt 1 using 2{if(++interruptent==4000) %计数到4000{second++; % 另一个计数器Interruptent=0; %计数器清零}}要是摸个中断源的申请得到相应,必须保证EA=1和相应的允许位为1定义中断服务函数的一般形式为::函数类型函数名(形式参数表)[interrupt n][using n]Interrupt 后面的n是中断号,n的取值范围为0-31,编译器从8n+3处产生中断向量。
11.111111外部中断例题:通过P1.7口电量发光二极管,然后外部输入一脉冲串,则发光二极管亮、暗交替#include <REGX51.H>Sbit P1_7=P1^7;V oid tnterrupt0()interrupt 0 using 2//定义定时器0{ P1_7=!P1^7;}V oid main(){EA=1;//开启总中断IT0=1;//外部中断0低电平触发EX0=1; //外部中断0P1_7=0;Do()while(1);}2222相套中断外部中断INT1触发后,启动计数器0,计数达到10次后停止计数,启动定时器1,由定时器1控制定时,由P1.7输出周期为200ms的方波性能好,接受2次中断后关闭方波发生器,P1.7置低。
STM32的中断函数和回调函数是两种不同的函数类型,它们在嵌入式系统中有着广泛的应用。
1. 中断函数:
中断函数通常用于处理实时事件或外部信号。
当某个事件发生时,中断控制器会打断正在执行的程序,跳转到中断处理函数中执行相应的操作。
在STM32中,中断处理函数通常被定义为ISR (Interrupt Service Routine)。
ISR应该尽可能地简短快速,避免在中断处理函数中进行复杂的计算或逻辑处理。
中断函数的定义通常如下:
```c
void ISR() interrupt 1 // 1表示中断号
{
// 中断处理代码
}
```
其中,`interrupt`后面的数字表示中断号,用于区分不同的中断。
2. 回调函数:
回调函数是一种通用的事件处理机制。
它通常用于将某个函数作为参数传递给另一个函数,当事件发生时,调用传递的函数进行相应的处理。
回调函数通常被定义为一个指针类型,指向一个具有特定参数和返回值的函数。
回调函数的定义通常如下:
```c
typedef void (*Callback)(int event); // 定义回调函数类型
void function(Callback callback) // 传递回调函数作为参数{
// 执行一些操作
// 当事件发生时,调用callback函数进行处理
callback(event);
}
```
其中,`Callback`是一个指向函数的指针类型,`event`是传递给回调函数的参数。
在`function`函数中,可以调用传递的回调函数进行事件处理。
单片机_C语言函数_中断函数(中断服务程序)在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。
中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就不讲了,首先来回忆下中断系统涉及到哪些问题。
(1)中断源:中断请求信号的来源。
(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个横杠不知道怎么加上去))(2)中断响应与返回:CPU采集到中断请求信号,怎样转向特定的中断服务子程序,并在执行完之后返回被中断程序继续执行。
期间涉及到C PU响应中断的条件,现场保护,现场恢复。
(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(外部中断IN T0请求标志位)和IE1由硬件自动清零;在电平触发方式下,不能自动清楚IE0和I E1。
c51中断函数的介绍C51编译器允许用c51创建中断服务程序,大家仅仅需要关心中断号和寄存器组的选择就可以了。
编译器自动产生中断向量和程序的入栈及出栈代码。
在函数声明时包括interrupt,将把所声明的函数定义为一个中断服务程序。
另外,可以用using定义此中断服务程序所使用的寄存器组。
一、中断函数的定义1、中断函数定义的格式为:函数类型函数名interrupt n using n其中:Interrupt后面的n是中断号。
关键字using后面的n是所选择的寄存器组,取值范围是0-3.定义中断函数时,using是一个选项,可以省略不用。
如果不用则由编译器选择一个寄存器组作为绝对寄存器组。
2、8051的中断过程通过使用interrupt关键字和中断号来实现,中断号告诉编译器中断程序的入口地址。
中断号对应着IE寄存器中的使能位,换句话说,IE 寄存器中的0位对应着外部中断0,相应的外部中断0的中断号是0.IE寄存器中的使能位与外部中断对应关系:中断号中断源0 外部中断01 定时器02 外部中断13 定时器1中断4 串行口中断5 定时器2中断二、使用中断函数时要注意的问题:1. 在设计中断时,要注意的是哪些功能应该放在中断程序中,哪些功能应该放在主程序中。
一般来说中断服务程序应该做最少量的工作,这样做有很多好处。
首先系统对中断的反应面更宽了,有些系统如果丢失中断或对中断反应太慢将产生十分严重的后果,这时有充足的时间等待中断是十分重要的。
其次它可使中断服务程序的结构简单,不容易出错。
中断程序中放入的东西越多,他们之间越容易起冲突。
简化中断服务程序意味着软件中将有更多的代码段,但可把这些都放入主程序中。
中断服务程序的设计对系统的成败有至关重要的作用,要仔细考虑各中断之间的关系和每个中断执行的时间,特别要注意那些对同一个数据进行操作的ISR.2. 中断函数不能传递参数。
3. 中断函数没有返回值。
4. 中断函数调用其他函数,则要保证使用相同的寄存器组,否则出错。
c2000中断程序代码C2000系列微控制器是德州仪器(TI)推出的一款高性能的32位微控制器,其中断服务程序是用来处理硬件中断的。
在C2000系列微控制器中,中断服务程序的编写一般包括以下几个步骤:1. 中断向量表设置,首先需要在程序的起始处设置中断向量表,将各个中断源对应的中断服务程序入口地址填入中断向量表中。
2. 中断服务程序编写,针对特定的中断源,编写相应的中断服务程序。
在C2000系列微控制器中,中断服务程序需要使用特定的关键字来声明,以确保编译器正确识别。
3. 中断使能,在初始化阶段,需要将特定的中断源使能,以确保当中断事件发生时,CPU能够响应并跳转到相应的中断服务程序执行。
4. 中断处理,在中断服务程序中,需要根据具体的中断源进行相应的处理,可能涉及到清除中断标志、读取相关寄存器状态、执行特定的操作等。
下面是一个简单的C2000中断服务程序的伪代码示例: c.#pragma CODE_SECTION(ISR, "ramfuncs");interrupt void ISR(void)。
{。
// 中断服务程序的具体内容。
// ...// 清除中断标志。
PieCtrlRegs.PIEACK.bit.ACK1 = 1;}。
void main(void)。
{。
// 初始化。
// ...// 使能中断。
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // 使能中断源INT7。
// 启用全局中断。
EINT;// 主循环。
while(1)。
{。
// 主循环内容。
// ...}。
}。
在这个示例中,我们定义了一个名为ISR的中断服务程序,并使用#pragma CODE_SECTION将其放置在RAM中,以提高执行速度。
在main函数中,我们将INT7中断源使能,并在主循环中等待中断事件的发生。
需要注意的是,实际的中断服务程序的编写可能涉及到更多的细节,比如中断优先级设置、中断嵌套处理、中断向量表的具体设置等。
单片机编程中的常用函数在单片机编程中,常用函数是我们编写程序时经常使用到的函数。
这些函数不仅能够减少我们的工作量,还能提高程序的效率和可读性。
下面将介绍单片机编程中常用的几种函数。
一、延时函数延时函数是单片机编程中非常常用的函数之一,它可以在程序中引入适当的延时,以确保程序能够按照我们的期望进行运行。
延时函数通常使用定时器或者循环来实现。
下面是一个简单的延时函数示例:```cvoid delay(unsigned int ms){unsigned int i, j;for(i = 0; i < ms; i++)for(j = 0; j < 114; j++);}```在这个延时函数中,我们使用两个循环来进行延时操作。
内层循环是一个简单的计数器,当计数器达到一定值时,延时一毫秒。
外层循环控制延时的总时长。
通过调整内层循环的计数器初值,可以实现不同的延时时长。
二、IO口控制函数在单片机编程中,我们经常需要对IO口进行控制操作,例如点亮LED灯、控制继电器等。
为了简化这些操作,可以使用IO口控制函数。
下面是一个简单的IO口控制函数示例:```cvoid GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal){if(BitVal)GPIOx->ODR |= GPIO_Pin;elseGPIOx->ODR &= ~GPIO_Pin;}```这个函数接收三个参数,分别为GPIO端口、GPIO引脚和操作位的值。
通过判断操作位的值,可以实现对相应的GPIO引脚进行设置或清零操作,从而实现对IO口的控制。
三、定时器中断函数定时器中断函数是单片机编程中非常重要的函数之一,它可以在定时器溢出时触发相应的中断服务程序(ISR),从而实现定时任务。
下面是一个简单的定时器中断函数示例:```cvoid TIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){// 定时器中断处理代码TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除中断标志位}}```在这个定时器中断函数中,我们首先判断定时器是否发生了溢出事件。
在STM32微控制器上使用FreeRTOS实时操作系统时,中断服务例程(ISR)的写法需要遵循一定的规范,以确保中断处理能够在不同的任务之间正确地进行。
以下是一些基本步骤和注意事项,用于在FreeRTOS中实现中断服务例程:1. **中断向量表初始化**:在系统启动时,需要初始化中断向量表,将中断处理函数的地址映射到相应的中断号上。
2. **中断优先级设置**:在FreeRTOS中,可以通过NVIC(嵌套向量中断控制器)设置中断的优先级。
在中断服务例程中,可以使用`HAL_NVIC_SetPriority`函数设置优先级。
3. **中断使能**:在中断服务例程编写完成后,需要使用`HAL_NVIC_EnableIRQ`或`HAL_NVIC_Enable`函数使能中断。
4. **中断服务例程的原型**:中断服务例程应该有一个原型,其中包含了中断号和中断服务例程的函数指针。
5. **在中断服务例程中保护现场**:在进入中断服务例程之前,应该保存CPU的状态,包括程序计数器和其他必要的寄存器,以防止中断服务例程被其他中断打断。
6. **中断服务例程的退出**:在中断服务例程结束时,应该恢复之前保存的状态,并使用`HAL_NVIC_DisableIRQ`或`HAL_NVIC_Disable`函数禁用中断。
7. **使用FreeRTOS的API**:如果需要在中断服务例程中使用FreeRTOS的API,比如创建任务、等待消息等,应该确保这些操作不会导致中断被禁止的时间过长,以免影响系统的响应性。
以下是一个简单的STM32中断服务例程的示例代码:```cvoid EXTI0_IRQHandler(void) {// 保存状态HAL_NVIC_DisableIRQ(EXTI0_IRQn); // 禁用中断// 中断处理逻辑// ...// 恢复状态HAL_NVIC_EnableIRQ(EXTI0_IRQn); // 使能中断} ```。
t0中断服务函数的书写方法在嵌入式系统中,中断是一种非常重要的机制,它可以让CPU在执行程序的同时,及时响应外部事件的发生。
而t0中断是一种定时器中断,它可以周期性地触发中断服务函数的执行。
在本文中,我们将介绍t0中断服务函数的书写方法。
1. 中断服务函数的定义中断服务函数是一种特殊的函数,它的执行是由中断触发的。
在t0中断中,中断服务函数的名称通常为“t0_isr”,它的定义如下:void t0_isr(void) interrupt 1{// 中断服务函数的代码}其中,void表示该函数没有返回值,interrupt 1表示该函数是由中断1触发的。
在8051单片机中,t0中断的中断号为1。
2. 中断服务函数的功能t0中断服务函数的主要功能是处理定时器中断。
在t0中断中,定时器的计数器会溢出,当计数器溢出时,就会触发中断。
中断服务函数需要在中断发生时,及时处理定时器中断,并清除中断标志位,以便下一次中断的触发。
下面是一个简单的t0中断服务函数的例子:void t0_isr(void) interrupt 1{// 处理定时器中断// 清除中断标志位TF0 = 0;}在这个例子中,我们只是简单地清除了中断标志位。
实际上,中断服务函数的功能可能会更加复杂,例如读取传感器数据、控制外设等。
3. 中断服务函数的注意事项在编写t0中断服务函数时,需要注意以下几点:(1)中断服务函数需要尽可能地短小精悍,以便尽快地完成中断处理,并返回到主程序中。
(2)中断服务函数中不应该使用延时函数或者阻塞函数,因为这些函数会占用CPU的时间,导致系统响应变慢。
(3)中断服务函数中不应该使用浮点运算,因为浮点运算需要较长的时间,会影响系统的响应速度。
(4)中断服务函数中不应该使用全局变量,因为全局变量可能会被主程序和中断服务函数同时访问,导致数据不一致。
(5)中断服务函数中可以使用局部变量,但是需要注意变量的生命周期,以免出现变量被销毁的情况。
单片机中断服务函数写法
一、在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。
(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.。