📄 sam_demokit.cpp
字号:
//---------------------------------------------------------------------------
//#include <vcl\vcl.h>
//#pragma hdrstop
#include <stdlib.h>
#include "sam_DemoKit.h"
/***************************************************************************\
* Local functions
\***************************************************************************/
static COMSTAT ComStatus;
static DWORD Ticks, Tout;
static HANDLE MIFS_Handle; //Change int to HANDLE
static short int MIFS_ComBase[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
// Possible not use below any more!
static unsigned char MIFS_SendNr;
static unsigned char MIFS_Number;
static unsigned char MIFS_DataLen;
static unsigned short int MIFS_Check;
static unsigned int MIFS_Baud;
static unsigned char SBuffer[100];
static unsigned char *UPtr;
static short int BCCMode; // flag
static short int ChkBytes; // flag
//---------------------------------------------------------------------------
static int send_cmd (unsigned int AddrX ,unsigned char cmd, int len);
//static int exec_3964 (unsigned char len, unsigned char *out, unsigned char *lrec, unsigned char *in);
static int receive_char (unsigned char *c, DWORD timeout);
static int receive_charLWC (unsigned char *c, DWORD timeout);
static int send_char (unsigned char c);
/****************************************************************************\
* Data structures
\****************************************************************************/
extern COMSTAT ComStatus;
extern DWORD Ticks, Tout;
extern HANDLE MIFS_Handle; //Change int to HANDLE
extern short int MIFS_ComBase[4];
// Possible not use below any more!
extern unsigned char MIFS_SendNr;
extern unsigned char MIFS_Number;
extern unsigned char MIFS_DataLen;
extern unsigned short int MIFS_Check;
extern unsigned int MIFS_Baud;
extern unsigned char SBuffer[100];
extern unsigned char *UPtr;
extern short int BCCMode; // flag
extern short int ChkBytes; // flag
/****************************************************************************\
* Prototypes
\****************************************************************************/
/****************************************************************************\
*
* name Comm_init
*
* Opens the specified COM-Port with the specified Baudrate.
* Communication parameter: 8 databits, 1 stopbit, no parity
*
* Inputs ComStr ... possible: "COM1", "COM2", "COM3", "COM4"
* BaudStr ... possible: "115200L", "57600L", "38400L", "28800L",
* "19200L", "14400L", "9600L"
*
* Return MI_INITERR, 0 ... 3 (Handle for COM1 ... COM4)
*
\****************************************************************************/
HANDLE WINAPI Comm_init (char *ComStr, char *BaudStr)
{
DCB dcb;
MIFS_Handle =CreateFile(ComStr,
GENERIC_READ | GENERIC_WRITE,
0, /* comm devices must be opened w/exclusive-access */
NULL, /* no security attrs */
OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
0,//FILE_ATTRIBUTE_NORMAL, /* not overlapped I/O */
NULL /* hTemplate must be NULL for comm devices */
);
if (MIFS_Handle == INVALID_HANDLE_VALUE)
{
GetLastError();
return(MI_INITERR);
}
if (!GetCommState(MIFS_Handle, &dcb)) return(MI_INITERR);
MIFS_Baud = atol (BaudStr);
switch (MIFS_Baud)
{ case 1200:
dcb.BaudRate = 1200;
break;
case 2400:
dcb.BaudRate = 2400;
break;
case 4800:
dcb.BaudRate = 4800;
break;
case 9600L:
dcb.BaudRate = 9600;
break;
case 19200L:
dcb.BaudRate = 19200;
break;
case 14400L:
dcb.BaudRate = 14400;
break;
case 38400L:
dcb.BaudRate = 38400;
break;
case 28800L:
dcb.BaudRate = 28800;
break;
case 57600L:
dcb.BaudRate = 57600;
break;
case 115200L:
dcb.BaudRate =115200;
break;
default:
dcb.BaudRate =115200;
break;
};
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(MIFS_Handle, &dcb)) return (MI_INITERR);
BCCMode = SER_BCC; // default
ChkBytes = BCC_CHKBYTES; // default
MIFS_SendNr = 0;
return (MIFS_Handle);
}
/****************************************************************************\
*
* name Comm_close
*
* Closes the specified COM-Port
*
* Inputs handle ... see 'Comm_init'
*
\****************************************************************************/
void WINAPI Comm_close ()
{
CloseHandle (MIFS_Handle);
}
/****************************************************************************\
*
* name send_cmd
*
* Bufferhandling and execution of serial communication
*
* Inputs cmd ... command
* len ... lenght of INFO
*
* Return Status
*
\****************************************************************************/
int send_cmd ( unsigned int AddrX ,uchar cmd, int len)
{
uchar c;
int i, e;
int delayms = 2500;
AddrX =0;
len=0;
send_char (0x55);
send_char (0xbb);
send_char (0x00);
send_char (0x00);
send_char (cmd);
if (((e = receive_char (&c, delayms)) == 0) && (c =='O'))
{
return 0;
}
else
return 1;
}
/****************************************************************************\
*
* name exec_3964
*
* Performs the command/response sequence via 3964 serial protocol
*
* Inputs len ... length of transmitted INFO
* out ... pointer to transmitted INFO
*
* Outputs lrec ... length of received DATA
* in ... pointer to received INFO
*
* Return MI_OK, MI_SERTIMEOUT, MI_SERERR, MI_3964BCC, MI_REC_OVERFLOW,
* MI_NO_DLE_REC, MI_NO_STX_REC, MI_WRONG_REC_LEN
*
\****************************************************************************/
int WINAPI exec_3964 ( unsigned int POS_Addr , uchar len, uchar *out, uchar *lrec, uchar *in)
{
int state, e, errcnt1, errcnt2, end = 99 ;
int delayms = 1500; //通讯延时(毫秒)
uchar c, i, j, k;
state = 0;
errcnt1 = 0;
errcnt2 = 0;
while (1)
{
if (state == end)
break;
switch (state)
{
case 0:
if ((e = send_char (STX)) < 0)
return (e);
c = POS_Addr;
if ((e = send_char (c)) < 0)
return (e);
POS_Addr = POS_Addr >> 8;
c = POS_Addr;
if ((e = send_char (c)) < 0)
return (e);
POS_Addr = POS_Addr >> 8;
c = POS_Addr;
if ((e = send_char (c)) < 0)
return (e);
POS_Addr = POS_Addr >> 8;
c = POS_Addr;
if ((e = send_char (c)) < 0)
return (e);
c = 0;
// if (((e = receive_charLWC (&c, 650)) == 0) && (c == DLE))
if (((e = receive_charLWC (&c, delayms)) == 0) && (c == DLE))
state = 1;
else
{
errcnt1++;
if (errcnt1 >= 3)
{
if (e == MI_SERTIMEOUT)
return (MI_SERTIMEOUT);
else
return (MI_NO_DLE_REC);
}
}
break;
case 1: // send DATA, BCC, DLE, ETX
for (i=0; i<len+1; i++)
{
if ((e = send_char (out[i])) < 0)
return (e);
if (out[i] == DLE) // send DLE twice
if ((e = send_char (DLE)) < 0)
return (e);
}
if ((e = send_char (DLE)) < 0) //send DLE again! Why?................
return (e);
if ((e = send_char (ETX)) < 0)
return (e);
state = 2;
break;
case 2: // receive DLE
c = 0;
// if (((e = receive_char (&c, 650)) == 0) && (c == DLE))
if (((e = receive_char (&c, delayms)) == 0) && (c == DLE))
state = 3;
else
{
errcnt2++;
if (errcnt2 >= 3)
{
if (e == MI_SERTIMEOUT)
return (MI_SERTIMEOUT);
else
return (MI_NO_DLE_REC);
}
errcnt1 = 0;
state = 0;
}
break;
case 3: // receive STX
c = 0;
// if (((e = receive_char (&c, 650)) == 0) && (c == STX))
if (((e = receive_char (&c, delayms)) == 0) && (c == STX))
state = 4;
else
{
if (e == MI_SERTIMEOUT)
return (MI_SERTIMEOUT);
else
return (MI_NO_STX_REC);
}
break;
case 4: // send DLE
if ((e = send_char (DLE)) < 0)
return (e);
i = 0;
state = 5;
break;
case 5: // receive DATA
if (i > 60)
return (MI_REC_OVERFLOW);
c = 0;
// if ((e = receive_char (&c, 650)) < 0)
if ((e = receive_char (&c, delayms)) < 0)
{
if (e == MI_SERTIMEOUT)
{
state = 3;
break;
}
else
return (e);
}
if (c == DLE)
{
state = 6;
break;
}
in[i] = c;
i++;
break;
case 6: // DLE received
c = 0;
// if ((e = receive_char (&c, 650)) < 0)
if ((e = receive_char (&c, delayms)) < 0)
return (e);
if (c == DLE) // DLE DLE sequence
{
in[i] = c;
i++;
state = 5;
}
else if (c == ETX) // DLE ETX sequence
state = 7;
break;
case 7: // check BCC
if ((in[2] + 3 + ChkBytes) != i)
return (MI_WRONG_REC_LEN);
if (ChkBytes == BCC_CHKBYTES) // BCC-Mode
{
MIFS_Check = 0;
for (j = 0; j < i; j++)
MIFS_Check ^= (unsigned int) in[j];
}
else // CRC16-Mode
{
MIFS_Check = CRC_PRESET;
for (j = 0; j < i; j++)
{
MIFS_Check ^= (unsigned int) in[j] << 8;
for (k = 0; k < 8; k++)
{
if (MIFS_Check & 0x8000)
MIFS_Check = (MIFS_Check << 1) ^ CRC_POLYNOM;
else
MIFS_Check = (MIFS_Check << 1);
}
}
}
if (MIFS_Check != 0)
{
if ((e = send_char (NAK)) < 0)
return (e);
state = 3;
break;
}
if ((e = send_char (DLE)) < 0)
return (e);
state = end;
break;
default: break;
}
}
MIFS_Number = in[0]; // Sequence number
MIFS_DataLen = in[2]; // len of received datablock
*lrec = in[2];
return (MI_OK);
}
/****************************************************************************\
*
* name send_char
*
* transmits one character via API
*
* Inputs c ... character to transmit
*
* Return MI_OK, MI_SERERR
*
\****************************************************************************/
int send_char (uchar c)
{
unsigned long nSend=0, dummy;
//PurgeComm(MIFS_Handle,PURGE_TXABORT);
ClearCommError(MIFS_Handle, &dummy, &ComStatus);
WriteFile (MIFS_Handle, &c, 1, &nSend, NULL);
do
ClearCommError(MIFS_Handle, &dummy, &ComStatus);
while (ComStatus.cbOutQue != 0);
if ( nSend <= 0)
{
return (MI_SERERR);
}
return (MI_OK);
}
/****************************************************************************\
*
* name receive_char
*
* receives one character via API, using clock-ticks for timeout
*
* Inputs timeout ... timeout [ms]
*
* Outputs c ... received character
*
* Return MI_OK, MI_SERTIMEOUT
*
\****************************************************************************/
int receive_char (uchar *c, DWORD timeout)
{
unsigned long dummy,nRead;
SETTIMEOUT (timeout);
do
ClearCommError(MIFS_Handle, &dummy, &ComStatus);
while ((ComStatus.cbInQue == 0) && !TIMEOUT);
if (TIMEOUT)return (MI_SERTIMEOUT);
ReadFile (MIFS_Handle, c, 1, &nRead, NULL); //&c
if ( nRead != 1 )
{
ClearCommError(MIFS_Handle, &dummy, &ComStatus);
return (MI_SERERR);
}
return (0);
}
/****************************************************************************\
*
* name receive_charLWC
*
* receives one character via API, using clock-ticks for timeout
*
* Inputs timeout ... timeout [ms]
*
* Outputs c ... received character
*
* Return MI_OK, MI_SERTIMEOUT
*
\****************************************************************************/
int receive_charLWC (uchar *c, DWORD timeout)
{
unsigned long dummy,nRead;
SETTIMEOUT (timeout);
PurgeComm(MIFS_Handle,PURGE_RXABORT);
PurgeComm(MIFS_Handle,PURGE_RXCLEAR);
do
ClearCommError(MIFS_Handle, &dummy, &ComStatus);
while ((ComStatus.cbInQue == 0) && !TIMEOUT);
if (TIMEOUT)return (MI_SERTIMEOUT);
ReadFile (MIFS_Handle, c, 1, &nRead, NULL); //&c
if ( nRead != 1 )
{
ClearCommError(MIFS_Handle, &dummy, &ComStatus);
return (MI_SERERR);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -