向串行端口写入数据和从串行端口读取数据(至英特尔伽利略)windows c
writing and reading data to and from a serial port (to an intel galileo) windows c
我正在为一个学校项目建造一台数控机床,它由一个英特尔伽利略和一个控制步进电机的屏蔽组成,这是由 windows 机器上的程序控制的(windows 7),程序基本上做的是读取包含gcode的文本文件,然后将其逐行发送给伽利略,伽利略然后将该行分解为坐标和指令,将主轴移动到需要去的地方当指令完成时,它通过串行向计算机发送一条消息,告诉它已完成,然后计算机发送下一行代码并重复该过程。
到目前为止,我可以读取 gcode 文件并将其逐行发送(使用按键发送每一行)到伽利略,一切正常。我的问题是从伽利略阅读我已经尝试了几种方法但没有任何乐趣。这是我认为最接近我应该做的事情。我不会 post 整个源代码,因为我认为通读它会太多,我 post 编辑了 main() ,它具有所有设置功能和应该读取串行的功能.
/************************************************************************************************************
application for controling galileo or arduino cnc machine
by brendan scullion
10/11/2014
**********************************************************************************************************/
#include <string.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
#include <conio.h>
#include "functions.h"
int main()
{
system("COLOR 1F");
// Declare variables and structures
unsigned char text_to_send[MAX_PATH];
unsigned char digits[MAX_PATH];
int baudrate = 19200;
int dev_num = 50;
char dev_name[MAX_PATH];
HANDLE hSerial;
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
DCB dcbSerialParams = {0};
COMMTIMEOUTS timeouts = {0};
printf("Searching serial ports...\n");
while(dev_num >= 0)
{
printf("\r ");
printf("\rTrying COM%d...", dev_num);
sprintf(dev_name, "\\.\COM%d", dev_num);
hSerial = CreateFile(
dev_name,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if (hSerial == INVALID_HANDLE_VALUE) dev_num--;
else break;
}
if (dev_num < 0)
{
printf("No serial port available\n");
return 1;
}
printf("OK\n");
// Set device parameters (38400 baud, 1 start bit,
// 1 stop bit, no parity)
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (GetCommState(hSerial, &dcbSerialParams) == 0)
{
printf("Error getting device state\n");
CloseHandle(hSerial);
return 1;
}
//dcbSerialParams.BaudRate = CBR_38400;
dcbSerialParams.BaudRate = baudrate;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if(SetCommState(hSerial, &dcbSerialParams) == 0)
{
printf("Error setting device parameters\n");
CloseHandle(hSerial);
return 1;
}
// Set COM port timeout settings
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if(SetCommTimeouts(hSerial, &timeouts) == 0)
{
printf("Error setting timeouts\n");
CloseHandle(hSerial);
return 1;
}
char *cmd = NULL;
char *para1 = NULL;
char *para2 = NULL;
char *para3 = NULL;
char comPort[10];
float baudRate;
int keepGoing = 1;
unsigned char message[MAX_STRING_LENGHT];
//*********************************************************************************************************************
char cmdLine[200];
heading();
while(keepGoing == 1)
{
printf(">>");
gets(cmdLine);
cmd = strtok(cmdLine, " ");
if(cmd!=false)
{
if(cmd != NULL)
{
para1 = strtok(NULL, " ");
}
else if(para1 != NULL)
{
para2 = strtok(NULL, " ");
}
else if(para2 != NULL)
{
para3 = strtok(NULL, " ");
}
if(strcmp(cmd, "help")== 0)
{
help();
}
else if(strcmp(cmd, "comset")== 0)
{
setupComs(comPort, baudRate);
}
else if(strcmp(cmd, "getg")== 0)
{
getgcode(hSerial,text_to_send,dev_name);
}
else if(strcmp(cmd, "readserial")== 0)
{
read_serial(hSerial, message, dev_name);
}
else if(strcmp(cmd, "offset")==0)
{
getOffset(hSerial, text_to_send, dev_name);
}
else if(strcmp(cmd, "setup") == 0)
{
setup(hSerial, text_to_send, dev_name);
}
else if(strcmp(cmd, "exit") == 0)
{
keepGoing = 0;
}
else
{
printf("Unknown command!\n");
}
printf("\n");
}
}
// Close serial port
printf("Closing serial port...");
if (CloseHandle(hSerial) == 0)
{
printf("Error\n");
return 1;
}
printf("OK\n");
return 0;
}
和阅读功能
void read_serial(HANDLE hComm, HANDLE screen, char *message, char *devName )
{
char buffer[MAX_STRING_LENGHT];
unsigned char ch;
DWORD bytes_recieved = MAX_STRING_LENGHT, written = 0;
strcpy(buffer,""); //empty buffer
strcpy(buffer,"");
while(buffer!=NULL){ // wait untill serail message revieved
ReadFile(hComm, &buffer,sizeof(buffer), // read serial
&bytes_recieved, NULL );
if(bytes_recieved){ // if something to read
WriteFile(screen, buffer, bytes_recieved, &written, NULL);
strcpy(message, buffer);
printf("%s", message);
if(kbhit()){
ch = getch();
if(ch== 'q')
break;
}
}
}
}
我可以 post 完整的源代码,如果有人想看的话
在read_serial中,您可以尝试在对ReadFile 的调用中将&buffer 替换为buffer。字符数组的名称应该是指向数组第一个元素的指针。
我会做的是,我会用一个简单而有用的协议来构建进出 Galileo 板的每条消息。例如,我会使用 STX 和 ETX 将消息从 Windows 7 通过串口发送到电路板,使用 ACK NAK 确认接收到的数据包,并使用 SYN 发送 Galileo 线路执行结束的信号。
使用上述框架,您可以构造接收和发送函数,您可以在其中等待特定字符(ETX、STX、SYN、ACK 等),并在您拥有完整帧或控制字符后退出。
我正在为一个学校项目建造一台数控机床,它由一个英特尔伽利略和一个控制步进电机的屏蔽组成,这是由 windows 机器上的程序控制的(windows 7),程序基本上做的是读取包含gcode的文本文件,然后将其逐行发送给伽利略,伽利略然后将该行分解为坐标和指令,将主轴移动到需要去的地方当指令完成时,它通过串行向计算机发送一条消息,告诉它已完成,然后计算机发送下一行代码并重复该过程。
到目前为止,我可以读取 gcode 文件并将其逐行发送(使用按键发送每一行)到伽利略,一切正常。我的问题是从伽利略阅读我已经尝试了几种方法但没有任何乐趣。这是我认为最接近我应该做的事情。我不会 post 整个源代码,因为我认为通读它会太多,我 post 编辑了 main() ,它具有所有设置功能和应该读取串行的功能.
/************************************************************************************************************
application for controling galileo or arduino cnc machine
by brendan scullion
10/11/2014
**********************************************************************************************************/
#include <string.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
#include <conio.h>
#include "functions.h"
int main()
{
system("COLOR 1F");
// Declare variables and structures
unsigned char text_to_send[MAX_PATH];
unsigned char digits[MAX_PATH];
int baudrate = 19200;
int dev_num = 50;
char dev_name[MAX_PATH];
HANDLE hSerial;
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
DCB dcbSerialParams = {0};
COMMTIMEOUTS timeouts = {0};
printf("Searching serial ports...\n");
while(dev_num >= 0)
{
printf("\r ");
printf("\rTrying COM%d...", dev_num);
sprintf(dev_name, "\\.\COM%d", dev_num);
hSerial = CreateFile(
dev_name,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if (hSerial == INVALID_HANDLE_VALUE) dev_num--;
else break;
}
if (dev_num < 0)
{
printf("No serial port available\n");
return 1;
}
printf("OK\n");
// Set device parameters (38400 baud, 1 start bit,
// 1 stop bit, no parity)
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (GetCommState(hSerial, &dcbSerialParams) == 0)
{
printf("Error getting device state\n");
CloseHandle(hSerial);
return 1;
}
//dcbSerialParams.BaudRate = CBR_38400;
dcbSerialParams.BaudRate = baudrate;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if(SetCommState(hSerial, &dcbSerialParams) == 0)
{
printf("Error setting device parameters\n");
CloseHandle(hSerial);
return 1;
}
// Set COM port timeout settings
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if(SetCommTimeouts(hSerial, &timeouts) == 0)
{
printf("Error setting timeouts\n");
CloseHandle(hSerial);
return 1;
}
char *cmd = NULL;
char *para1 = NULL;
char *para2 = NULL;
char *para3 = NULL;
char comPort[10];
float baudRate;
int keepGoing = 1;
unsigned char message[MAX_STRING_LENGHT];
//*********************************************************************************************************************
char cmdLine[200];
heading();
while(keepGoing == 1)
{
printf(">>");
gets(cmdLine);
cmd = strtok(cmdLine, " ");
if(cmd!=false)
{
if(cmd != NULL)
{
para1 = strtok(NULL, " ");
}
else if(para1 != NULL)
{
para2 = strtok(NULL, " ");
}
else if(para2 != NULL)
{
para3 = strtok(NULL, " ");
}
if(strcmp(cmd, "help")== 0)
{
help();
}
else if(strcmp(cmd, "comset")== 0)
{
setupComs(comPort, baudRate);
}
else if(strcmp(cmd, "getg")== 0)
{
getgcode(hSerial,text_to_send,dev_name);
}
else if(strcmp(cmd, "readserial")== 0)
{
read_serial(hSerial, message, dev_name);
}
else if(strcmp(cmd, "offset")==0)
{
getOffset(hSerial, text_to_send, dev_name);
}
else if(strcmp(cmd, "setup") == 0)
{
setup(hSerial, text_to_send, dev_name);
}
else if(strcmp(cmd, "exit") == 0)
{
keepGoing = 0;
}
else
{
printf("Unknown command!\n");
}
printf("\n");
}
}
// Close serial port
printf("Closing serial port...");
if (CloseHandle(hSerial) == 0)
{
printf("Error\n");
return 1;
}
printf("OK\n");
return 0;
}
和阅读功能
void read_serial(HANDLE hComm, HANDLE screen, char *message, char *devName )
{
char buffer[MAX_STRING_LENGHT];
unsigned char ch;
DWORD bytes_recieved = MAX_STRING_LENGHT, written = 0;
strcpy(buffer,""); //empty buffer
strcpy(buffer,"");
while(buffer!=NULL){ // wait untill serail message revieved
ReadFile(hComm, &buffer,sizeof(buffer), // read serial
&bytes_recieved, NULL );
if(bytes_recieved){ // if something to read
WriteFile(screen, buffer, bytes_recieved, &written, NULL);
strcpy(message, buffer);
printf("%s", message);
if(kbhit()){
ch = getch();
if(ch== 'q')
break;
}
}
}
}
我可以 post 完整的源代码,如果有人想看的话
在read_serial中,您可以尝试在对ReadFile 的调用中将&buffer 替换为buffer。字符数组的名称应该是指向数组第一个元素的指针。
我会做的是,我会用一个简单而有用的协议来构建进出 Galileo 板的每条消息。例如,我会使用 STX 和 ETX 将消息从 Windows 7 通过串口发送到电路板,使用 ACK NAK 确认接收到的数据包,并使用 SYN 发送 Galileo 线路执行结束的信号。 使用上述框架,您可以构造接收和发送函数,您可以在其中等待特定字符(ETX、STX、SYN、ACK 等),并在您拥有完整帧或控制字符后退出。