首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

做过COM口编程的大哥们帮帮忙啊该如何解决

2012-03-04 
做过COM口编程的大哥们帮帮忙啊1、每字节数据由10位组成,一个起始位,一个停止位,8个数据位。2、数据采用ASCII

做过COM口编程的大哥们帮帮忙啊
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

这是一个电子称的协议,我该怎么写啊?

[解决办法]

/*------------------------------*
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)
{
charc;
intdivisor;

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



[解决办法]
只是一个协议而已,具体实现的代码我以前发过这样的帖子,你可以找一下。我用的是RTU模式
[解决办法]
协议可以自己定义的,连接com的两端都一样就可以了。怎么组帧发送,就同样的规则解析。

一楼不是c#程序,是c++代码。

c#2005写串口很简单。有个serialPort类。
[解决办法]
同意 whChina(江城老温),楼主安装VS.net 2005吧,用SerialPort控件真的很方便
[解决办法]
部分代码:
SerialPort sp = new SerialPort();

if (!sp.IsOpen)
{
sp.Open();
}

Thread.Sleep(200);

sp.Read(by, 0, by.Length);

string instring = Encoding.ASCII.GetString(by);
[解决办法]
用VB msComm比较好。

热点排行