PC机高号中断编程8259初始化及中断服务程序处理

PC机高号中断编程8259初始化及中断服务程序处理 8259A Initialization and Interrupt Serve Program Processing for Higher IRQ in IBM PC  作者 龚建伟 摘 要 本文对PC机中高号中断(IRQ8~IRQ15)编程时如何初始化8259可编程中断控制器和中断服务程序处理进行了说明,给出了Turbo C++3.0编写的8259初始化程序和中断服务程序实例。 关键词 8259A可编程中断控制器; IBM PC中断编程 在IBM PC及其兼容机中,通过CPU的NMI(非屏蔽中断)和两个8259A可编程中断控制器芯片为系统提供了16级中断,硬件中断结构如图1所示1,两片8259A构成主从式级联控制结构,与CPU相连的称为主片,下一层的称为从片,从片中断请求信号INT与主片的IRQ2相连。IBM PC机中保留给用户可随意编程的中断号有IRQ10、IRQ11、IRQ12和IRQ15,这些中断信号都在8259A从片上。8259A的详细资料请参阅有关手册,本文仅列出大多数PC硬件手册中未提及的编程资料,然后说明PC机中8259A中断控制器的编程初始化过程和如何处理中断服务程序。 图1 IBM PC机中由8259A管理的16级中断均有规定的中断向量存储地址,主片中IRQ0-IRQ7分别对应08H-0FH,从片中IRQ8-IRQ15分别对应70H-77H。主片的中断控制寄存器ICR和中断屏蔽寄存器IMR的口地址分别为20H和21H,从片的相应寄存器口地址分别为A0H和A1H。 中断初始化编程时,当用主片中IRQ0-IRQ7时,只须在屏蔽寄存器中打开相应中断,在中断服务程序中,中断结束后,发一次中断结束命令EOI;而涉及从片中IRQ7-IRQ15高号中断时,除在从片中的屏蔽寄存器中打开相对应的中断,还须打开主片中的IRQ2,且在中断服务程序中中断结束时,要发两次EOI命令,分别使主片和从片执行中断结束命令。下面就IRQ11的初始化和中断服务程序处理给出Turbo C的源代码编程说明。 首先说明一个中断指针oldvect以保存原来的中断向量,在中断服务程序ser_program()结束后,分别向主片和从片的中断控制寄存器ICR送中断结束信号EOI。 void interrupt(*oldvect)(...); file://设置原中断向量保存指针 void interrupt ser_program(...) { {... ...} file://中断服务程序代码 outportb(0xA0,0x20); file://向从片ICR送EOI命令 outportb(0x20,0x20); file://向主片ICR送EOI命令 } 中断初始化时要先保存IRQ11对应的地址73H存储的原中断向量,然后将自己的中断服务程序入口地址装入,再分别打开主片IRQ2和从片IRQ11。 void Interrupt_Enable(void) { int temp; {... ...} file://其它初始化代码 oldvect = getvect(0x73); file://保存原中断向量 setvect(0x73,ser_program); file://装入中断服务程序入口地址 temp = inportb(0x21) & 0xFB;//打开主片IRQ2 outportb(0x21, temp); temp = inportb(0xA1) & 0xF7;//打开从片IRQ11 outportb(0xA1, temp); } 最后,不要忘记在程序关闭前关中断和恢复原中断向量。 void Interrupt_Disable(void) { int temp; setvect(0x73, oldvect); file://恢复原中断向量 temp = inportb(0x21) | ~(0xFB);//关主片IRQ2 outportb(0x21, temp); temp = inportb(0xA1) | ~(0xF7);//关从片IRQ11 outportb(0xA1, temp); } 以上仅给出了初始化和中断服务程序处理的必要源代码,如感兴趣,可与作者联系索要结合多串口中断收发数据的Turbo C++源程序(在Turbo C++3.0下编译),本人在做PC104时用到了多串口。 参考文献 1 Thom Hojam(美). PC软硬件技术资料大全. 清华大学出版社,1990.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
UART串口通信是一种常见的嵌入式系统通信方式,通过串口通信可以实现MCU与其他设备之间的数据传输。在使用UART串口通信时,需要先对UART构件进行初始化,设置波特率、数据位、停止位、校验位等参数,然后就可以使用UART发送和接收数据了。 中断处理是嵌入式系统中常用的一种软件技术,通过中断处理可以实现异步事件的响应和处理。在使用中断处理时,需要先对中断进行初始化,设置中断触发条件和中断服务函数,然后在程序运行中,当中断触发条件满足时,中断服务函数就会被调用进行处理。 下面是一个简单的串口通信及中断实验的程序示例,该程序实现了MCU通过UART串口与PC机进行通信,并且使用中断处理来响应串口接收事件。 ```C #include <reg52.h> #include <stdio.h> #define FOSC 11059200L #define BAUD 9600 #define TIMER_1MS (65536-FOSC/12/1000) sbit LED = P1^0; sbit UART_Tx = P3^1; sbit UART_Rx = P3^0; char buffer[32]; unsigned char flag = 0; void UART_Init(); void Timer0_Init(); void Interrupt_Init(); void UART_SendByte(char dat); void UART_SendString(char *s); void main() { UART_Init(); Timer0_Init(); Interrupt_Init(); while(1) { if(flag) { flag = 0; if(buffer[0] == '1') { UART_SendString("My name is AI.\r\n"); LED = 1; } else if(buffer[0] == '0') { UART_SendString("My student ID is 123456.\r\n"); LED = 0; } } } } void UART_Init() { TMOD &= 0x0F; TMOD |= 0x20; TH1 = TL1 = -(FOSC/12/32/BAUD); TR1 = 1; ES = 1; EA = 1; } void Timer0_Init() { TMOD &= 0xF0; TMOD |= 0x01; TH0 = TIMER_1MS/256; TL0 = TIMER_1MS%256; TR0 = 1; } void Interrupt_Init() { ET0 = 1; } void UART_SendByte(char dat) { SBUF = dat; while(!TI); TI = 0; } void UART_SendString(char *s) { while(*s) { UART_SendByte(*s++); } } void UART_ISR() interrupt 4 { if(RI) { RI = 0; buffer[0] = SBUF; } if(TI) { TI = 0; } } void Timer0_ISR() interrupt 1 { static unsigned int cnt = 0; TH0 = TIMER_1MS/256; TL0 = TIMER_1MS%256; cnt++; if(cnt >= 1000) { cnt = 0; flag = 1; } } ``` 程序流程: 1. 初始化UART串口通信模块,并设置波特率为9600; 2. 初始化定时器0,并设置定时器计数值为1ms; 3. 初始化中断服务函数,并开启中断; 4. 进入主函数,等待串口接收事件的触发; 5. 当串口接收事件触发时,中断服务函数会将接收到的数据存储到buffer数组中,并将flag标志位设置为1; 6. 主函数检测到flag标志位被设置为1后,判断接收到的数据是字符'1'还是'0',并分别回送自己的真实姓名和学号,并控制LED灯的状态; 7. 定时器0每隔1ms触发一次中断,计数器cnt累加,当cnt累加到1000时,将flag标志位设置为1,表示已经等待了1秒。 程序运行结果: ![串口通信及中断实验运行结果截图](https://img-blog.csdnimg.cn/20211211004256529.png)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值