自己做童装衣服加工卖:RS-232c接口的两机通信的问题 - C/C++ / C语言

来源:百度文库 编辑:九乡新闻网 时间:2024/04/30 17:51:55
谁有关于RS-232c接口的两机通信的资料?
要求实现两机的字符传送就行,采用查询方式好像简单点.
用c写的最好.汇编也行.

问个小问题:COM1和COM2是不是由两个不同的8251控制的?

在一台机上将COM1和COM2连起来,可以用查询方式从一个口传送,另一个口接受吗?怎样实现?

100分相送,望各位大侠指点.
  • lj_csdn
  • (大笨蛋)
  • 等 级:
#1楼 得分:0回复于:2002-06-23 14:59:45 给你一个
主程序用法:

#include   "rs232.h "

ComPort   COM;

COM.Open(port);     //port=1   2   ...
COM.Setup(9600,0x0A);
COM.Clear();
COM.DTR(1);
COM.RTS(1);
发送数据
COM.Write(buffer,length);
接收数据
i=COM.In();
COM.Read(result,i);

COM.RTS(0);
COM.Clear();
COM.Close();

//以下是rs232.h

#ifndef   _RS232_H
#define   _RS232_H

#define   S_CTS 0x01
#define   S_DSR 0x02
#define   S_RI 0x04
#define   S_CD 0x08

#define   DATA 0
#define   IER   1
#define   IIR   2
#define   LCR   3
#define   MCR   4
#define   LSR   5
#define   MSR   6

#ifndef   MAX_RECE
#define   MAX_RECE   1024
#endif

unsigned   char   RS232_buffer[MAX_RECE];
int     QueLast,QueNext,QueLoop;
int     baseport;

class   ComPort   {
    private:
        int     IRQ;
        unsigned   char   save8259;
        void   interrupt   (*OldRS232)(...);
    public:
        void   Open(void);
        void   Open(int   port);
        void   Open(int   address,int   irq);
        void   Setup(long   bps,int   mode);
        void   Close(void);
        void   Clear(void);
        void   Write(unsigned   char   *p,int   len);
        void   Read(unsigned   char   *p,int   len);
        void   DTR(int   onoff);
        void   RTS(int   onoff);
        int     In(void);
        int     Msr(void);
};

void   interrupt   NewRS232(...)
{     disable();
      if   ((!QueLoop)||(QueLast!=QueNext))
      {   RS232_buffer[QueLast++]=inportb(baseport);
          if   (QueLast> =MAX_RECE)   {   QueLast=0;   QueLoop=1;}
      }
      else   inportb(baseport);
      outportb(0x20,0x20);
      enable();
}

void   ComPort::Setup(long   bps,int   mode)
{     unsigned   char   c;
      c=(unsigned   char)(115200L/bps);
      outportb(baseport+LCR,0x80);
      outportb(baseport,c);
      outportb(baseport+1,0);
      outportb(baseport+LCR,(unsigned   char)mode);
}

void   ComPort::Open(void)
{     unsigned   char   c;
      QueLoop=QueLast=QueNext=0;
      OldRS232=getvect(0x08+IRQ);
      disable();
      setvect(0x08+IRQ,NewRS232);
      save8259=inportb(0x21);
      _CX=IRQ;
      asm   {
          mov     al,0xFE
          rol     al,cl
          mov     c,al
      }
      outportb(0x21,save8259&c);
      outportb(baseport+MCR,0x08);
      outportb(baseport+IER,0x01);
      enable();
}

void   ComPort::Open(int   port)
{     static   int   portaa[4]={0x3F8,0x2F8,0x3E8,0x2E8};
      static   int   irqaa[4]={4,3,4,3};
      if   ((port <1)||(port> 4))   port=1;
      baseport=portaa[port-1];
      IRQ=irqaa[port-1];
      Open();
}

void   ComPort::Open(int   address,int   irq)
{     baseport=address;
      IRQ=irq;
      Open();
}

void   ComPort::DTR(int   on_off)
{     unsigned   char   c;
      c=inportb(baseport+MCR);
      if   (on_off)   c|=0x01;   else   c&=0xFE;
      outportb(baseport+MCR,c);
}

