汇编语言第十三章-int中断

本文详细介绍了汇编语言中的int中断指令及其应用,包括int中断的执行过程、编写及安装中断例程的方法,并通过具体实例展示了如何利用int指令实现特定功能。此外,还探讨了BIOS和DOS中断例程的安装与应用。

本博文系列参考自<<汇编语言>>第三版,作者:王爽


本博文将继续介绍另外一种内中断类型,int中断。


13.1 int中断
int指令格式为:int n,其中n为中断类型码。
int n中断过程如下:
取中断类型码n
标志寄存器入栈,TF=0,IF=0
CS,IP入栈
(CS)=(n*4),(IP)=(n*4+2)
 
上面的代码段运行后将在屏幕中间显示一个’!’,然后再显示一个”divide overflow”,这里符号”!”的显示是我们通过编程实现的。而字符串“divide overflow”则是通过int 0指令执行第0号中断处理程序,而系统设置的第0号中断处理程序则是显示字符串“divide overflow”。显示之后再回到dos系统。
可见int指令与call指令类型,都是调用一段程序。

后面我们将中断处理程序称为中断例程。


13.2编写供应用程序调用的中断例程
问题:编写,安装7CH的中断例程
功能:要求一word类型数据的平方
参数:(ax)=要计算的数据
返回值:dx,ax中存放结果的高16位和低16位
举例:2*3456^2
 
分析一下,我们主要要做三部分的工作:
编写程序,实现求平方的功能
安装程序,将其安装在0200处
设置中断向量表,将程序的入口地址保存在7ch表项中,使其成为中断7ch的中断例程。
安装程序如下:

assume cs:code
code segment
start : mov ax,cs
mov ds,ax
mov si,offset sqr
mov ax,0
mov es,ax
mov di,200h
mov cx,offset sqrend-offset sqr
cld
rep movsb


mov ax,0
mov es,ax
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0


mov ax,4c00h
int 21h
sqr:    mul ax
          iret
sqrend: nop
code ends
end start



注意在中断例程sqr最后要使用iret指令,iret指令的功能为:
pop IP
pop CS
popf

CPU在执行7ch例程之前,标志寄存器,CS与IP入栈,在执行完中断例程后,用iret来恢复CS和IP以及标志寄存器。从而接着执行应用程序。
call指令与ret指令配合使用同int指令与iret指令配合使用方式类似。



13.3对int、iret和栈的深入理解
问题:用7ch中断例程完成loop指令的功能。
Loop指令的执行需要两个信息,循环次数和到S的位移。所以,7ch中断例程要完成loop指令的功能,也需要这两个信息作为参数。用cx存放循环次数,bx存放位移。
应用举例:在屏幕中间显示80个’!’
 
上面的程序中,int 7ch调用7ch中断例程进行转移,用bx传递转移的位移。
分析:为了模拟loop指令,7ch中断例程应
具有如下功能。
dec cx
如果(cx)!=0,转到标号s处执行,否则向下执行。
下面我们分析7ch中断例程如何实现目的地址的转移:
转到标号s显然应设(CS)=标号s的段地址,(IP)=标号s的偏移地址
那么,中断例程如何得到标号s的段地址和偏移地址呢?
Int 7ch进入中断例程,在中断过程中会将CS和IP压栈,此时CS和IP的内容为调用程序的段地址和int 7ch后一条指令的偏移地址。
现在知道如何从栈中间接的获取CS和IP,那么如何用它们来设置CS:IP呢?
可以利用iret指令,我们将栈中se的偏移地址加上bx中的转移位移。则栈中se的偏移地址就变成了s的偏移地址。我们再使用iret指令,用栈中的内容设置CS和IP,从而实现转移到标号处。
7ch的中断例程如下:

	lp:push bp
	    mov bp,sp
	    dec cx
	    jcxz lpret
	    add [bp+2],bx
     lpret:pop bp
           iret


因为要访问栈,使用了bp,在程序开始处将bp入栈保存,结束时出栈恢复。当要修改栈中se的偏移地址的时候,栈的情况为:栈顶为bp原来的值,下面是se的偏移地址,再下面是s的段地址,再下面是标志寄存器的值。而此时,bp中为栈顶的偏移地址,所以((ss)*16+(bp)+2)处为se的偏移地址,将它加上bx中的转移位移就变成s的偏移地址。最后用iret出栈返回,CS:IP即从标号处开始执行。

