Я пытаюсь написать приложение на C для связи с устройством через COM-порт.
Я могу отправлять данные с помощью Docklight (программа, похожая на гипертерминал) со следующими настройками, и я могу проверитьчто я получаю его через Itronix LogicPort Logic Analyzer.Скорость в бодах: 9600 Четность: нет Размер байта: 8 Стоп-биты: 1
У меня 2 проблемы с моей программой на C: 1) иногда CreateFile возвращает INVALID_HANDLE_VALUE, и другая проблема, с которой я не могу справиться, эточто GetCommState () SetCommState () SetCommTimeouts () всегда возвращают ERROR_INVALID_PARAMETER 87 (0x57)
Так как я не мог обойти эту проблему, я попробовал программу на C #, и она прекрасно работает, но моя программа должна бытьв C общаться с остальной частью моего кода.Эта программа также связывается с другими программами на языке Си через сокеты.
в диспетчере устройств устройство, с которым я хочу поговорить, занесено в список как COM6 в разделе «Порты (COM и LPT)»
, любая помощь приветствуется.!
Ниже приведен код для обеих программ:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
byte[] TxBuffer = new byte[20];
SerialPort CommPort = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
CommPort.Open();
TxBuffer[0] = (byte)'|';
TxBuffer[1] = 0;
TxBuffer[2] = 0;
TxBuffer[3] = 0;
TxBuffer[4] = 1;
TxBuffer[5] = 100;
TxBuffer[6] = 1;
TxBuffer[7] = 6;
TxBuffer[8] = (byte)'|';
TxBuffer[9] = 1;
}
private void button1_Click(object sender, EventArgs e)
{
CommPort.Write(TxBuffer, 0, 10);
}
}
}
, а код C:
где-то
struct serial_dev {
HANDLE hSerial;
};
struct serial_dev sdev; //global
//somewhere in main
if (init_serial(&sdev, com_file) == -1)
return -1;
write_ser(&sdev, buffer, buf_size);
close_serial(&sdev);
// in serial.c
int init_serial(struct serial_dev *sdev, char *port_name)
{
DCB dcbSerialParams;
COMMTIMEOUTS timeouts;
int error = 0;
memset(&dcbSerialParams, 0, sizeof(dcbSerialParams));
memset(&timeouts, 0, sizeof(timeouts));
sdev->hSerial = CreateFile("COM6", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (sdev->hSerial == INVALID_HANDLE_VALUE)
{
error = GetLastError();
close_serial(sdev);
fprintf(stderr, "error: could not open serial port (error:%d)\n", error);
return -1;
}
memset(&dcbSerialParams, 0, sizeof(dcbSerialParams));
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(sdev->hSerial, &dcbSerialParams))
{
close_serial(sdev);
error = GetLastError();
fprintf(stderr, "error: could not get serial port state (%d)\n", error);
return -1;
}
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(sdev->hSerial, &dcbSerialParams))
{
close_serial(sdev);
error = GetLastError();
fprintf(stderr, "error: could not set serial port state (%d)\n", error);
return -1;
}
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 200;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(sdev->hSerial, &timeouts))
{
close_serial(sdev);
error = GetLastError();
fprintf(stderr, "error: could not set serial port timeouts (%d)\n", error);
return -1;
}
return 0;
}
void close_serial(struct serial_dev *sdev)
{
CloseHandle(sdev->hSerial);
}
int write_ser(struct serial_dev *sdev, void *buf, size_t len)
{
DWORD written;
BOOL success;
success = WriteFile(sdev->hSerial, buf, len, &written, NULL);
if(!success || written == 0)
{
printf("error writing to serial\n");
return -1;
}
printf("writing to serial OK!\n");
return written;
}