精华内容
下载资源
问答
  • Dos串口编程

    2019-01-25 13:55:58
    Dos串口编程串行通信使用单条数据线代替了并行通信的8位数据线,传输的距离更远。通信接口每次从CPU得到8位数 据,然后通过一个并行入串行出的移位寄存器,转换成串行位,每次发送一位,将数据发送出去。同样,在接 ...
  • dos串口调试工具,串口抓包程序

    热门讨论 2011-06-22 17:18:29
    dos串口调试工具,串口抓包程序,难得的dos工具
  • DOS串口测试工具

    2017-06-09 12:53:59
    DOS下测试串口的工具。
  • DOS串口编程

    千次阅读 2008-12-24 11:53:00
    DOS串口编程2008-12-17 21:26DOS串口编程第一章 串行通信接口串行通信使用单条数据线代替了并行通信的8位数据线,传输的距离更远。通信接口每次从CPU得到8位数据,然后通过一个并行入串行出的移位寄存器,转换成串行...
    DOS串口编程
    2008-12-17 21:26

    DOS串口编程

    第一章 串行通信接口
    串行通信使用单条数据线代替了并行通信的8位数据线,传输的距离更远。通信接口每次从CPU得到8位数据,然后通过一个并行入串行出的移位寄存器,转换成串行位,每次发送一位,将数据发送出去。同样,在接收端也必须有一个串行入并行出的移位寄存器来接收串行数据。并组合打包成一个字节。

    以串行方式进入数据线的是由0和1组成的数据,一组这样的数叫做一个字符,一个字符可能有8位,或者7位,6位,5位。在传输中,每个字符都要加上起始位和终止位,起始位总是1位,终止位可以是1位或2位。为了保证传输数据的正确性,有时还包括一位效验位。一般芯片都允许编程时设定效验方式为奇效验,偶效验或者无效验。

    串行通信的数据传输速率用bps(bits per second)来表示。另外,还有一种表示信号传输速率的单位是波特率(band rate)。波特率是一种信号调制单位,和bps不一定相等,它定义每秒钟传输的离散信号的数目。所谓的离散信号,就是指不均匀的,不连续的也不相关的信号。更详细的讲解请查阅相关文档。通信端口的传输速率从110bps到115200bps,经验表明,波特率相当于9600bps的时候,传输相当稳定。

    1960年电子工业协会(Electronics Industries Association,EIA)制定了RS-232接口标准,以后又陆续发布了修订版本,这是目前广泛应用于个人计算机上的串行接口,用于近程数据通信,连接一些外部设备。下图就是我们经常用到的9针RS-232插头,
    每个引脚的定义为:
    引脚
    方向
    名称
    描述
    含义
    1
    输入
    CD
    Carrier Detect
    数据载波检测
    2
    输入
    RXD
    Receive Data
    数据接收端
    3
    输出
    TXD
    Transmit Data
    数据发送端
    4
    输出
    DTR
    Data Terminal Ready
    数据终端准备就绪(计算机)
    5
    -
    SG
    System Ground
    信号地
    6
    输入
    DSR
    Data Set Ready
    数据设备准备就绪
    7
    输出
    RTS
    Request to Send
    请求发送(计算机要求发送数据)
    8
    输入
    CTS
    Clear to Send
    清除发送(MODEM准备接收数据)
    9
    输入
    RI
    Ring Indicator
    响铃指示

    以上信号在通信过程中可能会被全部或者部分使用,把两台计算机通过串口连接起来,最简单的通讯仅需TXD及RXD及SG即可完成。


    第二章 端口设置
    IBM PC和80x86兼容机可以连接4个串行端口,即COM1~COM4,相应的BIOS中的编号为COM0~COM3,但程序每次只能对其中一个端口进行存取。计算机启动时,自检程序就会测试4个COM端口是否存在,并把每个COM端口的I/O地址写到BIOS的数据区0040:0000~0040:0007共8个字节,每个COM地址占用2个字节。如果系统没有连接串行端口,BIOS数据区的这几个单元内容就成为0。用debug可以查看COM端口地址。

    C>debug
    -d 0040:0000 L08
    0040:0000 F8 03 F8 02 E8 03 E8 02

    上例查看结果表明系统中有4个COM端口,对应I/O地址分别为3F8,2F8,3E8,2E8。每个COM端口都包括一组8位的寄存器,这四个地址都叫做基地址,也就是第一个寄存器的I/O地址,其他寄存器的地址按照递增的顺序排列。COM1的基地址是3F8,COM2的基地址是2F8,COM3的基地址是3E8,COM4的基地址是2E8。我们通过这些寄存器编程控制数据接收或者发送。

    COM1及COM3使用PC机中断4,COM2及COM4使用中断3。

    第三章 寄存器
    1 寄存器组
    COM端口的寄存器组如下表所示,共有12个寄存器,使用了8个地址,其中部分寄存器共用一个地址,由DLAB=0/1来区分。DLAB是线路控制寄存器的第7位。

    基地址
    读/写
    寄存器缩写
    描述
    0
    Write
    -
    发送保持寄存器(DLAB=0)
    0
    Read
    -
    接收数据寄存器(DLAB=0)
    0
    Read/Write
    -
    波特率低八位(DLAB=1)
    1
    Read/Write
    IER
    中断允许寄存器
    1
    Read/Write
    -
    波特率高八位(DLAB=1)
    2
    Read
    IIR
    中断标识寄存器
    2
    Write
    FCR
    FIFO控制寄存器
    3
    Read/Write
    LCR
    线路控制寄存器
    4
    Read/Write
    MCR
    MODEM控制寄存器
    5
    Read
    LSR
    线路状态寄存器
    6
    Read
    MSR
    MODEM状态寄存器
    7
    Read/Write
    -
    Scratch Register

    2 中断允许寄存器(IER)

    描述
    7
    未使用
    6
    未使用
    5
    进入低功耗模式(16750)
    4
    进入睡眠模式(16750)
    3
    允许MODEM状态中断
    2
    允许接收线路状态中断
    1
    允许发送保持器空中断
    0
    允许接收数据就绪中断

    Bit0置1将允许接收到数据时产生中断,Bit1置1时允许发送保持寄存器空时产生中断,Bit2置1将在LSR变化时产生中断,相应的Bit3置位将在MSR变化时产生中断。
    3 中断识别寄存器(IIR)

    描述
    Bit6:7=00
    无FIFO
    Bit6:7=01
    允许FIFO,但不可用
    Bit6:7=11
    允许FIFO
    Bit5
    允许64字节FIFO(16750)
    Bit4
    未使用
    Bit3
    16550超时中断
    Bit2:1=00
    MODEM状态中断(CTS/RI/DTR/DCD)
    Bit2:1=01
    发送保持寄存器空中断
    Bit2:1=10
    接收数据就绪中断
    Bit2:1=11
    接收线路状态中断
    Bit0=0
    有中断产生
    Bit0=1
    无中断产生

    IIR为只读寄存器,Bit6:7用来指示FIFO的状态,均为0时则无FIFO,此时为8250或16450芯片,为01时有FIFO但不可以使用,为11时FIFO有效并可以正常工作。Bit3用来指示超时中断(16550/16750)。Bit0用来指示是否有中断发生,Bit1:2标识具体的中断类型,这些中断具有不同的优先级别,其中LSR中断级别最高,其次是数据就绪中断,然后是发送寄存器空中断,而MSR中断级别最低。

    4 FIFO控制寄存器(FCR)

    描述
    Bit7:6=00
    1Byte产生中断
    Bit7:6=01
    4Byte产生中断
    Bit7:6=10
    8Byte产生中断
    Bit7:6=11
    14Byte产生中断
    Bit5
    允许64字节FIFO
    Bit4
    未使用
    Bit3
    DMA模式选择
    Bit2
    清除发送FIFO
    Bit1
    清除接收FIFO
    Bit0
    允许FIFO

    FCR可写但不可以读,该寄存器用来控制16550或16750的FIFO寄存器。Bit0置1将允许发送/接收的FIFO工作,Bit1和Bit2置1分别用来清除接收及发送FIFO。清除接收及发送FIFO并不影响移位寄存器。Bit1:2可自行复位,因此无需使用软件对其清零。Bit6:7用来设定产生中断的级别,发送/接收中断将在发送/接收到对应字节数时产生。

    5 线路控制寄存器(LCR)

    描述
    Bit7=1
    允许访问波特率因子寄存器
    Bit7=0
    允许访问接收/发送及中断允许寄存器
    Bit6
    设置间断,0-禁止,1-设置
    Bit5:3=XX0
    无校验
    Bit5:3=001
    奇校验
    Bit5:3=011
    偶校验
    Bit5:3=101
    奇偶保持为1
    Bit5:3=111
    奇偶保持为0
    Bit2=0
    1位停止位
    Bit2=1
    2位停止位(6-8位数据位),1.5位停止位(5位数据位)
    Bit1:0=00
    5位数据位
    Bit1:0=01
    6位数据位
    Bit1:0=10
    7位数据位
    Bit1:0=11
    8位数据位

    LCR用来设定通讯所需的一些基本参数。Bit7为1指定波特率因子寄存器有效,为0则指定发送/接收及IER有效。Bit6置1会将发送端置为0,这将会使接收端产生一个“间断”。Bit3-5用来设定是否使用奇偶校验以及奇偶校验的类型,Bit3=1时使用校验,Bit4为0则为奇校验,1为偶校验,而Bit5则强制校验为1或0,并由Bit4决定具体为0或1。Bit2用来设定停止位的长度,0表示1位停止位,为1则根据数据长度的不同使用1.5-2位停止位。Bit0:1用来设定数据长度。

    6 MODEM控制寄存器(MCR)

    描述
    Bit7
    未使用
    Bit6
    未使用
    Bit5
    自动流量控制(仅16750)
    Bit4
    环路测试
    Bit3
    辅助输出2
    Bit2
    辅助输出1
    Bit1
    设置RTS
    Bit0
    设置DSR

    MCR寄存器可读可写,Bit4=1进入环路测试模式。Bit3-0用来控制对应的管脚。

    7 线路状态寄存器(LSR)

    描述
    Bit7
    FIFO中接收数据错误
    Bit6
    发送移位寄存器空
    Bit5
    发送保持寄存器空
    Bit4
    间断
    Bit3
    帧格式错
    Bit2
    奇偶错
    Bit1
    超越错
    Bit0
    接收数据就绪

    LSR为只读寄存器,当发生错误时Bit7为1,Bit6为1时标示发送保持及发送移位寄存器均空,Bit5为1时标示仅发送保持寄存器空,此时,可以由软件发送下一数据。当线路状态为0时Bit4置位为1,帧格式错时Bit3置位为1,奇偶错和超越错分别将Bit2及Bit1置位为1。Bit0置位为1表示接收数据就绪。

    在接收和发送过程中,错误状态位(1,2,3,4位)一旦被置为1,则读入的接收数据已不是有效数据,所以在串行应用程序中,应检测数据传输是否出错。   
    奇偶错:通信线上(尤其是用电话线传输时)的噪声引起某些数据位的改变,产生奇偶错,通检测出奇偶错时,要求正在接受的数据至少应重新发送一段。
    超越错:在上一个字符还未被CPU取走,又有字符要传送到数据寄存器里,则会引起超越错。
    帧格式错:当接收/发送器未收到一个字符数据的终止位,会引起帧格式错。这种错误可能是由于通信线上的噪声引起终止位的丢失,或者是由于接收方和发送方初始化不匹配。
    间断:间断有有时候并不能算是一个错误,而是为某些特殊的通信环境设置的“空格”状态。当间断为1时,这说明接收的“空格”状态超过了一个完整的数据字传输时间。


    8 MODEM状态寄存器(MSR)

    描述
    Bit7
    载波检测
    Bit6
    响铃指示
    Bit5
    DSR准备就绪
    Bit4
    CTS有效
    Bit3
    DCD已改变
    Bit2
    RI已改变
    Bit1
    DSR已改变
    Bit0
    CTS已改变

    MSR寄存器的高4位分别对应MODEM的状态线,低4位表示MODEM的状态线是否发生了变化。到此,串口的寄存器就介绍完了,下面就要讲如何编程。

    第四章 BIOS串行通信功能
    BIOS int 14h提供了串行数据通信功能,包括将串行口初始化为指定的字节结构和传输速率,检查控制器的状态,读写字符等功能。

    串行通信口BIOS功能(int 14h)
    AH
    功能
    调用参数
    返回参数
    0
    初始化串行端口
    AL=初始化参数
    DX=通信口号
       COM1=0,COM2=1
       COM3=2,COM4=3
    AH=线路状态
    AL=MODEL状态
    1
    向串行通信口写字符
    AL=要写的字符
    DX=通信口号
    写字符成功:AH=0,AL=字符。
    写字符失败:AH中,Bit7=1,Bit6:0=线路状态。
    2
    从串行通信口读字符
    DX=通信口号
    读成功:AH中,Bit7=0;AL=字符
    读失败:AH中,Bit7=1,Bit6:0=线路状态
    3
    取线路状态
    DX=通信口号
    AH=线路状态
    AL=MODEL状态

    1 初始化串口
    int 14h的AH=0功能把指定的串行通信口初始化为希望的波特率,奇偶性,字长和终止位的位数,这些初始化参数设置在AL寄存器中,其各位的含义见下表:
    AL
    意义

    Bit7:5
    波特率
    000=110波特
    001=150波特
    010=300波特
    011=600波特
    100=1200波特
    101=2400波特
    110=4800波特
    111=9600波特
    Bit4:3
    效验
    1=2位
    Bit2
    终止位
    0=1位
    Bit1:0
    字长
    10=7位
    11=8位

    例如要求COM1口的传输率为2400波特,字长为8位,1位终止位,无奇偶效验:
    __asm
    {
        mov AH, 0
        mov AL, 0A03h // 0A03h =10100011
        mov DX, 0      // COM1
        int 14h        // 调用BIOS
    }

    2 发送数据
    char my_data = 65h;    //假设要发送65h
    __asm
    {
    mov AL, my_data
    mov AH, 1
    mov DX, 1          //通过COM2口发送出去
    int 14h
    }   

    3 接受数据
    为了接收字符,首先要用int 14h,AH=3来获取COM端口的状态,其返回值在AH寄存器中。检查AH的第0位,它是数据准备好位,如果该位是1,说明COM端口已经接收到字符。然后就可以用int 14h,AH=2功能,把字符读到AL寄存器中来。

    char LSR = 0;            //线路状态
    char my_data;            //接收到的数据
    __asm
    {
        mov AH, 3
        mov DX, 0            //COM1的线路状态
        int 14h
        mov LSR, AH
    }
    if(! (LSR & 01h))       //没有数据到达
    {
        printf("no data arrived");
        goto somewhere;
    }
    else                     //有数据到达,接受数据
    {
        __asm
        {
            mov AH, 2        //读字符
            mov DX, 0
            int 14h
            mov my_data, AL //接受到的字符保存在my_data中
        }
    }

    第五章 I/O寄存器编程
    直接读写 I/O寄存器可以更灵活更可靠地操作串口通信,很多程序都是用这种方式编写的。
    #define BASEADDR1 0x3F8 //COM1的寄存器基地址
    1 初始化串口
    void InitCom1()
    {
        //不允许中断
        outportb(BASEADDR1 + 1, 0);

        //设置DLAB=1, 允许访问波特率寄存器
        outportb(BASEADDR1 + 3, 0x80);

        //设置波特率9600, 设置的参数可以在下面表格中查到
        outportb(BASEADDR1 + 0, 0x0C); //波特率低8位
        outportb(BASEADDR1 + 1, 0x00); //波特率高8位

        //设置8位数据位, 1位停止位, 无校验, DLAB="0"
        outportb(BASEADDR1 + 3, 0x03);
    }

    在DLAB=1时去设定通讯所需的波特率。常用的波特率参数见下表:
    速率(BPS)
    波特率高八位
    波特率低八位
    50
    09h
    00h
    300
    01h
    80h
    600
    00h
    C0h
    1200
    00h
    60h
    2400
    00h
    30h
    4800
    00h
    18h
    9600
    00h
    0Ch
    19200
    00h
    06h
    38400
    00h
    03h
    57600
    00h
    02h
    115200
    00h
    01h

    2 发送数据
    再多的语言都不如代码表达得清楚,所以我还是把代码摆在下面,适当地做点注释。下面这个函数是把一个字符通过COM1口发送出去,my_data是要发送的字符。如果COM1不能够发送,就返回失败。
    bool send_com1(char my_data)
    {   
        char status = inportb(BASEADDR1 + 5); //检查线路状态
        int count = 10000;

        //一直等到发送寄存器空,或者超时
        while(!(status & 0x20) && (count > 0))
        {
            count--;
            status = inportb(BASEADDR1 + 5);
        }

        if(count > 0)                         //发送寄存器空
        {       
            outportb(BASEADDR1 + 0, my_data); //发送字符
            return true;
        }
        else
            return false;                     //超时未发送
    }

    3 接收数据
    下面这个函数是从COM1端口读一个字符,保存到pData指向的变量中,如果COM1口没有数据,就返回失败。
    bool recv_com1(char* pData);
    {
        char status = inportb(BASEADDR1 + 5); //检查线路状态
        if(status & 0x01)                     //接收数据就绪
        {
            *pData = inportb(BASEADDR1 + 0); //读一个字符
            return true;
        }
        else
            return false;                     //没有数据到达
    }

    4 打开FIFO功能
    串口中所谓的FIFO,也就是先入先出队列功能,说的就是一组接收缓冲寄存器,和一组发送保持寄存器。接收缓冲寄存器和发送保持寄存器的大小是16个字节,当FIFO功能关闭的时候,接收缓冲寄存器和发送保持寄存器都只能放一个数据,即相当于一个字节大小。我们最好开始从数据的接收和发送说起。

    数据接收:来自于线路上的数据首先进入接收移位寄存器(RSR),一个字符接收完成之后,数据移入接收缓冲寄存器(RBR),RBR实际就是一个16字节的FIFO队列。当中断设置时,串口控制器会根据FIFO的设置和RBR中数据的数目产生中断。FIFO功能关闭时,RBR只能放一个数据,如果主机设备来不及从RBR中读字符,那么串口接收到的下一个数据会把RBR覆盖,这样,就会有数据丢失。FIFO功能打开时,RBR中能够放16个数据,串口把完成的字符推入到RBR中,RBR原有的数就会前移,这样主机读字符的时间变得宽裕了。

    数据发送:发送操作和接收操作相反,主机数据写入发送保持寄存器(THR),THR也是一个16字节的FIFO,然后数据移入发送移位寄存器(TSR),之后送到线路上。当中断设置时,串口控制器也会根据THR中数据的数目产生中断。FIFO功能打开时,主机可以把16字节的数据一次写入发送保持寄存器中。

    我们接着就可以应用FIFO功能来完善先前的程序。发送数据:
    //pData指向要发送的数据,Len是数据长度,返回是否发送成功
    bool fifo_send(char* pData, int Len)
    {
        int count;

        //禁用FIFO,目的是让程序第一时间感知字符是否发送成功
        outportb(BASEADDR1 + 2, 0x00);

        while(Len > 0)
        {
            //一直等到发送寄存器空,或者超时
            count = 10000;
            while(!(inportb(BASEADDR1 + 5) & 0x20) && (count > 0))
                count--;

            if(count <= 0)                   //超时未发送
                return false;                    

            outportb(BASEADDR1 + 0, *pData); //发送字符
            Len--;
            pData++;
        }

        //再次等到发送寄存器空,或者超时
        count = 10000;
        while(!(inportb(BASEADDR1 + 5) & 0x20) && (count > 0))
            count--;

        if(count <= 0)                   
            return false;                    //超时未发送
        else
            return true;                     //确认,已经发送出去
    }

    接收数据:
    //pData指向要接收的数据,Len是数据长度,返回是否接收成功
    bool fifo_recv(char *pData, int Len)
    {
        int count;   

        //允许FIFO,清除接收FIFO,清除发送FIFO
        outportb(BASEADDR1 + 2, 0x07);

        while(Len > 0)
        {
            //一直等到接收数据就绪,或者超时
            count = 10000;
            while(!(inportb(BASEADDR1 + 5) & 0x01) && (count > 0))
                count--;

            if(count <= 0)                   //超时未收到
                return false;

            *pData = inportb(BASEADDR1 + 0); //读一个字符
            Len--;
            pDate++
        }
        return true;
    }
    到此,通过I/O寄存器对串口编程的方法就介绍完了,希望给这些能给我们开发的项目提供一些帮助,我们在具体使用的时候还要结合实际灵活运用。
    总结
    更具体的代码还是参考dongsuoying的过电压程序比接好。至于中断的传输方式,它适用于使用较快的速率传输大量的数据,现在一般都采用网口或者USB,串口的这种方式在实际应用中很少见了,所以在这里就暂不介绍了。

    展开全文
  • DOS串口通讯interlnk

    2013-02-24 14:00:39
    用于纯MS-DOS6.22系统的串口通讯,包括interlnk.exe和intersvr.exe及相关说明
  • DOS下的串口调试

    2018-03-16 20:51:38
    DOS系统下的串口 调试RS232 ,包括COM1 COM2 COM3 COM4
  • DOS串口通讯源码

    2010-12-20 13:48:38
    DOS串口通讯源码,包括.h文件和.c文件,经过borland C编译没有问题。
  • DOS下的串口C

    2018-03-16 20:45:09
    基于pc104主板在dos系统下的开发 ,使用c进行串口通信,COM1\COM2\COM3\COM4你可以随便配置,中断需要依据你板子的手册进行修改
  • DOS下的串口通信

    2013-11-25 21:38:02
    DOS下的串口通信 希望能对你有参考价值
  • DOS串口文件传送

    2010-06-27 08:54:35
    现有的计算机一般没有软驱,DOS系统下,文件复制非常不便。通过串口将文件送出去是一个不错的选择。
  • DOS串口编程2

    千次阅读 2012-02-08 14:31:09
    DOS平台下,操作串口主要有下列方式:通过BIOS调用、通过串口的硬件中断或通过对串口硬件进行轮询,本章将对以上三种方式进行具体的介绍并给出例子。  1.BIOS中断  在DOS操作系统下,IBM P

    转自:http://blog.csdn.net/xiexuetao/article/details/3595009

     

    串口编程之DOS的串口编程2
     
    在DOS平台下,操作串口主要有下列方式:通过BIOS调用、通过串口的硬件中断或通过对串口硬件进行轮询,本章将对以上三种方式进行具体的介绍并给出例子。

      1.BIOS中断

      在DOS操作系统下,IBM PC及其兼容机提供了一种灵活的串口I/O访问方法,即通过INT 14H调用ROM BIOS串行通讯例行程序。当设置AH为不同的值时,产生不同的功能:

      AH 0 初始化端口
      AH 1 向串口写字符
      AH 2 从串口读字符
      AH 3 取通讯口状态

      初始化端口时(即当AH=0时),需要在AL寄存器中赋一字节初始化参数,其各项意义如图1;


    图1 调用INT 14H时AL寄存器设置

      当向串口写字符时(即当AH=1时),AL寄存器中的字符是需要写入的字符;

      当向串口写字符时(即当AH=2时),AL寄存器中的字符是需要读取的字符。

      看看下面的例程:

    #include <stdio.h>
    #include <dos.h>
    #include <bios.h>
    #define STR "author:sbh"
    union REGS inregs,outregs;

    main()
    {
     //设置串口参数
     init_rs232();
     //写串口的例子
     write_rs232(STR,strlen(STR));
     //读串口的例子
     read_rs232();

     return(0);
    }

    init_rs232()
    {
     do{
      inregs.h.ah=0; //AH=0表示初始化端口
      inregs.h.al=0xe7;
      inregs.x.dx=0; //COM1
      int86(0x14, &inregs, &outregs);
     }while(outregs.h.ah>=0x80);

     return(0);
    }

    write_rs232(char *string, int len)
    {
     int i;
     do{
      inregs.h.ah=1;//发送AL寄存器的字符
      inregs.h.al= *string;
      inregs.x.dx=0;
      int86(0x14, &inregs, &outregs);
     }while(outregs.h.al>=0x80);

     for(i=1;i<len;i++)
     {
      inregs.h.ah=1;
      inregs.h.al=*(string+i);
      inregs.x.dx=0;
      int86(0x14, &inregs, &outregs);
     }
    }

    read_rs232()
    {
     do{
      inregs.h.ah=2; //读取AL寄存器中的字符
      inregs.x.dx=0;
      int86(0x14, &inregs, &outregs);
     }while(outregs.h.al!=3||outregs.h.ah>=0x80);

     return(0);
    }

      其中使用的int86函数的原型为:

    int _Cdecl int86(int intno, union REGS *inregs, union REGS *outregs);

      int86()函数可以调用BIOS功能,现在的程序员们已经很少接触这个函数,80%的程序员甚至都未曾见过这个函数。其实,在茹毛饮血的DOS时代,int86()函数几乎是最常用和最核心的函数之一。几乎可以说,在那个时代,不会int86()就等于不会编程。而与int86配合使用的,就是REGS这样一个联合体,定义为:

    union REGS {
     struct WORDREGS x;
     struct BYTEREGS h;
    };

      其中的WORDREGS定义为:

    struct WORDREGS {
     unsigned int ax, bx, cx, dx, si, di,
     cflag /*进位标志*/,
     flags /*标志寄存器*/;
    };

      而BYTEREGS则定义为:

    struct BYTEREGS {
     unsigned char al, ah, bl, bh, cl, ch, dl, dh;
    };

      原来WORDREGS和BYTEREGS是16位的8086处理器内部的寄存器啊!因此,当CPU发展到286、386以后,再安装DOS也是建立在利用CPU实模式的基础上的!

      另外一个函数与int86()的功能是类似的:

    Int _Cdecl int86x(int intno, union REGS inregs, union REGS outregs, struct SREGS segregs);

      其中的SREGS为段寄存器结构体,定义为:

    struct SREGS
    {
     unsigned int es;
     unsigned int cs;
     unsigned int ss;
     unsigned int ds;
    };

      int86和int86x这两个函数的功能都是执行一个由参数intno指定的8086软中断。在执行软中断之前,两个函数都把inregs中的内容放置到各寄存器中(int86x还把segregs.x.es和segregs.x.ds的值存到相应的段寄存器中),软中断返回后,这两个函数都把当前寄存器的值存到outregs,并把系统进位标志拷贝到outregs.s.cflag中,把8086标志寄存器值存到outregs.x.flag中(int86x还恢复DS,并设置Segregs.es和Segregs.ds的值为对应段寄存器的值)。

      查阅BIOS中断调用手册,发现绝大多数调用都未用到ES和DS段寄存器,故在程序设计中经常只利用了int86函数。
     2.硬件中断

      为了给读者一个直观的印象,我们通过在Windows操作系统中查看COM的资源属性获得某COM对应的中断号,如图2(该对话框中设备管理器中开启)。


    图2 COM中断号

      实际上COM的确直接对应于一个中断,而系统也按照一定的规律为各类硬件分配了一个较固定的中断号,如表1。

      表1 中断向量表

    INT (Hex) IRQ Common Uses
    08 0 System Timer
    09 1 Keyboard
    0A 2 Redirected
    0B 3 Serial Comms. COM2/COM4
    0C 4 Serial Comms. COM1/COM3
    0D 5 Reserved/Sound Card
    0E 6 Floppy Disk Controller
    0F 7 Parallel Comms.
    70 8 Real Time Clock
    71 9 Reserved
    72 10 Reserved
    73 11 Reserved
    74 12 PS/2 Mouse
    75 13 Maths Co-Processor
    76 14 Hard Disk Drive
    77 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;
     do
     {
      c = inportb(PORT1 + 5);
      if (c &1)
      {
       buffer[bufferin] = 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@senet.com.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 buffer[1025];

    void interrupt(*oldport1isr)();

    void interrupt PORT1INT() /* Interrupt Service Routine (ISR) for PORT1 */
    {
     int c;
     do
     {
      c = inportb(PORT1 + 5);
      if (c &1)
      {
       buffer[bufferin] = 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 later
     recovery */

     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");

     do
     {
      if (bufferin != bufferout)
      {
       ch = buffer[bufferout];
       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 */
    }
     3.硬件查询

      通过读取和写入串口UART对应的硬件端口,我们可以控制串口的收发。请看下面的例子:

    /* Name : Sample Comm's Program - Polled Version - termpoll.c */
    /* Written By : Craig Peacock <cpeacock@senet.com.au> */
    #include <dos.h>
    #include <stdio.h>
    #include <conio.h>

    00000000000000000000#define PORT1 0x3F8

    /* Defines Serial Ports Base Address */
    /* COM1 0x3F8 */
    /* COM2 0x2F8 */
    /* COM3 0x3E8 */
    /* COM4 0x2E8 */

    void main(void)
    {
     int c;
     int ch;
     outportb(PORT1 + 1, 0); /* Turn off interrupts - Port1 */

     /* PORT 1 - Communication Settings */

     outportb(PORT1 + 3, 0x80); /* SET DLAB ON */
     outportb(PORT1 + 0, 0x03); /* 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 */

     printf("/nSample Comm's Program. Press ESC to quit /n");

     do
     {
      c = inportb(PORT1 + 5); /* Check to see if char has been */
      /* received. */
      if (c &1)
      {
       ch = inportb(PORT1); /* If so, then get Char */
       printf("%c", ch);
      } /* Print Char to Screen */

      if (kbhit())
      {
       ch = getch(); /* If key pressed, get Char */
       outportb(PORT1, ch);
      } /* Send Char to Serial Port */
     }
     while (ch != 27); /* Quit when ESC (ASC 27) is pressed */
    }

      程序中的

    c = inportb(PORT1 + 5); /* Check to see if char has been */
    /* received. */
    if (c &1)

      检查PORT1 + 5端口地址,通过c&1可以判断是否有数据被UART接收到。关于UART对应的端口范围,从图2中也可以直观地看出。
    展开全文
  • DOS串口收发例程

    2012-10-24 09:19:40
    完整的串口收发例程,支持COM1~4,支持多种波特率,支持xon/xoff协议
  • dos下测试串口的工具,只要知道串口中断、地址,就可以测试,RS232、RS485都可用
  • dos环境串口通信C程序

    2010-09-07 18:24:25
    实现在dos环境下的串口通信,C语言程序,turbo c 3.0环境
  • DOS下的串口编程

    千次阅读 2013-10-07 11:01:18
    DOS下的串口编程   第一章串行通信接口 串行通信使用单条数据线代替了并行通信的8位数据线,传输的距离更远。通信接口每次从CPU得到8位数据,然后通过一个并行入串行出的移位寄存器,转换成串行位,每次发送一位...
    DOS下的串口编程
    

     

    第一章串行通信接口

    串行通信使用单条数据线代替了并行通信的8位数据线,传输的距离更远。通信接口每次从CPU得到8位数据,然后通过一个并行入串行出的移位寄存器,转换成串行位,每次发送一位,将数据发送出去。同样,在接收端也必须有一个串行入并行出的移位寄存器来接收串行数据。并组合打包成一个字节。

     

    以串行方式进入数据线的是由0和1组成的数据,一组这样的数叫做一个字符,一个字符可能有8位,或者7位,6位,5位。在传输中,每个字符都要加上起始位和终止位,起始位总是1位,终止位可以是1位或2位。为了保证传输数据的正确性,有时还包括一位效验位。一般芯片都允许编程时设定效验方式为奇效验,偶效验或者无效验。

     

    串行通信的数据传输速率用bps(bits per second)来表示。另外,还有一种表示信号传输速率的单位是波特率(band rate)。波特率是一种信号调制单位,和bps不一定相等,它定义每秒钟传输的离散信号的数目。所谓的离散信号,就是指不均匀的,不连续的也不相关的信号。更详细的讲解请查阅相关文档。通信端口的传输速率从110bps到115200bps,经验表明,波特率相当于9600bps的时候,传输相当稳定。

     

    1960年电子工业协会(Electronics Industries Association,EIA)制定了RS-232接口标准,以后又陆续发布了修订版本,这是目前广泛应用于个人计算机上的串行接口,用于近程数据通信,连接一些外部设备。下图就是我们经常用到的9针RS-232插头,

    每个引脚的定义为:

    引脚

    方向

    名称

    描述

    含义

    1

    输入

    CD

    Carrier Detect

    数据载波检测

    2

    输入

    RXD

    Receive Data

    数据接收端

    3

    输出

    TXD

    Transmit Data

    数据发送端

    4

    输出

    DTR

    Data Terminal Ready

    数据终端准备就绪(计算机)

    5

    -

    SG

    System Ground

    信号地

    6

    输入

    DSR

    Data Set Ready

    数据设备准备就绪

    7

    输出

    RTS

    Request to Send

    请求发送(计算机要求发送数据)

    8

    输入

    CTS

    Clear to Send

    清除发送(MODEM准备接收数据)

    9

    输入

    RI

    Ring Indicator

    响铃指示

     

    以上信号在通信过程中可能会被全部或者部分使用,把两台计算机通过串口连接起来,最简单的通讯仅需TXD及RXD及SG即可完成。

    TXD 3

    RXD 2

    GND 5

    DTR 4

    DSR 6

    CD  1

    RTS 7

    CTS 8

    2 RXD

    3 TXD

    5 GND

    4 DTR

    6 DSR

    1 CD

    7 RTS

    8 CTS

     

    第二章端口设置

    IBM PC和80x86兼容机可以连接4个串行端口,即COM1~COM4,相应的BIOS中的编号为COM0~COM3,但程序每次只能对其中一个端口进行存取。计算机启动时,自检程序就会测试4个COM端口是否存在,并把每个COM端口的I/O地址写到BIOS的数据区0040:0000~0040:0007共8个字节,每个COM地址占用2个字节。如果系统没有连接串行端口,BIOS数据区的这几个单元内容就成为0。用debug可以查看COM端口地址。

     

    C>debug

    -d 0040:0000 L08

    0040:0000 F8 03 F8 02 E8 03 E8 02

     

    上例查看结果表明系统中有4个COM端口,对应I/O地址分别为3F8,2F8,3E8,2E8。每个COM端口都包括一组8位的寄存器,这四个地址都叫做基地址,也就是第一个寄存器的I/O地址,其他寄存器的地址按照递增的顺序排列。COM1的基地址是3F8,COM2的基地址是2F8,COM3的基地址是3E8,COM4的基地址是2E8。我们通过这些寄存器编程控制数据接收或者发送。

     

    COM1及COM3使用PC机中断4,COM2及COM4使用中断3。

     

    第三章寄存器

    1 寄存器组

    COM端口的寄存器组如下表所示,共有12个寄存器,使用了8个地址,其中部分寄存器共用一个地址,由DLAB=0/1来区分。DLAB是线路控制寄存器的第7位。

     

    基地址

    读/写

    寄存器缩写

    描述

    0

    Write

    -

    发送保持寄存器(DLAB=0)

    0

    Read

    -

    接收数据寄存器(DLAB=0)

    0

    Read/Write

    -

    波特率低八位(DLAB=1)

    1

    Read/Write

    IER

    中断允许寄存器

    1

    Read/Write

    -

    波特率高八位(DLAB=1)

    2

    Read

    IIR

    中断标识寄存器

    2

    Write

    FCR

    FIFO控制寄存器

    3

    Read/Write

    LCR

    线路控制寄存器

    4

    Read/Write

    MCR

    MODEM控制寄存器

    5

    Read

    LSR

    线路状态寄存器

    6

    Read

    MSR

    MODEM状态寄存器

    7

    Read/Write

    -

    Scratch Register

     

    2 中断允许寄存器(IER)

    描述

    7

    未使用

    6

    未使用

    5

    进入低功耗模式(16750)

    4

    进入睡眠模式(16750)

    3

    允许MODEM状态中断

    2

    允许接收线路状态中断

    1

    允许发送保持器空中断

    0

    允许接收数据就绪中断

     

    Bit0置1将允许接收到数据时产生中断,Bit1置1时允许发送保持寄存器空时产生中断,Bit2置1将在LSR变化时产生中断,相应的Bit3置位将在MSR变化时产生中断。

    3 中断识别寄存器(IIR)

    描述

    Bit6:7=00

    无FIFO

    Bit6:7=01

    允许FIFO,但不可用

    Bit6:7=11

    允许FIFO

    Bit5

    允许64字节FIFO(16750)

    Bit4

    未使用

    Bit3

    16550超时中断

    Bit2:1=00

    MODEM状态中断(CTS/RI/DTR/DCD)

    Bit2:1=01

    发送保持寄存器空中断

    Bit2:1=10

    接收数据就绪中断

    Bit2:1=11

    接收线路状态中断

    Bit0=0

    有中断产生

    Bit0=1

    无中断产生

     

    IIR为只读寄存器,Bit6:7用来指示FIFO的状态,均为0时则无FIFO,此时为8250或16450芯片,为01时有FIFO但不可以使用,为11时FIFO有效并可以正常工作。Bit3用来指示超时中断(16550/16750)。Bit0用来指示是否有中断发生,Bit1:2标识具体的中断类型,这些中断具有不同的优先级别,其中LSR中断级别最高,其次是数据就绪中断,然后是发送寄存器空中断,而MSR中断级别最低。

     

    4 FIFO控制寄存器(FCR)

    描述

    Bit7:6=00

    1Byte产生中断

    Bit7:6=01

    4Byte产生中断

    Bit7:6=10

    8Byte产生中断

    Bit7:6=11

    14Byte产生中断

    Bit5

    允许64字节FIFO

    Bit4

    未使用

    Bit3

    DMA模式选择

    Bit2

    清除发送FIFO

    Bit1

    清除接收FIFO

    Bit0

    允许FIFO

     

    FCR可写但不可以读,该寄存器用来控制16550或16750的FIFO寄存器。Bit0置1将允许发送/接收的FIFO工作,Bit1和Bit2置1分别用来清除接收及发送FIFO。清除接收及发送FIFO并不影响移位寄存器。Bit1:2可自行复位,因此无需使用软件对其清零。Bit6:7用来设定产生中断的级别,发送/接收中断将在发送/接收到对应字节数时产生。

     

    5 线路控制寄存器(LCR)

    描述

    Bit7=1

    允许访问波特率因子寄存器

    Bit7=0

    允许访问接收/发送及中断允许寄存器

    Bit6

    设置间断,0-禁止,1-设置

    Bit5:3=XX0

    无校验

    Bit5:3=001

    奇校验

    Bit5:3=011

    偶校验

    Bit5:3=101

    奇偶保持为1

    Bit5:3=111

    奇偶保持为0

    Bit2=0

    1位停止位

    Bit2=1

    2位停止位(6-8位数据位),1.5位停止位(5位数据位)

    Bit1:0=00

    5位数据位

    Bit1:0=01

    6位数据位

    Bit1:0=10

    7位数据位

    Bit1:0=11

    8位数据位

     

    LCR用来设定通讯所需的一些基本参数。Bit7为1指定波特率因子寄存器有效,为0则指定发送/接收及IER有效。Bit6置1会将发送端置为0,这将会使接收端产生一个“间断”。Bit3-5用来设定是否使用奇偶校验以及奇偶校验的类型,Bit3=1时使用校验,Bit4为0则为奇校验,1为偶校验,而Bit5则强制校验为1或0,并由Bit4决定具体为0或1。Bit2用来设定停止位的长度,0表示1位停止位,为1则根据数据长度的不同使用1.5-2位停止位。Bit0:1用来设定数据长度。

     

    6 MODEM控制寄存器(MCR)

    描述

    Bit7

    未使用

    Bit6

    未使用

    Bit5

    自动流量控制(仅16750)

    Bit4

    环路测试

    Bit3

    辅助输出2

    Bit2

    辅助输出1

    Bit1

    设置RTS

    Bit0

    设置DTR

     

    MCR寄存器可读可写,Bit4=1进入环路测试模式。Bit3-0用来控制对应的管脚。

     

    7 线路状态寄存器(LSR)

    描述

    Bit7

    FIFO中接收数据错误

    Bit6

    发送移位寄存器空

    Bit5

    发送保持寄存器空

    Bit4

    间断

    Bit3

    帧格式错

    Bit2

    奇偶错

    Bit1

    超越错

    Bit0

    接收数据就绪

     

    LSR为只读寄存器,当发生错误时Bit7为1,Bit6为1时标示发送保持及发送移位寄存器均空,Bit5为1时标示仅发送保持寄存器空,此时,可以由软件发送下一数据。当线路状态为0时Bit4置位为1,帧格式错时Bit3置位为1,奇偶错和超越错分别将Bit2及Bit1置位为1。Bit0置位为1表示接收数据就绪。

     

    在接收和发送过程中,错误状态位(1,2,3,4位)一旦被置为1,则读入的接收数据已不是有效数据,所以在串行应用程序中,应检测数据传输是否出错。   

    奇偶错:通信线上(尤其是用电话线传输时)的噪声引起某些数据位的改变,产生奇偶错,通检测出奇偶错时,要求正在接受的数据至少应重新发送一段。

    超越错:在上一个字符还未被CPU取走,又有字符要传送到数据寄存器里,则会引起超越错。

    帧格式错:当接收/发送器未收到一个字符数据的终止位,会引起帧格式错。这种错误可能是由于通信线上的噪声引起终止位的丢失,或者是由于接收方和发送方初始化不匹配。

    间断:间断有有时候并不能算是一个错误,而是为某些特殊的通信环境设置的“空格”状态。当间断为1时,这说明接收的“空格”状态超过了一个完整的数据字传输时间。

     

     

    8 MODEM状态寄存器(MSR)

    描述

    Bit7

    载波检测

    Bit6

    响铃指示

    Bit5

    DSR准备就绪

    Bit4

    CTS有效

    Bit3

    DCD已改变

    Bit2

    RI已改变

    Bit1

    DSR已改变

    Bit0

    CTS已改变

     

    MSR寄存器的高4位分别对应MODEM的状态线,低4位表示MODEM的状态线是否发生了变化。到此,串口的寄存器就介绍完了,下面就要讲如何编程。

     

    第四章 BIOS串行通信功能

    BIOS int 14h提供了串行数据通信功能,包括将串行口初始化为指定的字节结构和传输速率,检查控制器的状态,读写字符等功能。

     

    串行通信口BIOS功能(int 14h)

    AH

    功能

    调用参数

    返回参数

    0

    初始化串行端口

    AL=初始化参数

    DX=通信口号

       COM1=0,COM2=1

       COM3=2,COM4=3

    AH=线路状态

    AL=MODEL状态

    1

    向串行通信口写字符

    AL=要写的字符

    DX=通信口号

    写字符成功:AH=0,AL=字符。

    写字符失败:AH中,Bit7=1,Bit6:0=线路状态。

    2

    从串行通信口读字符

    DX=通信口号

    读成功:AH中,Bit7=0;AL=字符

    读失败:AH中,Bit7=1,Bit6:0=线路状态

    3

    取线路状态

    DX=通信口号

    AH=线路状态

    AL=MODEL状态

     

    1 初始化串口

    int 14h的AH=0功能把指定的串行通信口初始化为希望的波特率,奇偶性,字长和终止位的位数,这些初始化参数设置在AL寄存器中,其各位的含义见下表:

    AL

    意义

    Bit7:5

    波特率

    000=110波特

    001=150波特

    010=300波特

    011=600波特

    100=1200波特

    101=2400波特

    110=4800波特

    111=9600波特

    Bit4:3

    效验

    1=2位

    Bit2

    终止位

    0=1位

    Bit1:0

    字长

    10=7位

    11=8位

     

    例如要求COM1口的传输率为2400波特,字长为8位,1位终止位,无奇偶效验:

    __asm

    {

        mov AH, 0

        mov AL, 0A03h  // 0A03h =10100011

        mov DX, 0      // COM1

        int 14h        // 调用BIOS

    }

     

    2 发送数据

    char my_data = 65h;    //假设要发送65h

    __asm

    {

        mov AL, my_data

        mov AH, 1

        mov DX, 1          //通过COM2口发送出去

        int 14h

    }    

     

    3 接受数据

    为了接收字符,首先要用int 14h,AH=3来获取COM端口的状态,其返回值在AH寄存器中。检查AH的第0位,它是数据准备好位,如果该位是1,说明COM端口已经接收到字符。然后就可以用int 14h,AH=2功能,把字符读到AL寄存器中来。

     

    char LSR = 0;            //线路状态

    char my_data;            //接收到的数据

    __asm

    {

        mov AH, 3

        mov DX, 0            //COM1的线路状态

        int 14h

        mov LSR, AH

    }

    if(!  (LSR & 01h))       //没有数据到达

    {

        printf("no data arrived");

        goto somewhere;

    }

    else                     //有数据到达,接受数据

    {

        __asm

        {

            mov AH, 2        //读字符

            mov DX, 0

            int 14h

            mov my_data, AL  //接受到的字符保存在my_data中

        }

    }

     

    第五章 I/O寄存器编程

    直接读写 I/O寄存器可以更灵活更可靠地操作串口通信,很多程序都是用这种方式编写的。

    #define BASEADDR1 0x3F8 //COM1的寄存器基地址

    1 初始化串口

    void InitCom1()

    {

        //不允许中断

        outportb(BASEADDR1 + 1, 0);

     

        //设置DLAB=1, 允许访问波特率寄存器

        outportb(BASEADDR1 + 3, 0x80);

     

        //设置波特率9600, 设置的参数可以在下面表格中查到

        outportb(BASEADDR1 + 0, 0x0C); //波特率低8位

        outportb(BASEADDR1 + 1, 0x00); //波特率高8位

     

        //设置8位数据位, 1位停止位, 无校验, DLAB=0

        outportb(BASEADDR1 + 3, 0x03);

    }

     

    在DLAB=1时去设定通讯所需的波特率。常用的波特率参数见下表:

    速率(BPS)

    波特率高八位

    波特率低八位

    50

    09h

    00h

    300

    01h

    80h

    600

    00h

    C0h

    1200

    00h

    60h

    2400

    00h

    30h

    4800

    00h

    18h

    9600

    00h

    0Ch

    19200

    00h

    06h

    38400

    00h

    03h

    57600

    00h

    02h

    115200

    00h

    01h

     

    2 发送数据

    再多的语言都不如代码表达得清楚,所以我还是把代码摆在下面,适当地做点注释。下面这个函数是把一个字符通过COM1口发送出去,my_data是要发送的字符。如果COM1不能够发送,就返回失败。

    bool send_com1(char my_data)

    {   

        char status = inportb(BASEADDR1 + 5); //检查线路状态

        int  count = 10000;

     

        //一直等到发送寄存器空,或者超时

        while(!(status & 0x20) && (count > 0))

        {

            count--;

            status = inportb(BASEADDR1 + 5);

        }

     

        if(count > 0)                         //发送寄存器空

        {       

            outportb(BASEADDR1 + 0, my_data); //发送字符

            return true;

        }

        else

            return false;                     //超时未发送

    }

     

    3 接收数据

    下面这个函数是从COM1端口读一个字符,保存到pData指向的变量中,如果COM1口没有数据,就返回失败。

    bool recv_com1(char* pData);

    {

        char status = inportb(BASEADDR1 + 5); //检查线路状态

        if(status & 0x01)                     //接收数据就绪

        {

            *pData = inportb(BASEADDR1 + 0);  //读一个字符

            return true;

        }

        else

            return false;                     //没有数据到达

    }

     

    4 打开FIFO功能

    串口中所谓的FIFO,也就是先入先出队列功能,说的就是一组接收缓冲寄存器,和一组发送保持寄存器。接收缓冲寄存器和发送保持寄存器的大小是16个字节,当FIFO功能关闭的时候,接收缓冲寄存器和发送保持寄存器都只能放一个数据,即相当于一个字节大小。我们最好开始从数据的接收和发送说起。

     

    数据接收:来自于线路上的数据首先进入接收移位寄存器(RSR),一个字符接收完成之后,数据移入接收缓冲寄存器(RBR),RBR实际就是一个16字节的FIFO队列。当中断设置时,串口控制器会根据FIFO的设置和RBR中数据的数目产生中断。FIFO功能关闭时,RBR只能放一个数据,如果主机设备来不及从RBR中读字符,那么串口接收到的下一个数据会把RBR覆盖,这样,就会有数据丢失。FIFO功能打开时,RBR中能够放16个数据,串口把完成的字符推入到RBR中,RBR原有的数就会前移,这样主机读字符的时间变得宽裕了。

     

    数据发送:发送操作和接收操作相反,主机数据写入发送保持寄存器(THR),THR也是一个16字节的FIFO,然后数据移入发送移位寄存器(TSR),之后送到线路上。当中断设置时,串口控制器也会根据THR中数据的数目产生中断。FIFO功能打开时,主机可以把16字节的数据一次写入发送保持寄存器中。

     

    我们接着就可以应用FIFO功能来完善先前的程序。发送数据:

    //pData指向要发送的数据,Len是数据长度,返回是否发送成功

    bool fifo_send(char* pData, int Len)

    {

        int  count;

     

        //禁用FIFO,目的是让程序第一时间感知字符是否发送成功

        outportb(BASEADDR1 + 2, 0x00);

     

        while(Len > 0)

        {

            //一直等到发送寄存器空,或者超时

            count = 10000;

            while(!(inportb(BASEADDR1 + 5) & 0x20) && (count > 0))

                count--;

     

            if(count <= 0)                   //超时未发送

                return false;                    

     

            outportb(BASEADDR1 + 0, *pData); //发送字符

            Len--;

            pData++;

        }

     

        //再次等到发送寄存器空,或者超时

        count = 10000;

        while(!(inportb(BASEADDR1 + 5) & 0x20) && (count > 0))

            count--;

     

        if(count <= 0)                   

            return false;                    //超时未发送

        else

            return true;                     //确认,已经发送出去

    }

     

    接收数据:

    //pData指向要接收的数据,Len是数据长度,返回是否接收成功

    bool fifo_recv(char *pData, int Len)

    {

        int count;   

     

        //允许FIFO,清除接收FIFO,清除发送FIFO

        outportb(BASEADDR1 + 2, 0x07);

     

        while(Len > 0)

        {

            //一直等到接收数据就绪,或者超时

            count = 10000;

            while(!(inportb(BASEADDR1 + 5) & 0x01) && (count > 0))

                count--;

     

            if(count <= 0)                   //超时未收到

                return false;

     

            *pData = inportb(BASEADDR1 + 0); //读一个字符

            Len--;

            pDate++

        }

        return true;

    }

    到此,通过I/O寄存器对串口编程的方法就介绍完了,希望给这些能给我们开发的项目提供一些帮助,我们在具体使用的时候还要结合实际灵活运用。

    总结

    更具体的代码还是参考董锁英的过电压程序比接好。至于中断的传输方式,它适用于使用较快的速率传输大量的数据,现在一般都采用网口或者USB,串口的这种方式在实际应用中很少见了,所以在这里就暂不介绍了。

     

    展开全文
  • DOS串口通信程序

    2010-03-14 11:26:01
    串口通信把数据转换成PWM信号控制电机工作
  • 示例:DOS串口通信源程序

    千次阅读 2013-10-07 11:53:49
    示例:DOS串口通信源程序   该程序实现的原理是利用C库函数outportb与inportb来读写对串口芯片的寄存器进行读写和配置。 程序利用中断接收串口数据,利用查询方式来发送数据,可以自发自收。详细源代码如下: ...

    示例:DOS下串口通信源程序

     

    该程序实现的原理是利用C库函数outportb与inportb来读写对串口芯片的寄存器进行读写和配置。

    程序利用中断接收串口数据,利用查询方式来发送数据,可以自发自收。详细源代码如下:
     
    #include <stdio.h>
    #include 
    <conio.h>
    #include 
    <stdlib.h>
    #include 
    <dos.h>

    #define MAXBUFFERSIZE 1024                     /* 数据缓冲区大小 */
    unsigned 
    char DataBuffer[MAXBUFFERSIZE];       /**//* 数据缓冲区 */
    int regBASE;                                   /**//* 串口基地址 */
    int inBuffer = 0;                              /**//* 接收计数 */
    int outBuffer = 0;                             /**//* 发送计数 */
    /**//* 以下枚举为串口相关设置选项 */
    typedef 
    enum ...{COM1,COM2} COM;                  /**//* 串口号 */
    /**//* 奇偶校验类型 */
    typedef 
    enum ...{NONE=0,ODD=1,EVEN=3,MARK=5,SPACE=7} PARITY;
    /**//* 数据位 */
    typedef 
    enum ...{BIT5,BIT6,BIT7,BIT8} DATABIT;
    /**//* 停止位 */
    typedef 
    enum ...{BIT1=0,BIT15=1,BIT2=1} STOPBIT;
    /**//* 自定义bool数据类型 */
    typedef 
    enum ...{false,true} bool;
    /**//* 8250寄存器偏移地址 */
    typedef 
    enum ...{RXR=0,TXR=0,IER=1,IIR=2,LCR=3,MCR=4,LSR=5,MSR=6,LSB=0,MSB=1}
                  regSeriesCOMM;
    /**//* 串口结构体 */
    typedef 
    struct
    ...{
        COM     comNumber;              
    /**//* 串口号 */
        
    long    comBps;                 /**//* 波特率 */
        PARITY  comParity;              
    /**//* 奇偶校验类型 */
        DATABIT comDataBit;             
    /**//* 数据位 */
        STOPBIT comStopBit;             
    /**//* 停止位 */
    }
     SeriesCOMM;

    /**//* 设置波特率 */
    bool SettingBPS(long bps);
    /**//* 获取波特率 */
    long GettingBPS();
    /**//* 初始化串口 */
    bool InitSeriesCOMM( long bps,
                         DATABIT databit,
                         PARITY paritycheck,
                         STOPBIT stopbit);
    /**//* 打开串口 */
    bool OpenCOMM( COM com,
                   
    long bps,
                   DATABIT databit,
                   PARITY paritycheck,
                   STOPBIT stopbit);
    /**//* 关闭串口 */
    void CloseCOMM();
    /**//* 发送数据 */
    void SendByte(unsigned char data);
    /**//* 中断服务程序 */
    void interrupt far asyncint();
    /**//* 中断向量表 */
    void interrupt(*asyncoldvect)();
    /**//* 读取数据 */
    unsigned 
    char ReadData(void);

    int main()
    ...{
        unsigned 
    char temp;         /**//* 临时变量 用于缓存接收数据            */
        
    char buffer[10];            /**//* 临时缓冲区 用于接收控制台输入数据    */
        
    char * pParme;              /**//* 控制台输入字符串指针                 */
        
    char sendBuffer[1024];      /**//* 发送数据缓冲区                       */
        SeriesCOMM thisComm;        
    /**//* 串口结构 保存当前操作串口数据        */

        
    /**//********************************************************************/
        
    /**//* 该段程序用于向用户获取串口初始化配置 */
        
    /**//* 根据用户输入的数据来配置串口 */
        printf(
    "Enter the Seriec COM Number(COM1:1,COM2):");  /**//* 获取要使用的串口 */
        pParme 
    = cgets(buffer);
        
    if( atoi(pParme) == 2)
            thisComm.comNumber 
    = COM2;
        
    else
            thisComm.comNumber 
    = COM1;
        
    /**//* 获取波特率 */
        printf(
    " Enter the Seriec COM BPS(eg:2400):");
        pParme 
    = cgets(buffer);
        thisComm.comBps 
    = atol(pParme);
        
    /**//* 获取数据位位数 */
        printf(
    " Please Choice the Data Bits: ");
        printf(
    "5 bits:  0 6 bits:  1 7 bits:  2 8 bits:  3 ");
        pParme 
    = cgets(buffer);
        
    if ( atoi(pParme) == 0)
            thisComm.comDataBit 
    = BIT5;
        
    else if ( atoi(pParme) == 1)
            thisComm.comDataBit 
    = BIT6;
        
    else if ( atoi(pParme) == 2)
            thisComm.comDataBit 
    = BIT7;
        
    else
            thisComm.comDataBit 
    = BIT8;
        
    /**//* 获取奇偶校验模式 */
        printf(
    " Please Choice the Parity Check Mode: ");
        printf(
    "NONE:    0 ODD:     1 EVEN:    2 MARK:    3 SPACE:   4 ");
        pParme 
    = cgets(buffer);
        
    if ( atoi(pParme) == 1)
            thisComm.comParity 
    = ODD;
        
    else if ( atoi(pParme) == 2)
            thisComm.comParity 
    = EVEN;
        
    else if ( atoi(pParme) == 3)
            thisComm.comParity 
    = MARK;
        
    else if ( atoi(pParme) == 4)
            thisComm.comParity 
    = SPACE;
        
    else
            thisComm.comParity 
    = NONE;
        
    /**//* 获取停止位位数 */
        printf(
    " Please Choice the Stop Bits: ");
        printf(
    "1 bits:      0 1.5 bits:    1 2 bits:      2 ");
        pParme 
    = cgets(buffer);
        
    if ( atoi(pParme) == 1)
            thisComm.comStopBit 
    = BIT15;
        
    else if ( atoi(pParme) == 2)
            thisComm.comStopBit 
    = BIT2;
        
    else
            thisComm.comStopBit 
    = BIT1;
        
    /**//* 根据用户配置打开串口 */
        
    if(OpenCOMM(thisComm.comNumber,thisComm.comBps,thisComm.comDataBit,
                thisComm.comParity,thisComm.comStopBit))
            printf(
    "The Series COMM Is Start... ");
        
    else
            printf(
    "The Series COMM Opened False. ");

        printf(
    "The Series COMM Ready To Receive Data. ");
        
    /**//* 如果是接收数据,将下面while语句注释取消,将发送语句注释掉
           如果是发送数据,将while注释掉,取消发送语句注释 
    */

        
    /**//* 接收数据 */

        
    while(1)
        
    ...{
            temp 
    = ReadData();
            
    if (temp != 0xFF)               /**//* 如果接收的不是0xff 则打印接收结果 */
                printf(
    "%c",temp);
        }


        
    /**//*
        while(1)
        {
            SendByte('a');
        }
        CloseCOMM();
        getch(); 
    */

        
    return 0;
    }

    /**//*******************************************************************
        函数名   : SettingBPS
        参数功能 : 设置串口波特率
        参数列表 :  long bps :  输入 串口波特率
        返回值   :  如果设置成功 返回   true
                    如果设置失败 返回   false
        备注     :  波特率时钟为数据时钟的1/16,而INS8250频率为1.8432MHZ
                    所以有如下等式:
                    预置数 = (主时钟频率/16)/波特率=115200/波特率
    *******************************************************************
    */

    bool SettingBPS(long bps)
    ...{
         unsigned 
    char regBPSMSB;           /**//* 波特率寄存器高8位 */
         unsigned 
    char regBPSLSB;           /**//* 波特率寄存器低8位 */
         unsigned 
    int  regBPS;              /**//* 波特率寄存器值 */

         regBPS 
    = 115200/bps;               /**//* 获取波特率寄存器预置数 */
         regBPSMSB 
    = regBPS >> 8;           /**//* 将预置数分解为高8位与低8位 */
         regBPSLSB 
    = regBPS & 0x00FF;

         
    /**//* LCR控制寄存器的最高位D7为0时 地址 regBASE 与 regBASE+1 为接收/发送、
            中断控制寄存器,当D7为1时,地址regBASE与regBASE+1 为波特率LSB、MSB
            寄存器,所以设置波特率寄存器应先将LCR寄存器最高位置1
    */

         outportb((regBASE
    +LCR),0x80);      /**//* 置D7为1 */
         outportb((regBASE
    +LSB),regBPSLSB); /**//* 先设波特率寄存器低8位 */
         outportb((regBASE
    +MSB),regBPSMSB); /**//* 设置波特率寄存器高8位 */

         
    /**//* 读取波特率寄存器,如果读取值与设置值相等,表示设置成功
            返回 true, 否则返回 false 
    */

         
    if(((inportb(regBASE+MSB)<< 8| inportb(regBASE+LSB)) == regBPS)
            
    return true;
         
    else
            
    return false;
    }

    /**//*******************************************************************
        函数名   : GettingBPS
        参数功能 : 获取串口波特率
        参数列表 :  空
        返回值   :  long bps : 当前串口设置的波特率
        备注     :  波特率 = 115200/波特率寄存器值
    *******************************************************************
    */

    long GettingBPS()
    ...{
        
    long bps;
        outportb((regBASE
    +LCR),0x80);   /**//* 置D7为1表示操作波特率寄存器 */
        bps 
    = 115200 / ((inportb(regBASE+MSB)<< 8| inportb(regBASE+LSB));
        
    return bps;
    }

    /**//*******************************************************************
        函数名   : InitSeriesCOMM
        参数功能 : 初始化串口
        参数列表 :  long bps            输入    波特率
                    DATABIT databit     输入    数据位位数
                    PARITY paritycheck  输入    奇偶校验模式
                    STOPBIT stopbit     输入    停止位位数
        返回值   :  如果设置成功 返回   true
                    如果设置失败 返回   false
        备注     :  D7  :与串口初始化无关,D7为1表示操作波特率寄存器
                         D7为0表示操作RXT/TXT、IEE寄存器
                    D6  :当D6为1时,允许发送器空闲一个完整的发送周期


                          D5D4D3         |        含义
                        --------------------------------------
                        000/010/100/110  |   无奇偶校验
                        --------------------------------------
                             001         |   奇校验
                        --------------------------------------
                             011         |   偶校验
                        --------------------------------------
                             101         |标志(MARK)奇偶校验
                                         |奇偶位恒为1
                        --------------------------------------
                             111         |空白(SPACE)奇偶校验
                                         |奇偶位恒为0
                        --------------------------------------

                    D2  :停止位设置,当该位为0时,停止位为1位,该位为1时,
                         当D1D0=00时,停止位为1.5位,否则停止位为2位

                             D1D0  |  数据位数
                           ----------------------
                               00  |     5
                           ----------------------
                               01  |     6 
                           ----------------------
                               10  |     7
                           ----------------------
                               11  |     8
                           ------------------------
    *******************************************************************
    */

    bool InitSeriesCOMM( long bps,
                         DATABIT databit,
                         PARITY paritycheck,
                         STOPBIT stopbit)
    ...{
        unsigned 
    char parme;

        
    /**//* 组合参数 */
        parme 
    = paritycheck<<3 | stopbit<<2 | databit;
        
    /**//* 设置波特率 */
        SettingBPS(bps);

        outportb((regBASE
    +LCR),0x00);             /**//* 置LCR最高位为0 */
        outportb((regBASE
    +LCR),parme);            /**//* 根据参数设置LCR寄存器 */

        
    /**//* 读取控制寄存器的值,如果和设置值相同,说明设置成功
           返回 true,否则设置失败,返回false。 
    */

        
    if(inportb(regBASE+LCR) == parme)
            
    return true;
        
    else
            
    return false;
    }

    /**//*******************************************************************
        函数名   : OpenCOMM
        参数功能 : 打开串口进行串行通信
        参数列表 :  COM  com            输入    串口号
                    long bps            输入    波特率
                    DATABIT databit     输入    数据位位数
                    PARITY paritycheck  输入    奇偶校验模式
                    STOPBIT stopbit     输入    停止位位数
        返回值   :  如果设置成功 返回   true
                    如果设置失败 返回   false
        备注     :  系统中断表:
                    INT | (Hex)   |      IRQ  Common Uses 
                    ---------------------------------------
                    08  |   0     |       System Timer 
                    --------------------------------------- 
                    09  |    1     |        Keyboard 
                    --------------------------------------- 
                    0A  |    2     |        Redirected 
                    --------------------------------------- 
                    0B  |    3     | Serial Comms. COM2/COM4 
                    --------------------------------------- 
                    0C  |    4     | Serial Comms. COM1/COM3  
                    --------------------------------------- 
                    0D  |    5     |   Reserved/Sound Card  
                    --------------------------------------- 
                    0E  |    6     | Floppy Disk Controller  
                    --------------------------------------- 
                    0F  |    7     |    Parallel Comms.  
                    --------------------------------------- 
                    70  |    8     |    Real Time Clock 
                    --------------------------------------- 
                    71  |    9     |      Reserved 
                    --------------------------------------- 
                    72  |    10    |      Reserved 
                    --------------------------------------- 
                    73  |    11    |      Reserved 
                    --------------------------------------- 
                    74  |    12    |      PS/2 Mouse 
                    --------------------------------------- 
                    75  |    13    |   Maths Co-Processor
                    ---------------------------------------  
                    76  |    14    |      Hard Disk Drive 
                    --------------------------------------- 
                    77  |    15    |   Reserved  
                    ---------------------------------------
    *******************************************************************
    */

    bool OpenCOMM( COM com,
                   
    long bps,
                   DATABIT databit,
                   PARITY paritycheck,
                   STOPBIT stopbit)
    ...{
        unsigned 
    char temp;
        
    /**//* 根据用户选择的串口设置寄存器基地址
           如果选择串口1,基地址为0x03F8
           如果选择串口2,基地址为0x02F8 
    */

        
    if(com)
            regBASE 
    = 0x2F8;
        
    else
            regBASE 
    = 0x3F8;

        asyncoldvect 
    = getvect(0x0C);           /**//* 获取中断向量表 */
        disable();                              
    /**//* 禁止系统中断 */
        outportb((regBASE
    +LCR),0x00);           /**//* 选择设置中断寄存器*/
        outportb((regBASE
    +IER),0x01);           /**//* 允许串口接收中断 */
        temp 
    = inportb(0x21& 0xef;            /**//* 读取当前中断设置 */
        outportb(
    0x21,temp);                    /**//* 注册串口中断 */
        setvect(
    0x0C,asyncint);                 /**//* 设置中断向量表 */
        enable();                               
    /**//* 允许系统中断 */

        
    /**//* 调用串口初始化函数初始化串口,如果调用成功,表示
           打开端口成功,返回 true,否则打开端口失败,返回false。 
    */

        
    if(InitSeriesCOMM(bps,databit,paritycheck,stopbit))
            
    return true;
        
    else
            
    return false;
    }

    /**//*******************************************************************
        函数名   : SendByte
        参数功能 : 利用串口发送1字节数据
        参数列表 :  unsigned char data     输入    发送字节数据
        返回值   :  void
        备注     :
    *******************************************************************
    */

    void SendByte(unsigned char data)
    ...{
        
    /**//* 查询LSR寄存器,如果数据准备好,则发送1字节数据 */
        
    while (((inportb(regBASE+LSR)) & 0x40== 0);
        
    /**//* 将数据写入RTX寄存器发送 */
        outportb((regBASE
    +TXR),data);
    }

    /**//*******************************************************************
        函数名   : CloseCOMM
        参数功能 : 关闭串口
        参数列表 :  空
        返回值   :  void
        备注     :
    *******************************************************************
    */

    void CloseCOMM()
    ...{
        disable();                              
    /**//* 禁止全部中断 */
        outportb((regBASE
    +LCR),0x00);           /**//* 清串口控制寄存器 */
        outportb((regBASE
    +IER),0x00);           /**//* 清串口中断寄存器 */
        outportb((regBASE
    +MCR),0x00);           /**//* 清串口MODEM寄存器 */
        outportb(
    0x21,inportb(0x21)&0x10);      /**//* 禁止串口全局中断 */
        enable();                               
    /**//* 开全局中断 */
        setvect(
    0x0C,asyncoldvect);             /**//* 重设中断向量表 */
    }

    /**//*******************************************************************
        函数名   : asyncint
        参数功能 : 串口接收中断服务程序,通过中断接收串口数据
        参数列表 :  空
        返回值   :  void
        备注     :
    *******************************************************************
    */

    void interrupt far asyncint()
    ...{
        
    /**//* 接收数据 */
        DataBuffer[inBuffer
    ++= inportb(regBASE);
        
    /**//* 如果接收到最大数据量,重设数据指针*/
        
    if (inBuffer >= MAXBUFFERSIZE)
            inBuffer 
    = 0;

        outportb(
    0x20,0x20);                /**//* 中断完成,返回主程序 */
    }

    /**//*******************************************************************
        函数名   : ReadData
        参数功能 : 从接收缓冲区读取数据
        参数列表 :  空
        返回值   :  unsigned char temp : 读取数据成功
                    0xff               : 读取数据失败
        备注     :
    *******************************************************************
    */

    unsigned 
    char ReadData(void)
    ...{
        unsigned 
    char temp;

        
    if (outBuffer != inBuffer)
        
    ...{
            temp 
    = DataBuffer[outBuffer++];
            
    /**//* 如果读取到最最后一个数据,重设读取数据指针*/
            
    if (outBuffer >= MAXBUFFERSIZE)
                outBuffer 
    = 0;
            
    return temp;
        }
                                          /**//* 返回读取数据 */
        
    else
            
    return 0xff;                       /**//* 读取失败,返回0xff*/
    }

                

     

    展开全文
  • 串口测试程序(DOS)

    2009-12-24 16:00:11
    用来在DOS下进行串口测试的程序BC31编译
  • <br /> 1.BIOS中断 <br /> 在DOS操作系统下,IBM PC及其兼容机提供了一种灵活的串口I/O访问方法,即通过INT 14H调用ROM BIOS串行通讯例行程序。当设置AH为不同的值时,产生不同的功能: <br /> ...
  • DOS平台下,操作串口主要有下列方式:通过BIOS调用、通过串口的硬件中断或通过对串口硬件进行轮询,本章将对以上三种方式进行具体的介绍并给出例子。 1.BIOS中断 在DOS操作系统下,IBM PC及其兼容机提供了一种.....
  •  1.BIOS中断 在DOS操作系统下,IBM PC及其兼容机提供了一种灵活的串口I/O访问方法,即通过INT 14H调用ROM BIOS串行通讯例行程序。当设置AH为不同的值时,产生不同的功能: AH 0 初始化端口 AH 1 向串口写字符 
  • 单片机和嵌入式系统中串口编程实例。DOS串口通信分中断和查询两种通信方式,本例程序采用了中断方式。
  • <br /> 1.BIOS中断 <br /> 在DOS操作系统下,IBM PC及其兼容机提供了一种灵活的串口I/O访问方法,即通过INT 14H调用ROM BIOS串行通讯例行程序。当设置AH为不同的值时,产生不同的功能: <br /> ...
  • DOS下的串口c程序

    2009-05-12 02:18:25
    简单串口c程序简单串口c程序简单串口c程序简单串口c程序
  • 在工厂领域,有些老的条码扫描器是串口接口的,本代码实现了从串口读取条码器的数据并加到BIOS的键盘缓冲区,给人的感觉就像是从键盘键入的,以保证现有从键盘读数据的应用程序不需改动地使用串口扫描器。
  • DOS系统下控制串口(1)

    千次阅读 2015-03-07 16:08:15
    实现DOS下是使用Borland C编写控制串口寄存器的代码,实现在DOS下使用COM1发送文件内容。编译生成send.exe ,使用send C1 \1.txt,就是将1.txt的文件内容读取,同COM1发送出去。Code主要分3个部分:1初始化COM 2.发送...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,855
精华内容 6,342
关键字:

dos串口