如果(cx)=0,则不需要修改栈中se的偏移地址,直接返回即可。CPU从标号se处向下开始执行。


13.4  BIOS和DOS所提供的中断例程
在电脑主板的ROM中有一套程序,称为BIOS,BIOS主要包含以下几个部分:
硬件系统的检测和初始化程序;
外部中断和内部中断的中断例程
用于对硬件设备进行I/O操作的中断例程
其他和硬件系统相关的中断例程
操作系统DOS也提供了中断例程,从操作系统的角度看,DOS中断例程就是操作系统向程序员提供编程资源。

BIOS和DOS所提供的中断例程包含了很多子程序,这些子程序实现了程序员在编程的时候经常用到的功能。程序员在编程的时候,可以用Int指令调用bios或者dos提供的中断例程。


13.5  BIOS和DOS中断例程的安装过程
(1)开机后,CPU加电。初始化(CS)=0FFFFH,(IP)=0,自动从FFFF:0单元开始执行程序。FFFF:0处有一条跳转指令,CPU执行该指令后,转去执行BIOS中的硬件检测和初始化程序。
(2)初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中,注意:对BIOS所提供的中断例程,只需要将入口地址等级在中断向量表中即可,因为他们是固化到ROM中,一直在内存中运行。
(3) 硬件检测和初始化完成后,执行int 19h进行系统引导,将计算机交给操作系统控制
(4)DOS启动后将其提供的中断例程装入内存,并建议相应的中断向量。



13.6  BIOS中断例程应用
Int 10h中断向量是BIOS提供的中断例程,其中包含多个和屏幕输出相关的子程序。一般来说中断例程用传入的参数来区别到底调用哪个子程序,BIOS和DOS提供的中断例程,都用ah来传递内部子程序的编号。
下面是int 10h中断例程设置光标位置:
 
(ah)=2表示调用10h中断例程的二号子程序,设置光标位置。
(bh)=0,(dh)=5,(dl)=12 设置光标第0页,第5行,第12列
bh中页号的含义:内存地址空间中,B8000H~BFFFFH共32kb的空间,为80*25彩色字符模式的显示缓冲区,一屏的内容在缓冲区为4000字节。显示缓冲区为8页,每页大概4kb,一般情况显示第0页。
13.7  DOS中断例程应用
Int  21h中断例程是dos提供的中断例程,其中包含了DOS提供给程序员在编程时调用的子程序。
前面我们经常使用

Mov ax,4c00h
Int 21h

(ah)=4ch表示调用21h中断例程的4ch号功能,(al)=00h为返回值。
再比如:使用21h中断例程在光标处显示字符:

ds:dx 指向字符串
mov ah,9
int 21h

(ah)=9表示调用21h号中断例程的9号子程序,功能为在光标位置显示字符串,可以提供要显示字符串的地址作为参数。