void   ComPort::RTS(int   on_off)
{     unsigned   char   c;
      c=inportb(baseport+MCR);
      if   (on_off)   c|=0x02;   else   c&=0xFD;
      outportb(baseport+MCR,c);
}

void   ComPort::Close(void)
{     disable();
      outportb(0x21,save8259);
      setvect(0x08+IRQ,OldRS232);
      outportb(baseport+IER,0x0);
      outportb(baseport+MCR,0x0);
      enable();
}

void   ComPort::Clear(void)
{     disable();
      QueLast=QueNext=QueLoop=0;
      enable();
}


int   ComPort::In(void)
{     if   (!QueLoop)   return   QueLast-QueNext;
      return   QueLast+MAX_RECE-QueNext;
}

void   ComPort::Write(unsigned   char   *p,int   len)
{     int   i;
      for   (i=0;i       {     while   ((inportb(baseport+LSR)&0x20)==0);
            outportb(baseport,*p);
      }
}

void   ComPort::Read(unsigned   char   *p,int   len)
{     int   i;
      for   (i=0;i       {     *p=RS232_buffer[QueNext++];
            if   (QueNext> =MAX_RECE)
            {   disable();
QueLoop=QueNext=0;
enable();
            }
      }
      p[len]=0;
}

int   ComPort::Msr(void)
{     int   i;
      i=inportb(baseport+MSR);
      return   (i> > =4);
}

#endif
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:腾讯2面面试官出的3个题
  • lj_csdn
  • (大笨蛋)
  • 等 级:
#2楼 得分:0回复于:2002-06-23 15:05:41 若主板使用8250,应该是两个
两个口是可以互通的。与两机互连一样。
    将串行电缆连成2-3   3-2   5-5(九针头)   7-7(25针)
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:推荐 初学者学习C++的50条忠告
  • delphihero
  • (何去何从)
  • 等 级:
#3楼 得分:0回复于:2002-06-23 15:41:09 用vc写的有好多   http://roaringwind.best.163.com/有几个
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:C/C++板块常见问题集:(写给新手),欢迎大家补充,帮顶也可以
  • sqsavagepointer
  • (野人)
  • 等 级:
#4楼 得分:0回复于:2002-06-23 15:45:44 谢大哥,可是,有使用查询方式通信而不是使用中断方式的吗?

一台机的两口连接后,可以使用查询方式一个口发送,一个口接受吗?我是指用查询方式.
用查询方式通信的程序可在windows中寻运行吗?
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:指针函数能修改函数的内容吗??
  • sqsavagepointer
  • (野人)
  • 等 级:
#5楼 得分:0回复于:2002-06-23 16:36:05 这是我写的程序,采用查询方式,在一台机上,COM1   COM2已用9针线互联,COM1发送,CMO2接收:
#include   "stdio.h "
#include  
#include   "string.h "
#define   COM1   0x3f8
#define   COM2   0x2f8
void   main()   {
//先初始化COM2
outportb(COM2+1,0xAA);//8251空操作
outportb(COM2+1,0x50);//软件复位8251A,清除错误标志
outportb(COM2+1,0xcf);//8251选择方式字:1100   1111b:D5:发送请求,D4:错误标志位,
                                            //D3:发送终止符     D1:数据终端准备好   D0:发送允许
outportb(COM2+1,0x14);//8251A工作命令字,置位ER、RxE
char   data[3]={ 'I ', 'O ', 'Y '};     //COM1要发送的字符
//初始化COM1
outportb(COM1+1,0x00);//8251空操作
outportb(COM1+1,0x40);//软件复位8251A
outportb(COM1+1,0xcf);
outportb(COM1+1,0x37);//8251A工作命令字:置位RTS、ER、RxD、DTR、TcEN
int   id=0;  
unsigned   char   status;//用来保存从CMO口读进的状态寄存器的内容
char   data2[3];
    while   (id <=2)
  {
        do   {
            status=inportb(0x3fd);   //0x3fd:COM1线路状态寄存器地址,
                                                          //D6:发送寄存器空,D5:发送保持寄存器空(TBE)
            status=status   &   0x20;     //0x20:0010   0000,检查发送寄存器是否空
            }while   (status== '0 ');
            outportb(COM1,data[id]);
/*
        do   {
              status=inportb(0x2fd);//0x2fd:COM2线路状态寄存器地址,D1:接受数据准备好(RDA)
              status=status   &   0x01;//检查是否已收到数据
            }while   (status== '0 ');
            data2[id]=inportb(COM2);
*/
            id++;
  }//while
for   (int   i=0;i <=2;i++)
    printf( "%c ",data2[i]);
}

此程序在不屏蔽/*   ...*/中的部分时,COM2口可接收数据,data2[]会变成:I   O   Y与data[]相同。
本来采用查询方式,当COM2口没有接收数据,亦即屏蔽掉的接收部分后,COM1口应该在不断循环等待CMO2口接收后,才发送第二个数据的,是不是?
但是我在调试过程中发现:在COM2口没有接收数据的情况下(我试过把线拔掉),COM1口仍然会不断发送数据,这是为什么?
COM1口在发送完一个数据后而且COM2口没有接收的情况下,线路状态寄存器将会变成什么?是不是D5:发送保持寄存器为0?可是我每次循环都发现status的值都是0x60=0110   0000,亦即D6、D5都为1,这是什么意思?是表示数据以发送出去,CMO2口已接收?可是当时我根本没有把两个口连起来!!!

我在DOS环境试了一次,还是同一情况。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:遇到一个奇怪的问题 高手(懂汇编)的进来看看 高分奉上 晚上结贴
  • lj_csdn
  • (大笨蛋)
  • 等 级:
#6楼 得分:70回复于:2002-06-23 18:00:06 串口发送数据时寄存器状态变化是与外设无关的,是在芯片内部的串行数据发送后产生,不管是否到达对方的。
另外     while   (status== '0 ')   应该改为   while   (status==0)

当然可以一个口发一个口收。
windows下的dos模式是可以用的.
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • sqsavagepointer
  • (野人)
  • 等 级:
#7楼 得分:0回复于:2002-06-23 19:15:48 那么,我要COM1口发送一个数据后,要COM2口接收到后通知COM1,然后COM1才能发送下一个数据,怎样实现呢?
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • sqsavagepointer
  • (野人)
  • 等 级:
#8楼 得分:0回复于:2002-06-23 19:17:31 用查询方式可行吗?我只要能实现双机用232口通信就行。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • sqsavagepointer
  • (野人)
  • 等 级:
#9楼 得分:0回复于:2002-06-23 22:02:55 救我呀!各位大哥!
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • leafstream
  • (叶飘扬)
  • 等 级:
#10楼 得分:15回复于:2002-06-23 23:10:57 上面给了很多代码了
你所要求的,是要通过自己的程序来实现的
com2收到后,只需要给com1发送一个确认信息,com1接收一个确认信息后,继续向com2发送新的数据
这是一个自己定义的通信关系,或者说协议,这与如何控制com1和com2是没有必需本质的关系。
控制com口的操作,就是那些基本操作,没什么吧。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • sqsavagepointer
  • (野人)
  • 等 级:
#11楼 得分:0回复于:2002-06-24 12:54:23 现在的PC是不是都是8251A芯片了的?能把8251A当作8250那样编程吗?

亦即在那些基于8250的程序在8251A的PC中能不能用?

我想把一段基于8250的程序在8251A的机器(如果现在的PC都是8251A的话)上编译调试,可以吗?
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • lj_csdn
  • (大笨蛋)
  • 等 级:
#12楼 得分:0回复于:2002-06-24 13:37:58 跟芯片无关,所有支持RS232通讯的芯片最终的逻辑通讯信号都是一样
你用PC机的8250,单片机内置的,掌上电脑,手机接口他们都一样。
就像你用nokia手机和motrola手机一样.
他们都遵循相同的协议就可以一样用.

8250和8251他们对PC机来说端口兼容,你在任意芯片下做的程序可以互换
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • xrbeck
  • (ALEK)
  • 等 级:
#13楼 得分:5回复于:2002-06-24 13:51:49 这什么呀,WIN32明确规定不能对硬件直接访问,怎么还有些
outportb之类的用法呢..小弟愚昧,没用过.
可以看看刚写的一篇章:http://www.csdn.net/Develop/article/14/14204.shtm
请大家多多批评指正。。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • shornmao
  • (毛豆子[死猫])
  • 等 级:
#14楼 得分:10回复于:2002-06-24 14:57:24 现在的PC的UART一般是16550的兼容芯片。早就不是8251了。