Помогите пожалуйста, коллеги!
Мне нужно написать програмку для работы с com-портом на Visual Studio C#. Простым языком говоря пользователь вводит
текст в тесктовое поле, он при нажатии кнопки "отправить" должен передаваться выбранному com-порту; а при нажатии на
кнопку "получить из порта" соответсвенно этот текст должен получаться оттуда в другое тектовое поле. Т.е. как бы
обмен данными между программой и портом. Пробовал реализовать с помощью serialport класса: запись вроде проходит
(хотя когда проверяю св-во byteToRead/byteToWrite — там нули), а при чтении выдается ошибка — истекло время
ожидания. Пробовал использовать Win32-функции: получение данных вроде идет, но вместо отправленных значений пустые
строки. Сейчас пытаюсь сделать симбиозный вариант — ниче пока не получается... Прогу сдавать послезавтра —
подскажите пожалуйста что делать, может кто пробовал такую фишку!!!
Заранее благодарю всех откликнувшихся, исходный код и файл проекта на сегодняшний момент прилагаю.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace SerrialPortReader
{
public partial class Form1 : Form
{
string InputData = String.Empty;
delegate void SetTextCallback(string text);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// получаем список СОМ портов системы
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
comboBox1.Items.Add(port);
}
}
/*
void AddData(string text)
{
listBox1.Items.Add(text);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
InputData = port.ReadExisting();
if (InputData != String.Empty)
{
SetText(InputData);
}
}
*/
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.Text != "")
{
button1.Enabled = true;
button3.Enabled = true;
}
else
{
button1.Enabled = false;
button3.Enabled = false;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (port.IsOpen) port.Close();
port.PortName = comboBox1.Text;
port.BaudRate = Convert.ToInt32(comboBox2.Text);
port.ReadTimeout = 1000;
port.WriteTimeout = 1000;
//port.Parity = Parity.No;
port.DataBits = Convert.ToInt32("8");
//port.StopBits = StopBits.Bits1;
port.Handshake = Handshake.None;
try
{
port.Open();
}
catch
{
MessageBox.Show("Порт " + port.PortName + " невозможно открыть!", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
comboBox1.SelectedText = "";
}
//port.WriteLine(this.textBox1.Text);
byte[] buffer = new byte[6] { 0x02, 0x03, 0x06, 0x30, 0x41, 0xB3 };
port.Write(buffer, 1, 5);
//label4.Text = port.BytesToRead.ToString();
//label5.Text = port.BytesToWrite.ToString();
if (port.IsOpen) port.Close();
}
/*
private void SetText(string text)
{
if (this.listBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.AddData(text);
}
}
*/
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
button1.Text = "Стоп";
Application.DoEvents();
button1_Click(sender, e);
Application.DoEvents();
}
//принять из порта
private void button3_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[6] { 0x02, 0x03, 0x06, 0x30, 0x41, 0xB3 };
CommPort port2 = new CommPort((comboBox1.SelectedIndex + 1), 115200, 8, Parity.No, StopBits.Bits1);
if (port2.Open())
{
port2.Write(buffer);
//byte[] buff = new byte[port2.BytesToRead];
//port2.Read(buff);
byte[] data = port2.Read(2);
char dd;
string ss = "";
foreach (byte b in data)
{
dd = Convert.ToChar(b);
string tmp = dd.ToString();
if (tmp == "\r") tmp = ";";
ss = ss + tmp;
}
listBox1.Items.Add(ss);
listBox1.SetSelected(listBox1.Items.Count - 1, true);
string[] sa = ss.Split(';');
string aa = "";
for (int i = 0; i < sa.Length; i++)
{
aa = aa + sa.GetValue(i).ToString() + ";";
}
port2.Close();
}
this.button2.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
}
}
класс для работы с портом:
namespace SerrialPortReader
{
public enum Parity : byte
{
No = 0,
Odd = 1,
Even = 2,
Mark = 3,
Space = 4
}
public enum StopBits : byte
{
Bits1 = 0,
Bits1_5 = 1,
Bits2 = 2
}
class CommPort
{
private int PortNum;
private int BaudRate;
private byte ByteSize;
private Parity parity;
private StopBits stopBits;
private int hPortHanle = INVALID_HANDLE_VALUE;
public CommPort(int PortNum, int BaudRate, byte ByteSize, Parity parity, StopBits stopBits)
{
this.PortNum = PortNum;
this.BaudRate = BaudRate;
this.ByteSize = ByteSize;
this.parity = parity;
this.stopBits = stopBits;
}
public bool Open()
{
// Открытие порта
hPortHanle = CreateFile("COM" + PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0);
if(hPortHanle == INVALID_HANDLE_VALUE)
{
return false;
}
// Настройка порта
DCB dcbCommPort = new DCB();
GetCommState(hPortHanle, ref dcbCommPort);
dcbCommPort.BaudRate = BaudRate;
dcbCommPort.Parity = (byte)parity;
dcbCommPort.ByteSize = ByteSize;
dcbCommPort.StopBits = (byte)stopBits;
if (!SetCommState(hPortHanle, ref dcbCommPort))
{
return false;
}
return true;
}
// Возврашает true, если порт открыт
public bool IsOpen()
{
return(hPortHanle!=INVALID_HANDLE_VALUE);
}
// Закрытие порта
public void Close()
{
if (IsOpen())
{
CloseHandle(hPortHanle);
}
}
// Чтение данных
public byte[] Read(int NumBytes)
{
byte[] BufBytes;
byte[] OutBytes;
BufBytes = new byte[NumBytes];
if (hPortHanle!=INVALID_HANDLE_VALUE)
{
int BytesRead=0;
ReadFile(hPortHanle, BufBytes, NumBytes, ref BytesRead, 0);
OutBytes = new byte[BytesRead];
Array.Copy(BufBytes, OutBytes, BytesRead);
}
else
{
throw(new ApplicationException("Порт не был открыт"));
}
return OutBytes;
}
// Передача данных
public void Write(byte[] WriteBytes)
{
if (hPortHanle!=INVALID_HANDLE_VALUE)
{
int BytesWritten = 0;
WriteFile(hPortHanle,WriteBytes,WriteBytes.Length,ref BytesWritten, 0);
}
else
{
throw(new ApplicationException("Порт не был открыт"));
}
}
// Описание констант Win32 API
private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const int OPEN_EXISTING = 3;
private const int INVALID_HANDLE_VALUE = -1;
[StructLayout(LayoutKind.Sequential)]
public struct DCB
{
public int DCBlength;
public int BaudRate;
/*
public int fBinary;
public int fParity;
public int fOutxCtsFlow;
public int fOutxDsrFlow;
public int fDtrControl;
public int fDsrSensitivity;
public int fTXContinueOnXoff;
public int fOutX;
public int fInX;
public int fErrorChar;
public int fNull;
public int fRtsControl;
public int fAbortOnError;
public int fDummy2;
*/
public uint flags;
public ushort wReserved;
public ushort XonLim;
public ushort XoffLim;
public byte ByteSize;
public byte Parity;
public byte StopBits;
public char XonChar;
public char XoffChar;
public char ErrorChar;
public char EofChar;
public char EvtChar;
public ushort wReserved1;
}
[DllImport("kernel32.dll")]
private static extern int CreateFile(
string lpFileName,
uint dwDesiredAccess,
int dwShareMode,
int lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
int hTemplateFile
);
[DllImport("kernel32.dll")]
private static extern bool GetCommState(
int hFile, // дескриптор файла (порта)
ref DCB lpDCB // структура DCB
);
[DllImport("kernel32.dll")]
private static extern bool SetCommState(
int hFile, // дескриптор файла (порта)
ref DCB lpDCB // структура DCB
);
[DllImport("kernel32.dll")]
private static extern bool ReadFile(
int hFile, // дескриптор файла (порта)
byte[] lpBuffer, // буфер
int nNumberOfBytesToRead, // размер буфера
ref int lpNumberOfBytesRead,// реально прочитано
int lpOverlapped // 0 для синхронных операций
);
[DllImport("kernel32.dll")]
private static extern bool WriteFile(
int hFile, // дескриптор файла (порта)
byte[] lpBuffer, // буфер данных
int nNumberOfBytesToWrite, // число байт данных
ref int lpNumberOfBytesWritten, // реально переданное число байт
int lpOverlapped // 0 для синхронных операций
);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(
int hObject // дескриптор файла (порта)
);
}
}
12.11.08 10:53: Перенесено модератором из 'C/C++' — Кодт