dos下串口通信编程.doc
中断向量表INT (Hex) IRQ Common Uses08 0 System Timer09 1 Keyboard0A 2 Redirected0B 3 Serial Comms. COM2/COM40C 4 Serial Comms. COM1/COM3 0D 5Reserved/Sound Card 0E 6 Floppy Disk Controller 0F7 Parallel Comms. 70 8 Real Time Clock71 9 Reserved72 10 Reserved73 11 Reserved74 12 PS/2 Mouse75 13Maths Co-Processor76 14 Hard Disk Drive77 15 Reserved 通过编写COM对应的中断服务程序,我们也可以操作串口,涉及到的相关函数有:(1)设置中断向量表/*dos.h*/void _Cdecl setvect (int interruptno, void interrupt (*isr) ();例如,COM3对应的中断号是4,那么对应中断向量表中的地址是0x0C,设置0x0C对应中断程序的函数为:setvect(0x0C, PORT1INT);其中的中断服务程序PORT1INT为:void interrupt PORT1INT()int c;doc = inportb(PORT1 + 5);if (c &1)bufferbufferin = inportb(PORT1);bufferin+;if (bufferin = 1024)bufferin = 0;while (c &1);outportb(0x20, 0x20);上述中断服务程序检查是否有字符可接收,其后将其通过inportb(PORT1)语句将其从UART中读出并放入输入buffer。持续的检查UART,以便能在一次中断里读取所有可获得的数据。最后的"outportb(0x20,0x20);"语句告诉可编程中断控制器(Programmable Interrupt Controller,PIC)中断已经完成。(2)读取中断向量表/*dos.h*/void interrupt (* _Cdecl getvect(int interruptno) ();例如:oldport1isr = getvect(INTVECT); 其中的oldport1isr定义为:void interrupt (*oldport1isr)();我们融合setvect()函数、中断服务程序和getvect()函数,给出一个由Craig Peacock编写的完备例程:/* Name : Sample Comm's Program - 1024 Byte Buffer - buff1024.c */* Written By : Craig Peacock <cpeacock.au> */#include <dos.h>#include <stdio.h>#include <conio.h>#define PORT1 0x3F8 /* Port Address Goes Here */#define INTVECT 0x0C /* Com Port's IRQ here (Must also change PIC setting) */* Defines Serial Ports Base Address */* COM1 0x3F8 */* COM2 0x2F8 */* COM3 0x3E8 */* COM4 0x2E8 */int bufferin = 0;int bufferout = 0;char ch;char buffer1025;void interrupt(*oldport1isr)();void interrupt PORT1INT() /* Interrupt Service Routine (ISR) for PORT1 */int c;doc = inportb(PORT1 + 5);if (c &1)bufferbufferin = inportb(PORT1);bufferin+;if (bufferin = 1024)bufferin = 0;while (c &1);outportb(0x20, 0x20);void main(void)int c;outportb(PORT1 + 1, 0); /* Turn off interrupts - Port1 */oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector of laterrecovery */setvect(INTVECT, PORT1INT); /* Set Interrupt Vector Entry */* COM1 - 0x0C */* COM2 - 0x0B */* COM3 - 0x0C */* COM4 - 0x0B */* PORT 1 - Communication Settings */outportb(PORT1 + 3, 0x80); /* SET DLAB ON */outportb(PORT1 + 0, 0x0C); /* Set Baud rate - Divisor Latch Low Byte */* Default 0x03 = 38,400 BPS */* 0x01 = 115,200 BPS */* 0x02 = 57,600 BPS */* 0x06 = 19,200 BPS */* 0x0C = 9,600 BPS */* 0x18 = 4,800 BPS */* 0x30 = 2,400 BPS */outportb(PORT1 + 1, 0x00); /* Set Baud rate - Divisor Latch High Byte */outportb(PORT1 + 3, 0x03); /* 8 Bits, No Parity, 1 Stop Bit */outportb(PORT1 + 2, 0xC7); /* FIFO Control Register */outportb(PORT1 + 4, 0x0B); /* Turn on DTR, RTS, and OUT2 */outportb(0x21, (inportb(0x21) &0xEF); /* Set Programmable Interrupt Controller */* COM1 (IRQ4) - 0xEF */* COM2 (IRQ3) - 0xF7 */* COM3 (IRQ4) - 0xEF */* COM4 (IRQ3) - 0xF7 */outportb(PORT1 + 1, 0x01); /* Interrupt when data received */printf("nSample Comm's Program. Press ESC to quit n");doif (bufferin != bufferout)ch = bufferbufferout;bufferout+;if (bufferout = 1024)bufferout = 0;printf("%c", ch);if (kbhit()c = getch();outportb(PORT1, c);while (c != 27);outportb(PORT1 + 1, 0);/* Turn off interrupts - Port1 */outportb(0x21, (inportb(0x21) | 0x10); /* MASK IRQ using PIC */* COM1 (IRQ4) - 0x10 */* COM2 (IRQ3) - 0x08 */* COM3 (IRQ4) - 0x10 */* COM4 (IRQ3) - 0x08 */setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */2007-1-11 20:43:00 回复:dos下的串口编程(硬件中断方式) 今题网友40245(游客)发表评论于2009-8-18 18:54:00你这个程序我在windows的命令行能收发数据,可到了纯dos为什么收发不了?