CVI 串口调试助手

基于Labwindows CVI 2017编写的一个简单的串口调试助手,附带接收一个00–99的两位数并进行波形绘制的功能,编写过程可见:https://blog.csdn.net/Stark_/article/details/129003839

#include <ansi_c.h>
#include <rs232.h>
#include <cvirte.h>        
#include <userint.h>
#include "SerialDebug.h"

#define MAX_BUF_NUM 512

static int panelHandle;       //主界面句柄

int comSelect = 0;   //串口号
int status;
int ComState = 0;  //串口开关状态
char info[MAX_BUF_NUM+1]; //串口数据缓冲区
//设置页面控件状态,stat = 0表示关闭,1表示打开
//SetCtrlAttribute(,,ATTR_DIMMED,)将对应控件属性变暗和变亮,以禁用和使用对应控件
int CVIFUNC DimObject(int stat)
{
    SetCtrlAttribute(panelHandle,PANEL_COMSELECT,ATTR_DIMMED,stat); //串口号选择 
    SetCtrlAttribute(panelHandle,PANEL_BAUDSELECT,ATTR_DIMMED,stat); //波特率
    SetCtrlAttribute(panelHandle,PANEL_CHECKSELECT,ATTR_DIMMED,stat);//校验位
    SetCtrlAttribute(panelHandle,PANEL_LONGSELECT,ATTR_DIMMED,stat); //数据位
    SetCtrlAttribute(panelHandle,PANEL_STOPSELECT,ATTR_DIMMED,stat);//停止位
    SetCtrlAttribute(panelHandle,PANEL_OPEN_COM,ATTR_DIMMED,stat);  //打开串口
    
    SetCtrlVal(panelHandle,PANEL_LED,stat);   //LED 
    
    SetCtrlAttribute(panelHandle,PANEL_CLOSE_COM,ATTR_DIMMED,!stat); //关闭串口
    SetCtrlAttribute(panelHandle,PANEL_SEND,ATTR_DIMMED,!stat);//发送
    
    return 0;    
}

int main (int argc, char *argv[])
{
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;    /* out of memory */
    if ((panelHandle = LoadPanel (0, "SerialDebug.uir", PANEL)) < 0)
        return -1;
    DimObject(0);
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);
    return 0;
}

int CVICALLBACK PanelMain (int panel, int event, void *callbackData,
                           int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_GOT_FOCUS:

            break;
        case EVENT_LOST_FOCUS:

            break;
        case EVENT_CLOSE:
                QuitUserInterface (0);//关闭面板0(主面板)
            break;
    }
    return 0;
}

int CVICALLBACK ComOpen (int panel, int control, int event,
                         void *callbackData, int eventData1, int eventData2)
{
    int comValue,baudValue,checkValue,longValue,stopValue; 
    switch (event)
    {
        case EVENT_COMMIT:
                GetCtrlVal(panelHandle,PANEL_COMSELECT,&comValue); //获取串口号
                GetCtrlVal(panelHandle,PANEL_BAUDSELECT,&baudValue); //获取波特率 
                GetCtrlVal(panelHandle,PANEL_CHECKSELECT,&checkValue);//获取校验位
                GetCtrlVal(panelHandle,PANEL_LONGSELECT,&longValue);//获取数据位
                GetCtrlVal(panelHandle,PANEL_STOPSELECT,&stopValue);//获取停止位
                //设置和打开串口
                status = OpenComConfig(comValue,"",baudValue,checkValue,longValue,stopValue,MAX_BUF_NUM,MAX_BUF_NUM);
                if(status!=0)
                {
                    MessagePopup("Error","config failed!");   //弹窗提示
                    ComState = 0;
                    return 0;
                }
                SetCTSMode(comValue,LWRS_HWHANDSHAKE_OFF); /* 禁止硬件握手,即不用RTS/CTS和DTR/DSR */
                FlushInQ(comValue);   //清空输入队列的缓存数据
                FlushOutQ(comValue);  //清空输出队列的缓存数据
                comSelect = comValue;
                DimObject(1);
                ComState = 1;  //串口开启状态
            break;
    }
    return 0;
}

int CVICALLBACK ClearTextBox (int panel, int control, int event,
                              void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:
                if(control == PANEL_CLEARRECEIVE)//清除接收控件
                    ResetTextBox(panelHandle,PANEL_RECEIVETEXT,"\0");//清除接收框
                else
                    ResetTextBox(panelHandle,PANEL_SENDTEXT,"\0");//清除发送框
            break;
    }
    return 0;
}

int CVICALLBACK Send (int panel, int control, int event,
                      void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:
                if(!comSelect) return -1; //发送出错
                GetCtrlVal(panelHandle,PANEL_SENDTEXT,info);//获取要发送的文本
                status = ComWrt(comSelect,info,strlen(info));//发送
                if(status != strlen(info))
                    MessagePopup("Error","Send data failed!");  //弹窗提示
            break;
    }
    return 0;
}

