我有一个问题,我必须将大量数据保存到txt文件中,问题是我每隔100ns从串口接收一次。 我能怎么做?我试图将数据放在RichTextBox上但我收到一个线程错误。 抱歉我的英文。
我正在使用Windows 7 64位
private: void FindPorts(void)
{
array<Object^>^ ListaPorte = SerialPort::GetPortNames();
this->cmbPort->Items->AddRange(ListaPorte);
}
private: System::Void btnOpenPort_Click(System::Object^ sender, System::EventArgs^ e)
{
if(this->cmbPort->Text==String::Empty || this->cmbBaudRate->Text==String::Empty)
this->rtbLog->Text="cmbError";
else
{
try{
if(!this->serialPort->IsOpen)
{
this->serialPort->PortName = this->cmbPort->Text;
this->serialPort->BaudRate = Int32::Parse(this->cmbBaudRate->Text);
this->serialPort->Open();
this->rtbLog->Text+="Porta aperta\r\n";
this->btnOpenPort->Text="Close Port";
}
else
{
this->serialPort->Close();
this->rtbLog->Text+="Porta chiusa\r\n";
this->btnOpenPort->Text="Open Port";
}
}
catch(UnauthorizedAccessException^)
{
this->rtbLog->Text+="UnauthorizedAccessException\r\n";
}
}
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
if(!lettura)
{
lettura = true;
this->button1->Text="sto leggendo";
}
else
if(lettura)
{
lettura=false;
//rtbLog->Text += letturaBuffer;
this->button1->Text="sono ferma";
}
//serialPort->
}
private: System::Void serialPort_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e)
{
if(lettura){
//letturaBuffer += serialPort->ReadExisting() + "\r\n";
rtbLog->Text += serialPort->ReadExisting() + "\r\n";
}
}
答案 0 :(得分:2)
如果数据始终以100ns的间隔进行,那么在正常操作系统下,您将无法保持速度。 100ns间隔是10MHz所以你应该寻找可以处理这个速度的实时操作系统。要实时显示它,你需要轻量级组件,所以实际上你应该对RichTextBox进行基准测试并检查它是否可以处理10MHz。 您可能遇到的另一个问题是中断延迟,如果需要1us才能获得它,您已经错过了10次数据传输。
答案 1 :(得分:1)
您不太可能每100秒获取一次数据:标准串行端口的最大速度为每秒115,200位,即每秒11,520字节,最大值。即使您的事件已收到每个接收到的字节(也不太可能)的信号,这是每隔87微秒,而不是每100纳秒。
您遇到线程错误的原因是因为在线程池线程上调用了serialPort_DataReceived
方法,并且只能从UI线程访问UI组件。让我们解决这个问题,然后担心你想要这样做的频率,以及它是否可以在非RTOS中使用。
从您的代码看起来就像您使用的是WinForms,而不是WPF。试一试:
void AddAString(String^ s)
{
this->rtbLog->Text += (s + Environment::NewLine);
}
void serialPort_DataReceived(Object^ sender, SerialDataReceivedEventArgs^ e)
{
if(lettura)
{
this->BeginInvoke(
gcnew Action<String^>(this, MyClass::AddAString),
serialPort->ReadExisting());
}
}