Labwindows中使用多线程编写编写一个串口通信函数并将串口接收到的数据显示在波形图表中,代码说明
时间: 2024-02-20 12:59:31 浏览: 282
LabWindows™CVI中的多线程技术 - National Instruments.pdf
以下是一个使用LabWindows中的多线程编写串口通信函数并将串口接收到的数据显示在波形图表中的示例代码。代码实现了在一个子线程中进行串口通信,并将接收到的数据存储在一个缓冲区中。主线程定期读取缓冲区中的数据,并将其添加到图形控件中进行显示。
```
#include <formatio.h>
#include <userint.h>
#include <utility.h>
#include <ansi_c.h>
#include <cvirte.h>
#include <multithread/multithread.h>
#include <visa.h>
#include <asynctmr.h>
#include <utility.h>
#define VISA_ADDR "ASRL1::INSTR" // 串口地址
#define BUF_SIZE 1024 // 缓冲区大小
#define TIMEOUT 2000 // 超时时间
static int panelHandle;
static int waveformHandle;
static int threadId;
static unsigned char buffer[BUF_SIZE];
static int bufferIndex = 0;
static int stopThread = 0;
static int stopTimer = 0;
static ViSession instr;
static int CVICALLBACK threadFunc(int reserved, int threadId, int handle);
static int CVICALLBACK timerFunc(int reserved, int timerId, int event, void *callbackData, int eventData1, int eventData2);
static void readData(void);
int main(int argc, char *argv[])
{
int error = 0;
unsigned long timeout = TIMEOUT;
int timerId = 0;
// 初始化LabWindows
if (InitCVIRTE(0, argv, 0) == 0)
return -1;
// 创建主面板
panelHandle = LoadPanel(0, "main.uir", PANEL);
if (panelHandle < 0)
return -1;
// 创建波形图表
waveformHandle = GetCtrlIndex(panelHandle, PANEL_WAVEFORM);
if (waveformHandle < 0)
return -1;
PlotY(waveformHandle, NULL, 0, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);
// 打开串口
error = viOpenDefaultRM(&instr);
if (error < 0)
return -1;
error = viOpen(instr, VISA_ADDR, VI_NULL, VI_NULL, &timeout);
if (error < 0)
return -1;
error = viSetAttribute(instr, VI_ATTR_TMO_VALUE, TIMEOUT);
if (error < 0)
return -1;
// 创建子线程
threadId = CreateThread(0, 0, threadFunc, NULL, 0, NULL);
if (threadId < 0)
return -1;
// 创建定时器
stopTimer = 0;
timerId = NewAsyncTimer(0, 100, 0, timerFunc, NULL);
if (timerId < 0)
return -1;
// 运行主循环
RunUserInterface();
// 关闭定时器
stopTimer = 1;
while (stopTimer)
Delay(1);
DiscardAsyncTimer(timerId);
// 关闭子线程
stopThread = 1;
while (stopThread)
Delay(1);
CloseThread(threadId);
// 关闭串口
viClose(instr);
viCloseDefaultRM();
// 关闭LabWindows
DiscardPanel(panelHandle);
CloseCVIRTE();
return 0;
}
static int CVICALLBACK threadFunc(int reserved, int threadId, int handle)
{
int error = 0;
unsigned long timeout = TIMEOUT;
int bytesRead = 0;
int i = 0;
while (!stopThread)
{
// 读取串口数据
error = viRead(instr, buffer + bufferIndex, BUF_SIZE - bufferIndex, &bytesRead);
if (error < 0)
continue;
bufferIndex += bytesRead;
// 处理串口数据
readData();
}
return 0;
}
static int CVICALLBACK timerFunc(int reserved, int timerId, int event, void *callbackData, int eventData1, int eventData2)
{
// 刷新波形图表
PlotY(waveformHandle, buffer, bufferIndex, VAL_UNSIGNED_CHAR, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);
bufferIndex = 0;
// 停止定时器
if (stopTimer)
return -1;
else
return 0;
}
static void readData(void)
{
int i = 0;
int j = 0;
// 处理串口数据
for (i = 0; i < bufferIndex; i++)
{
if (buffer[i] == '\n')
{
// 处理一行数据
for (j = 0; j < i; j++)
{
// 数据处理代码
}
// 清空缓冲区
memmove(buffer, buffer + i + 1, bufferIndex - i - 1);
bufferIndex -= i + 1;
i = -1;
}
}
}
```
该代码使用了LabWindows提供的多线程、定时器、VISA和图形控件等功能,可以实现在一个子线程中进行串口通信,并将接收到的数据显示在波形图表中。需要注意的是,该代码仅供参考,具体实现需要根据实际需求进行修改和调整。
阅读全文