int CVICALLBACK Timer (int panel, int control, int event,
                       void *callbackData, int eventData1, int eventData2)
{
    int i = 0;
    int len = 0;
    double point = 0;
    
    switch (event)
    {
        case EVENT_TIMER_TICK:
                if(ComState)
                {
                    if(!comSelect) return -1;
                    SetComTime(comSelect,1); //设置一帧数据的接收超时时间为1s
                    len = GetInQLen(comSelect);
                    status = ComRd(comSelect,info,len);//接收,GetInQLen用于得到Com口的输入队列数据缓存的大小
                    if(status<=0)
                    {
                        //MessagePopup("Error","Read data failed!");   //弹窗提醒没有读取到信息
                        break;
                    }
                    //将信息写入接收框
                    info[status] = '\0';
                    SetCtrlVal(panelHandle,PANEL_RECEIVETEXT,info); //设置接收文本框显示info的内容
                    SetActiveCtrl(panelHandle,PANEL_RECEIVETEXT);    
                    
                    if((len == 2)||(info[2] == 0x0D))  //收到两个字符,或者第三个字符是回车
                    {
                        point = (info[0]-48)*10 + (info[1]-48);   //接收一个两位数,比如 01、09、10、90、AB
                        if((point>=0)&&(point<=99))//判定这个两位数属于00-99之间
                        {
                            PlotStripChartPoint(panelHandle,PANEL_WAVE_DISPLAY,point);    //对于在范围内的数据进行绘制点
                        }
                    }
                    
                    for(0;i<len;i++)
                    {
                        info[i]=0;
                        i++;
                    }
                }
            break;
    }
    return 0;
}

int CVICALLBACK ComClose (int panel, int control, int event,
                          void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:
               CloseCom(comSelect);        //关闭串口
               comSelect = 0;
               DimObject(0);
               ComState = 0; 
            break;
        case EVENT_TIMER_TICK:

            break;
    }
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 串口调试助手是一种用于通过计算机与串口设备进行通信和调试的工具。CVI(即LabWindows/CVI)是一种基于C语言开发的集成开发环境,我们可以使用CVI来编写串口调试助手。 首先,我们需要在CVI中创建一个新的项目。然后,我们可以使用CVI提供的函数库来进行串口通信。通过使用CVI串口编程函数,我们可以打开串口、配置串口参数(如波特率、数据位数、校验位、停止位等)、发送数据和接收数据等。 接下来,我们可以通过编写代码来实现串口调试助手的功能。例如,我们可以设计一个用户界面,用于设置串口参数和发送数据。在用户界面中,可以包括一个下拉菜单用于选择串口号,一个输入框用于输入要发送的数据等。当用户设置好参数并点击发送按钮时,我们可以调用CVI提供的发送数据函数将数据发送到选定的串口。 在接收数据方面,我们可以通过编写一个循环来不断接收串口传来的数据,并将数据显示在用户界面的接收区域中。我们可以使用CVI的接收数据函数来获取串口接收缓冲区中的数据,并将其显示在用户界面上。 此外,我们还可以添加其他功能,如清空接收区、保存接收数据日志、接收数据校验等。 最后,我们可以通过编译和构建应用程序来生成可执行文件,用户可以在计算机上运行该文件,实现串口调试助手的功能。 总结起来,CVI提供了一套强大的函数库和开发环境,可以帮助我们编写串口调试助手。通过使用CVI,我们可以方便地实现串口通信、发送和接收数据等功能,并为用户提供一个友好的界面来操作和显示数据。 ### 回答2: CVI(LabWindows/CVI)是一个面向工程师和科学家的图形化开发环境,用于编写控制、测试和测量应用程序。要编写串口调试助手,可以使用CVI提供的串口通信库函数和图形界面设计工具来实现。 首先,使用CVI的图形界面设计器创建一个用户界面。可以添加文本框用于显示接收到的串口数据,添加输入框用于发送指令,还可以添加按钮和菜单等用户交互元素。 然后,在代码中调用CVI提供的串口通信库函数。首先需要初始化串口参数,如波特率、数据位、校验位等。可以使用函数`serial_open`打开串口,并用`serial_configurate`设置串口参数。然后可以调用`serial_read`在接收缓冲区中读取数据,并在界面的文本框中显示出来。使用`serial_write`函数可以发送数据到串口。 接下来,可以使用CVI的事件处理函数来处理按钮点击事件和串口接收事件。当用户点击发送按钮时,可以调用`serial_write`函数发送输入框中的指令到串口。当从串口接收到数据时,可以调用`serial_read`函数并更新界面的文本框来显示接收到的数据。 最后,在程序退出时,记得关闭串口连接,可以使用`serial_close`函数来关闭串口。 通过上述步骤,就可以用CVI编写一个串口调试助手。这个助手能够提供串口数据的接收和发送功能,并将接收到的数据显示在界面上,用户可以通过界面来发送指令到串口。 ### 回答3: CVI(C语言编写的虚拟仪器)是一种用于开发控制和测量应用程序的软件工程平台。要编写串口调试助手,我们可以利用CVI的功能来实现。 首先,我们需要使用CVI提供的库函数来操作串口CVI提供了一些函数,例如open、read和write,用于打开和关闭串口,并读取和写入数据。 接下来,我们可以创建用户界面来实现串口调试助手CVI提供了图形用户界面(GUI)设计器,使我们能够轻松地设计用户友好的界面。我们可以添加文本框来显示接收到的串口数据,并添加一个发送按钮来向串口发送数据。通过这些控件,用户可以实时地接收和发送数据。 在后台,我们可以使用CVI提供的函数来监听串口数据。当我们接收到新数据时,我们可以将它显示在文本框中。对于发送操作,我们可以在点击发送按钮时,使用CVI提供的函数将文本框中的数据发送到串口。 除了基本的读写功能,我们还可以利用CVI来实现其他功能,例如数据处理和保存功能。我们可以使用CVI提供的函数来处理和解析接收到的数据,并将处理后的数据保存到文件中。 最后,我们可以使用CVI提供的调试工具来测试和调试串口调试助手CVI提供了一些功能强大的调试工具,例如断点和变量监视器,并且可以方便地查看和分析程序中的错误和问题。 总之,使用CVI编写串口调试助手可以使我们更高效地实现串口通信功能,并且提供了友好的用户界面和各种调试工具来保证软件的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值