<think> 我们正在讨论MPU6050的INT中断使用方法。根据提供的引用内容,我们可以总结如下: 1. **中断配置步骤**:引用[1]和[3]提供了配置中断的寄存器的示例代码。主要涉及以下几个寄存器: - `INT_PIN_CFG`(中断引脚配置寄存器):用于设置中断引脚的电平触发方式(高电平或低电平)以及输出模式(推挽或开漏)。 - `INT_ENABLE`(中断使能寄存器):用于使能特定的中断源,比如数据就绪中断、运动检测中断等。 - 此外,还需要配置传感器的工作模式(如采样率、量程等)和电源管理。 2. **中断类型**: - **数据就绪中断**:当新的传感器数据准备好时触发中断(如引用[2]所述)。 - **运动检测中断**:当检测到运动时触发中断(如引用[3]所示)。 3. **关键配置**: - 设置中断引脚的电平逻辑:通过`INT_PIN_CFG`寄存器设置。例如,引用[1]中设置为0x80(即最高位为1,表示中断信号为低电平时有效)。而引用[3]中设置为0x10(表示高电平有效,推挽输出)。 - 使能中断:通过`INT_ENABLE`寄存器。例如,使能数据就绪中断(通常对应位0)或运动检测中断(位6)。 4. **初始化流程**(综合引用内容): - 复位MPU6050(写`PWR_MGMT_1`寄存器为0x80,延时,再写0x00唤醒)。 - 配置传感器量程和采样率(引用[1]和[3])。 - 关闭所有中断(`INT_ENABLE`写0x00)和FIFO(如果需要)。 - 配置中断引脚(`INT_PIN_CFG`)和中断使能(`INT_ENABLE`)。 - 最后,根据需求设置其他寄存器(如电源管理、时钟源等)。 5. **使用中断的目的**: - 减少MCU轮询负担,提高效率。 - 在数据就绪时及时读取数据(如引用[2]和[4]提到的平衡小车应用)。 - 用于唤醒休眠中的MCU(如引用[3])。 现在,我们根据以上信息,整理MPU6050使用INT中断的方法(步骤): </think> ### MPU6050 INT中断使用方法 MPU6050的INT中断功能用于实时通知MCU传感器数据准备就绪或触发特定事件。以下是配置步骤和关键要点(基于引用内容整合): --- ### **1. 中断初始化步骤** #### (1) 硬件连接 - 将MPU6050的`INT`引脚连接至MCU的GPIO中断引脚(如STM32的EXTI)。 - 确保I²C通信正常(SCL/SDA引脚连接正确)。 #### (2) 寄存器配置流程 ```c // 复位MPU6050 MPU_Write_Byte(MPU6050_RA_PWR_MGMT_1, 0x80); // 复位命令 delay_ms(100); // 等待复位完成 MPU_Write_Byte(MPU6050_RA_PWR_MGMT_1, 0x00); // 唤醒设备[^1] // 配置传感器量程 MPU_Set_Gyro_Fsr(3); // 陀螺仪±2000dps MPU_Set_Accel_Fsr(0); // 加速度计±2g[^1] // 设置采样率(200Hz示例) MPU_Set_Rate(200); // 采样率=时钟/(1+SMPLRT_DIV) MPU_Write_Byte(MPU6050_RA_SMPLRT_DIV, 39); // 200Hz计算:8MHz/(1+39)=200Hz[^2] // 配置中断引脚逻辑 MPU_Write_Byte(MPU6050_RA_INT_PIN_CFG, 0x10); // 0x10: 高电平有效 + 推挽输出[^3] // 可选:0x80=低电平有效[^1] // 使能中断类型 MPU_Write_Byte(MPU6050_RA_INT_ENABLE, 0x01); // 0x01: 数据就绪中断(Data Ready)[^2] // 0x40: 运动检测中断(Motion Detect)[^3] ``` --- ### **2. 中断类型说明** | 中断类型 | 寄存器值 | 功能描述 | |-----------------|----------|------------------------------| | **数据就绪中断** | `0x01` | 新传感器数据生成时触发[^2] | | **运动检测中断** | `0x40` | 加速度超过阈值时触发[^3] | | **FIFO溢出中断** | `0x10` | 数据缓冲区溢出时触发 | --- ### **3. MCU端中断处理** #### (1) STM32配置示例(以数据就绪中断为例) ```c // 初始化EXTI中断(下降沿触发) HAL_GPIO_Init(INT_GPIO_Port, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTIx_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTIx_IRQn); // 中断服务函数 void EXTIx_IRQHandler(void) { if (__HAL_GPIO_EXTI_GET_FLAG(INT_Pin)) { __HAL_GPIO_EXTI_CLEAR_FLAG(INT_Pin); // 读取传感器数据 MPU_Read_Accel(...); // 读取加速度 MPU_Read_Gyro(...); // 读取陀螺仪 } } ``` #### (2) 唤醒休眠MCU ```c // 配置中断唤醒休眠(参考引用[3]) MPU_Write_Byte(MPU6050_RA_INT_PIN_CFG, 0x10); // 高电平有效 MPU_Write_Byte(MPU6050_RA_INT_ENABLE, 0x40); // 使能运动检测中断 ``` --- ### **4. 常见问题解决** - **中断引脚无响应** 1. 检查`INT_PIN_CFG`配置(0x80=低电平,0x10=高电平)[^1][^3] 2. 确认`INT_ENABLE`已使能目标中断源 3. 验证MCU端GPIO中断配置(上拉/下拉电阻需匹配INT电平) - **中断触发频率异常** 调整`SMPLRT_DIV`寄存器:$$ \text{采样率} = \frac{\text{时钟源}}{1 + \text{SMPLRT\_DIV}} $$ 例如:8MHz时钟源需设`SMPLRT_DIV=39`以获得200Hz中断[^2]。 --- ### **5. 应用场景** 1. **平衡小车**:实时读取姿态角(Pitch/Roll)[^4] 2. **低功耗设备**:休眠时通过运动检测中断唤醒MCU[^3] 3. **姿态解算**:结合DMP模块获取四元数后转换为欧拉角[^4]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值