从串口读取数据的问题 [英] problem reading data from serial port
问题描述
应用与芯片和芯片的对话串口COM1上的引脚端子。将命令从PC发送到终端
&应该显示加密的响应。但是,我只能捕获对第一个命令的响应。所有后续命令虽然被传送到终端,却无法获得&b
因此无法显示。终端肯定有一个响应,正如在后台运行的串口监视器应用程序所证实的那样。
所以问题是以下代码&如何修复它以便我可以捕获所有命令的所有响应。
Hi,
Application talks to a chip & pin terminal on serial port COM1. Sends commands from PC to terminal
& should display the encrypted responses back. However, I can capture the response to the 1st command only. All subsequent commands, although are transmitted to the terminal, fail to be
captured & hence cannot be displayed. There is definitely a response from the terminal as confirmed by a serial port monitor application running in the back ground.
So the question is what is wrong with the following code & how can I repair it so that I can capture all the responses to all the commands.
private void initialize_com_ports()
{
//let's assign the default parms to the output serial port structure
init_ip_serialport(); //initailize ip port setings - RX
init_op_serialport(); //initailize op port setings - TX
}
private void init_op_serialport()
{
//let's assign the default parms to the input serial port structure
op_serialport.PortName = def_ip_portname;
op_serialport.BaudRate = def_baudrate;
op_serialport.DataBits = def_databits;
op_serialport.Handshake = def_handshake;
op_serialport.Parity = def_parity;
op_serialport.StopBits = def_stopbits;
}
private void init_ip_serialport()
{
//let's assign the default parms to the input serial port structure
ip_serialport.PortName = def_ip_portname;
ip_serialport.BaudRate = def_baudrate;
ip_serialport.DataBits = def_databits;
ip_serialport.Handshake = def_handshake;
ip_serialport.Parity = def_parity;
ip_serialport.StopBits = def_stopbits;
// ip_serialport.ReadTimeout = 1000;
// ip_serialport.WriteTimeout = 1000;
}
private void test_harness() //we place our test script here
{
display_messages("Start Test Script.", 3);
display_messages("Reset Device.", 3);
byte[] op_data1 = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x00, 0x00, 0x00, 0xD5 }; //010004D0000000D5 -reset device
op_serialport.Write(op_data1, 0, op_data1.Length);
TX_Box.Items.Add(BitConverter.ToString(op_data1));
op_serialport.Close();
// write_read_op(op_data1);
MySerialReader(); //read the response from the terminal
byte[] op_data2 = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x01, 0x01, 0xD6 }; //010004D2010101D6 -reset display
write_read_op(op_data2);
display_messages("Reset Display.", 3);
byte[] op_data3 = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x60, 0x1F, 0x00, 0xAA }; //010004D0601F00AA -Monitor card status
write_read_op(op_data3);
display_messages("Monitor Card status.", 3);
byte[] op_data4 = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x61, 0x03, 0x00, 0xB7 }; //010004D0610300B7 -Monitor keyboard status
write_read_op(op_data4);
display_messages("Monitor Keyboard status.", 3);
byte[] op_data5 = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x0D, 0x01, 0xDA }; //010004D2010D01DA -Prompt for card
write_read_op(op_data5);
display_messages("Insert Test Card.", 3);
display_messages("Start Transaction Data.", 2);
byte[] op_data = new byte[] { 0x01, 0x00, 0x37, 0xDE, 0xD1, 0x00, 0x00, 0x32, //start transaction data
0xE0, 0x30, 0x9F, 0x02, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x9C, 0x01, 0x00, 0x9F, 0x21,
0x03, 0x01, 0x01, 0x01, 0x9A, 0x03, 0x11, 0x01,
0x01, 0x9F, 0x41, 0x02, 0x00, 0x01, 0xDF, 0xA2,
0x04, 0x01, 0x01, 0x5F, 0x2A, 0x02, 0x08, 0x26,
0xDF, 0xA2, 0x18, 0x01, 0x00, 0xDF, 0xA2, 0x04,
0x01, 0x01, 0x09};
write_read_op(op_data);
display_messages("Press Cancel", 3);
op_data = new byte[] { 0x01, 0x00, 0x46, 0xDE, 0xD2, 0x00, 0x00, 0x41, //continue Transaction
0xE0, 0x3F, 0xC0, 0x01, 0x01, 0xC2, 0x02, 0x36,
0x35, 0xDF, 0xA2, 0x18, 0x01, 0x00, 0xDF, 0xA3,
0x07, 0x02, 0x03, 0xE8, 0x8A, 0x02, 0x59, 0x32,
0x91, 0x0A, 0x37, 0xDD, 0x29, 0x75, 0xC2, 0xB6,
0x68, 0x2D, 0x00, 0x12, 0x9F, 0x1B, 0x04, 0x00,
0x00, 0x10, 0x00, 0x9F, 0x02, 0x06, 0x00, 0x00,
0x00, 0x04, 0x99, 0x99, 0x5F, 0x2A, 0x02, 0x09,
0x78, 0x9F, 0x1A, 0x02, 0x09, 0x78, 0xC3, 0x01,
0x01, 0xF1};
write_read_op(op_data);
//Wait for PIN Entry in progress
//Wait for Online request
display_messages("Enter PIN no.", 3);
op_data = new byte[] { 0x01, 0x00, 0x0E, 0xDE, 0xD2, 0x00, 0x00, 0x09, //Continue with NEGATIVE response
0xE0, 0x07, 0xC0, 0x01, 0x00, 0x8A, 0x02, 0x30,
0x30, 0xA4 };
write_read_op(op_data);
display_messages("Remove Test Card", 3);
op_data = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x0E, 0x01, 0xD9 }; //Prompt for removal of card
write_read_op(op_data);
display_messages("Reset Display.", 2);
op_data = new byte[] { 0x01, 0x00, 0x04, 0xD2, 0x01, 0x01, 0x01, 0xD6 }; //010004D2010101D6 -reset display
write_read_op(op_data);
display_messages("Reset Device.", 2);
op_data = new byte[] { 0x01, 0x00, 0x04, 0xD0, 0x00, 0x00, 0x00, 0xD5 }; //010004D0000000D5 -reset device
write_read_op(op_data);
display_messages("End of Script.", 3);
}
private void write_read_op(byte[] command)
{
//write operation - TX command
if (ip_serialport.IsOpen)
{
ip_serialport.Close();
}
op_serialport.Open();
op_serialport.Write(command, 0, command.Length);
TX_Box.Items.Add(BitConverter.ToString(command));
// op_serialport.DiscardOutBuffer();
op_serialport.Close();
// let's stick in a delay here - just for fun 400mS
// System.Threading.Thread.Sleep(400);
//read operation - RX command
MySerialReader(); //read the response from the terminal
}
private void display_messages(string message, int how_many)
{
if (how_many > 2)
{
MessageBox.Show(message);
}
RX_Box.Items.Add(message);
TX_Box.Items.Add(message);
}
private void MySerialReader()
{
ip_serialport.Open();
ip_serialport.DataReceived += serialPort_DataReceived;
// ip_serialport.Close(); //This causes the problems
}
public string RxString;
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RxString = ip_serialport.ReadExisting();
this.Invoke(new EventHandler(DisplayText_RX)); //<<-- ????!!!
}
private void DisplayText_RX(object sender, EventArgs e)
{
RX_Box.Items.Add(RxString);
}
有点长,但希望上面说得有道理。在此先感谢您的帮助。
问候
KM
Bit long, but hope the above makes some sense. Thanks in advance for all your assistance.
Regards
KM
推荐答案
this.Invoke(new EventHandler(DisplayText_RX));
每次你创建一个新的事件处理程序。这是必需品吗?
也许你只需要像
each time you create a new eventhandler. Is this necessarry?
maybe you just need something like
RX_Box.Invoke(new Action(()=> RX_Box.Items.Add(RxString)));
很难看出你的代码出错了,你可以捕获对第一个命令的响应,
很可能这是你港口的开启和关闭。
你也可以在同一个港口使用两个名字! ,这可以工作但是很混乱。
gggustafson的评论是现货!
这是帮助您走正确道路的一个例子:
It is difficult to see where Your code is wrong and You can capture the response to the 1st command,
so probably it is the opening and closing of you port.
Also You use two names for the same port!!! , this can work but is confusing.
The comment of gggustafson is spot on!
Here is an example to help you on the right path:
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;
using System.Threading;
using System.IO;
namespace Terminal
{
public partial class Form1 : Form
{
//Use only one serial port, change all ip_serialport to op_serialport
private SerialPort op_serialport= new SerialPort();
public string RxString;
public Form1()
{
InitializeComponent();
//Declare DataReceived_handler here only once!
op_serialport.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
//let's assign the default parms to the output serial port structure
init_op_serialport(); //initailize op port setings -RX/TX
// Open the port and keep it open until you close application!
OpenPort();
}
private void init_op_serialport()
{
//let's assign the default parms to the input serial port structure
op_serialport.PortName = def_ip_portname;
op_serialport.BaudRate = def_baudrate;
op_serialport.DataBits = def_databits;
op_serialport.Handshake = def_handshake;
op_serialport.Parity = def_parity;
op_serialport.StopBits = def_stopbits;
}
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
RxString = op_serialport.ReadExisting();
DisplayText_RX(RxString);
}
private void OpenPort()
{
bool error = false;
// If the port is open, close it.
if (op_serialport.IsOpen) op_serialport.Close();
//Add some error_handling!
try
{
// Open the port
op_serialport.Open();
}
catch (UnauthorizedAccessException) { error = true; }
catch (IOException) { error = true; }
catch (ArgumentException) { error = true; }
if (error) MessageBox.Show(this, "Could not open the COM port."+
" Most likely it is already in use,"+
"has been removed, or is unavailable.",
"COM Port Unavalible", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// here RX_Box = Ritch textbox
private void DisplayText_RX(string rxString)
{
RX_Box.Invoke(new EventHandler(delegate
{
RX_Box.AppendText(rxString);
}));
}
}
}
这篇关于从串口读取数据的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!