1、每字节数据由10位组成,一个起始位,一个停止位, 8个数据位。
2、数据采用ASCII码格式。
3、数据传输速率可调(1200-115200)。
4、数据格式:0x02  ST  ID  WT  0x0d  XOR,共计18字节,除起始、结束和校验字节外均为ASCII码
   0x02:起始字节
   ST:  1位状态,0x31
   ID:  7位编号
   WT:  6位重量
   DN:  1位小数点位置
   0x0d:结束字节
   XOR: 前17字节的异或值
如:02 31 33 34 35 36 37 38 39 30 30 30 35 38 32 31 0d 32,代表ID号为3456789,重量为58.2kg这是一个电子称的协议,我该怎么写啊?

解决方案 »

  1.   


      /*------------------------------------------------------------------*
      GSERIAL.CPP   For asynchronous serial port communications
      适用于DOS环境下异步串口通信编程      ATTENTION: Compile this program with Test Stack Overflow OFF.
    在Turbo C++3.0中选项设置 Options/Compiler/Entry中关闭Test Stack Overflow  *------------------------------------------------------------------*/#include "GSerial.h"
    char  inbuf[IBUF_LEN]; // in buffer
    char  outbuf[OBUF_LEN]; // out buffer unsigned int   startbuf = 0;
    unsigned int   endbuf  = 0;
    unsigned int   inhead  = 0;
    unsigned int   intail   = 0;
    unsigned int   outhead  = 0;
    unsigned int   outtail  = 0;
    unsigned int   PortBase = 0;GSerial::GSerial()
    {
    }GSerial::~GSerial()
    {
    }//*  get status of the port  */
    int GSerial::ReadStatus(void)
    {
      return(inp(m_unPortBase+5));
    }/*  send one valid char from the port  */
    void GSerial::SendChar(unsigned char unCh)
    {
       while ((ReadStatus() & 0x40) == 0);
       outportb(m_unPortBase,unCh);
    }/*  send one string from the port  */
    void GSerial::SendString(int nStrlen, unsigned char *unChBuf)
    {
    int k=0;
    do {
    SendChar(*(unChBuf + k));
    k++;
    } while ((k < nStrlen));
    }
    /* Install our functions to handle communications */
    void GSerial::SetVects(void interrupt(*New_Int)(...))
    {
    disable();
    OldVects = getvect(InterruptNo[m_unPortNo-1]);
    setvect(InterruptNo[m_unPortNo-1], New_Int);
    enable();
    }/* Uninstall our vectors before exiting the program */
    void GSerial::ResetVects(void)
    {
    setvect(InterruptNo[m_unPortNo-1], OldVects);
    }/* Tell modem that we're ready to go */
    void GSerial::CommOn(void)
    {
    int temp;
    disable();
    //temp = inportb(m_unPortBase + MCR) | MCR_INT;
    //outportb(m_unPortBase + MCR, temp);
    outportb(m_unPortBase + MCR, MCR_INT);
    //temp = inportb(m_unPortBase + MCR) | MCR_DTR | MCR_RTS;
    //outportb(m_unPortBase + MCR, temp);
    temp = (inportb(m_unPortBase + IER)) | IER_RX_INT;//|IER_TX_INT;
    outportb(m_unPortBase + IER, temp);
    temp = inportb(PIC8259_IMR) & ComIRQ[m_unPortNo-1];
    outportb(PIC8259_IMR, temp);
    enable();
    }/* Go off-line */
    void GSerial::CommOff(void)
    {
     int  temp; disable();
    temp = inportb(PIC8259_IMR) | ~ComIRQ[m_unPortNo-1];
    outportb(PIC8259_IMR, temp);
    outportb(m_unPortBase + IER, 0);
    outportb(m_unPortBase + MCR, 0);
    enable();
    }/* Set the port number to use */
    int GSerial::SetPortBaseAddr(int Port)
    {
    if((Port<1)||(Port>6))
    return(-1);
    m_unPortNo = Port;
    m_unPortBase = PortBaseAddr[m_unPortNo-1];
    return (0);
    }/* This routine sets the speed; will accept funny baud rates. */
    /* Setting the speed requires that the DLAB be set on.        */
    int GSerial::SetSpeed(int Speed)
    {
    char c;
    int divisor; if (Speed == 0)            /* Avoid divide by zero */
    return (-1);
    else
    divisor = (int) (115200L/Speed); if (m_unPortBase == 0)
    return (-1); disable();
    c = inportb(m_unPortBase + LCR);
    outportb(m_unPortBase + LCR, (c | 0x80)); /* Set DLAB */
    outportb(m_unPortBase + DLL, (divisor & 0x00FF));
    outportb(m_unPortBase + DLH, ((divisor >> 8) & 0x00FF));
    outportb(m_unPortBase + LCR, c);          /* Reset DLAB */
    enable(); return (0);
    }/* Set other DATA Format communications parameters */
    int GSerial::SetDataFormat(int Parity, int Bits, int StopBit)
    {
    int  setting; if (m_unPortBase == 0)
    return (-1);
    if (Bits < 5 || Bits > 8)
    return (-1);
    if (StopBit != 1 && StopBit != 2)
    return (-1);
    if (Parity != LCR_NO_PARITY && Parity != LCR_ODD_PARITY && Parity != LCR_EVEN_PARITY)
    return (-1); setting  = Bits-5;
    setting |= ((StopBit == 1) ? 0x00 : 0x04);
    setting |= Parity; disable();
    outportb(m_unPortBase + LCR, setting);
    enable(); return (0);
    }
    void GSerial::CloseSerialPort(void)
    {
    CommOff();
    ResetVects();
    }/* Set up the port */
    int GSerial::InitSerialPort(int Port, int Speed, int Parity, int Bits, int StopBit)
    {
    int flag = 0;
    if (SetPortBaseAddr(Port))
      flag = -1;
    if (SetSpeed(Speed))
      flag = -1;
    if (SetDataFormat(Parity, Bits, StopBit))
      flag = -1;
    return(flag);
    }
    void interrupt ComIntServ(...)
    {
    int temp;
    disable();
    temp = (inportb(PortBase+IIR)) & IIR_MASK; // why interrupt was called
    switch(temp)
    {
    case 0x00:  // modem status changed
    inportb(PortBase+MSR);   // read in useless char
    break;
    case 0x02:  // Request To Send char
    if (outhead != outtail) // there's a char to send
    {
    outportb(PortBase+TXR,outbuf[outhead++]); // send the character
    if (outhead == OBUF_LEN)
    outhead=0; // if at end of buffer, reset pointer
    }
    break;
    case 0x04:  // character ready to be read in
    //inbuf[inhead++] = inportb(m_unPortBase+RXR);// read character into inbuffer
    inbuf[inhead] = inportb(PortBase+RXR);// read character into inbuffer
    inhead++;
    if (inhead == IBUF_LEN) // if at end of buffer
    inhead=0;           // reset pointer
    break;
    case 0x06:  // line status has changed
    inportb(PortBase+LSR);     // read in useless char
    break;
    default:
    break; } outportb(PIC8259_ICR, PIC8259_EOI); // Signal end of hardware interrupt
    enable(); // reenable interrupts at the end of the handler}// Returns either the character to be received from modem if there is one
    // waiting in the buffer, or returns a 0 if there is no character waiting.
    char ReadChar(void)
    {
    char ch;
    if (inhead != intail)     // there is a character
    {
    disable();                          // disable irqs while getting char
    ch = inbuf[intail++];               // get character from buffer
    if (intail == IBUF_LEN) // if at end of in buffer
    intail=0; // reset pointer
    enable();                           // re-enable interrupt
    return(ch);                      // return the char
    }
    ch = -1;
    return(ch);                          // return nothing
    }
    ///////
    main()
    {
    /* Communications parameters */
    int        port     = COM1;
    int        speed    = 9600;
    int        parity   = LCR_NO_PARITY;
    int        bits     = 8;
    int        stopbits = 1;
    int        done  = FALSE;
    char       c;
    int temp;
    int SError=0; GSerial gs; if (!gs.InitSerialPort(port, speed, parity, bits, stopbits))
    {
    PortBase = PortBaseAddr[port-1];
    gs.SetVects(ComIntServ);
    gs.CommOn();
    }
    else
       SError=2; fprintf(stdout, "\nCOM%d, PortBase=0X%x, IntVect=0X%x\n\n",gs.m_unPortNo,gs.m_unPortBase,ComIRQ[gs.m_unPortNo-1]);
    fprintf(stdout, "TURBO C TERMINAL\n"
    "...You're now in terminal mode, "
    "press [ESC] to quit...\n\n"); /*
       The main loop a MSR_CTS as a dumb terminal. We repeatedly
       check the keyboard buffer, and communications buffer.
    */
    do {
    if (kbhit())
    {
    c = getch();
    /* Look for an Escape key */
    switch (c)
    {
    case ESC:
    done = TRUE;  /* Exit program */
    break;
    }
    if (!done)
    {
       gs.SendChar( c );
       fprintf(stdout,"%c",c);
    }
    }
    c = ReadChar();
    if (c != -1)     //'-1' is the END signal of a string
    {
    fprintf(stdout,"%c",c);
    }
       // fprintf(stdout,"%d",testtemp); } while ((!done) && (!SError)); gs.CloseSerialPort(); /* Check for errors */
    switch (SError)
    {
    case NO_ERROR: fprintf(stderr, "\nbye.\n");
      return (0); case BUF_OVFL: fprintf(stderr, "\nBuffer Overflow.\n");
      return (99);
    case 2:   fprintf(stderr,"\n Cannot init serial port");
       return(2);
    default:      fprintf(stderr, "\nUnknown Error, SError = %d\n",
      SError);
      return (99);
    }
    }
      

  2.   

    只是一个协议而已,具体实现的代码我以前发过这样的帖子,你可以找一下。我用的是RTU模式
      

  3.   

    协议可以自己定义的,连接com的两端都一样就可以了。怎么组帧发送,就同样的规则解析。一楼不是c#程序,是c++代码。c#2005写串口很简单。有个serialPort类。
      

  4.   

    同意 whChina(江城老温),楼主安装VS.net 2005吧,用SerialPort控件真的很方便
      

  5.   

    部分代码:
    SerialPort sp = new SerialPort();                if (!sp.IsOpen)
                    {
                        sp.Open();
                    }                Thread.Sleep(200);                sp.Read(by, 0, by.Length);                string instring = Encoding.ASCII.GetString(by);
      

  6.   

    byte[] by = new byte[1024];