FPGA + labwindows/CVI 2017 串口通信 电子钟

1 篇文章 0 订阅

1. 描述

基于上一个FPGA的数字钟的实验,采用CVI2017制作了一个简单的上位机软件。实现了上位机和FPGA开发板同时可以显示时间、设置时间、蜂鸣器报警、LED灯闪烁等功能。FPGA开发板和上位机采用串口的方式通信。上一篇博文的链接:https://blog.csdn.net/qq_42965223/article/details/109432049

2.环境

硬件:硬件 :altera公司的Cyclone IV --EP4CE6F17C8N
软件:Quartus Prime Lite Edition 17.1
Labwindows/CVI 2017
操作系统:Windows10家庭版

3.整体框架

整个实验除了在开发板上实现数字钟的功能,在上位机也实现了类似功能的界面,通过每秒上发的16进制时间信息更新上位机显示。上位机的按键在按下后也会下发数据给开发板,开发板接收到数据后进行处理触发软按键实现按键按下的效果。其顶层文件框架如下所示:
顶层文件实现框架
与上位机通信的相关数据帧定义如下所示:

通信数据帧
顶层文件的输入输出如下所示:
顶层模块输入输出
管脚分配如下图所示:

管脚分配

4.具体实现思路

a. 顶层模块概述

串口收发模块

串口收发模块主要参考了开发板的串口例程,并且在顶层文件中编写了发送状态机,可以发送任意字节的数据。串口收发模块的输入输出如下图所示:
在这里插入图片描述
如上,CLK_FRE为输入时钟(和上个实验一样为50MHz)115200表示的是波特率,Clk也为系统时钟,Nrst为复位信号,tx_data(rx_data)为一个8位的数据,tx_data_valid 为 发送数据有效信号(也就是由外部控制(相对于串口模块)的输入信号,要发送数据时可置为有效),tx_data_ready 为串口模块输出信号,表示模块自身已经准备好发送了。同理接收模块的对应信号意思相近。后面会附上模块具体实现代码。通过对串口模块相应位的检测判断,可以在顶层文件中实现对个Byte数据的发送。其具体实现代码如下

//notes: state machine   compose the IDEL-WAIT-SEND state  
always@(posedge Clk or negedge Nrst)
begin
    if(Nrst == 1'b0)
    begin
        wait_cnt <= 32'd0;
        tx_data <= 8'd0;
        state <= IDLE;
        tx_cnt <= 8'd0;
        tx_data_valid <= 1'b0;
		 
    end
    else
    begin
        case (state)

            //idel state
            IDLE: state <= SEND;

            //sending state
            SEND:
            begin
                wait_cnt <= 32'd0;

                if(IsCommandData == 1'b1) tx_data <= tx_str1;   //select send Cmd or Time
                else tx_data <= tx_str;

                //the first 6 data represents time and the last data is command states
                if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1 && tx_cnt < 8'd4)
                begin
                    tx_cnt <= tx_cnt + 8'd1;    //sent byte counter
                end
                else if (tx_data_valid && tx_data_ready) //last byte sending is completed
                begin
                    tx_cnt <= 8'd0;            //clear counter
					tx_data_valid <= 1'b0;     //
                    IsCommandData <= 1'b0; 
                    state <= WAIT;
                end
                else if(~tx_data_valid)
			    begin
				    tx_data_valid <= 1'b1;
			    end
            end

            //waitting state
            WAIT:
            begin
                wait_cnt <= wait_cnt + 32'd1;     //wait counter(send data to PC every seconds)
                
                if(tx_data_valid && tx_data_ready) 
                begin
                    tx_data_valid <= 1'b0;
                end
                //todo: we can add other trigger conditions here
                 else if (wait_cnt >= CLK_FRE * 1000000)  //wait time is up and change to sending state
                 begin
                     state <= SEND;
 				    tx_cnt <= 8'd0;   
                 end  
                else if(IsAnyKeyTrg)
                begin
                    state <= SEND;
                    IsCommandData <= 1'b1;
                    //tx_cnt <= 8'd0;
                end
            end    

            default: state <= IDLE;
        endcase  //endcase   
    end
end

然后再在另一个块语句中实现发送数据的切换,实现方式如下:

//notes: change send bytes
always@(*)
begin
    case(tx_cnt)
        8'd0 :  tx_str <= 8'hbb;
	    8'd1 :  tx_str <= {wHorCntShi,wHorCntGe};
 	    8'd2 :  tx_str <= {wMinCntShi,wMinCntGe};
	    8'd3 :  tx_str <= {wSecCntShi,wSecCntGe};       
        8'd4 :  tx_str <= 8'hee;
	    default:tx_str <= 8'd0;
    endcase
end


//notes: send command
always@(*)
begin
    case(tx_cnt)
	    8'd0 :  tx_str1 <= 8'haa;
        8'd1 :  tx_str1 <= 8'd0;
        8'd2 :  tx_str1 <= 8'd0;
 	    8'd3 :  tx_str1 <= {4'b0000,KeyValue};
	    8'd4 :  tx_str1 <= 8'hdd;
	    default:tx_str1 <= 8'd0;
    endcase
end

接收模块实现方法类似,在这就不粘贴代码了。在接收数据后,通过判断上位机发送的不同数据产生模拟的边沿触发时钟,送入失踪模块,实现像视同按键触发的效果。

时钟模块

时钟模块根据上一次实验做了些许修改,对滤波后的键值进行了输出共顶层模块使用。(实体按键按下时需要发送键值给上位机),其做的修改如下所示:
在这里插入图片描述

assign ISANYKEY = {NRST,wKeyBdSet,wKeyBdMadd,wKeyBdHadd};

然后再外面对模拟按键和实体按键进行相与操作,使得上位机和开发板上的实体按键都可以对数字钟进行控制。

//both the hard key and the simulated key works to control the system
assign FinalKeySet = (SoftKeySet && Keyset) ;     //keyset both hard and soft works
assign FinalKeyHadd = (SoftKeyHadd && Keyhadd);   
assign FinalKeyMadd = (SoftKeyMadd && Keymadd);
assign FianlReset  =  (SoftKeyReset && Nrst);
assign Buzz_out = BeepLock?TempBuzz_out:1;  //Lock the beep clock out
编码器模块

使用编码器模块主要是对时钟模块输出的段码再次进行转换,转为二进制后再通过串口模块发送给上位机。其实可以直接在时钟模块里增加输出端口,输出未转化的二进制数据,但是为了时钟模块的完整性(尽量使用上个实验一样的代码),就用了个编码器。代码如下:

module seg_coder(
                input            Nrst,
                input[6:0]       Seg_data,
                output[3:0]      Bin_data
);


reg[3:0]    rBin_data;

assign Bin_data = rBin_data;

always@(Seg_data or Nrst)
begin
    if (Nrst == 1'b0) 
    begin
        rBin_data <= 4'b0000;    
    end
    else
    begin
        case(Seg_data)
            7'b100_0000 : rBin_data <= 4'd0 ;
            7'b111_1001 : rBin_data <= 4'd1 ;
            7'b010_0100 : rBin_data <= 4'd2 ;
            7'b011_0000 : rBin_data <= 4'd3 ;
            7'b001_1001 : rBin_data <= 4'd4 ;
            7'b001_0010 : rBin_data <= 4'd5 ;
            7'b000_0010 : rBin_data <= 4'd6 ;
            7'b111_1000 : rBin_data <= 4'd7 ;
            7'b000_0000 : rBin_data <= 4'd8 ;
            7'b001_0000 : rBin_data <= 4'd9 ;
            7'b000_1000 : rBin_data <= 4'ha ;
            7'b000_0011 : rBin_data <= 4'hb ;
            7'b100_0110 : rBin_data <= 4'hc ;
            7'b010_0001 : rBin_data <= 4'hd ;
            7'b000_0110 : rBin_data <= 4'he ;
            7'b000_1110 : rBin_data <= 4'hf ;
            default :     rBin_data <= 4'd0 ;
        endcase  
    end
end
endmodule

5.上位机实现

上位机通过 CVI2017实现,因为刚开始学,实现的界面较为简单,调用的是其自带的串口库实现数据收发。包括一些设置按键和串口通信信息的设置输入框。上位机效果图如下所示:
电子钟CVI界面
其具体实现代码如下:

DigitalClock.c

#include <userint.h>
#include "DigitalClock.h"

/*================================================================
Title:		DigitalClock

Purpose:	FPGA Comprehensive Internship

Created on:	2020/11/24 at 19:37:03 by

Created by: NightVoyager

Copyright:	All Rights Reserved.

===================================================================*/

#include "main.h"

static int panelHandle = 0;
ST_COM gComParam;

//=======================================
static int InterFaceInit(int PanelHandle);
static void CtrlsDisable(int PanelHandle);
static void CtrlsEnable(int PanelHandle);
//=======================================

int main(int argc, char *argv[])
{
    int error = 0;
    //? Verify that weather the PC speaker can work
    //printf("%d",CVILowLevelSupportDriverLoaded());

    /* initialize and load resources */
    nullChk(InitCVIRTE(0, argv, 0));
    errChk(panelHandle = LoadPanel(0, "DigitalClock.uir", PANEL));

    /* display the panel and run the user interface */
    errChk(DisplayPanel(panelHandle));

    InterFaceInit(panelHandle); //init the controls

    errChk(RunUserInterface());

Error:
    /* clean up */
    if (panelHandle > 0)
        DiscardPanel(panelHandle);
    return 0;
}

//==============================================================================
// UI callback function prototypes

int CVICALLBACK panelCB(int panel, int event, void *callbackData,
                        int eventData1, int eventData2)
{
    if (event == EVENT_CLOSE)
        QuitUserInterface(0);
    return 0;
}

static int InterFaceInit(int PanelHandle)
{
    //init the segment-showing part
    SetCtrlAttribute(PanelHandle, PANEL_SEG_STR, ATTR_NO_EDIT_TEXT, 1);         //can't edit
    SetCtrlVal(PanelHandle, PANEL_SEG_STR, "00:00:00");                         //set the initial value
    SetCtrlAttribute(PanelHandle, PANEL_SEG_STR, ATTR_TEXT_BGCOLOR, VAL_BLACK); //set the segment's background color
    SetCtrlAttribute(PanelHandle, PANEL_SEG_STR, ATTR_TEXT_COLOR, VAL_RED);     //set the text's color

    //set the default Com information
    gComParam.PortNum = 6;
    gComParam.BaudRate = 9600;
    gComParam.DataBit = 8;
    gComParam.Parity = 0;
    gComParam.StopBit = 1;
    memset(gComParam.RecvData, 0, sizeof(gComParam.RecvData));
    memset(gComParam.SendData, 0, sizeof(gComParam.SendData));
    gComParam.SendData[0] = 0xaa; //set the command data's head and tail
    gComParam.SendData[2] = 0xdd;
    gComParam.IsSetBtnOk = 0;

    //disable the timer
    SetCtrlAttribute(PanelHandle, PANEL_TIMER, ATTR_ENABLED, 0);

    //CtrlsDisable
    CtrlsDisable(PanelHandle);
    return 0;
}

/*=============================================================
Function Name:CtrlsEnable
Description:鍦ㄥ仠姝㈡椂鍚敤鎺т欢
Input:鏃?
Output:鏃?
Notes锛氭棤
==============================================================*/
static void CtrlsEnable(int PanelHandle)
{
    //鍚敤鎺т欢
    SetCtrlAttribute(PanelHandle, PANEL_SEG_STR, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_LED3, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_LED2, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_LED1, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_LED0, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_MADD, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_HADD, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_SET, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_RESET, ATTR_DIMMED, 0);
    SetCtrlAttribute(PanelHandle, PANEL_BINBEEPCTRL, ATTR_DIMMED, 0);

    SetCtrlAttribute(PanelHandle, PANEL_TBN_COM, ATTR_DIMMED, 0);
}

/*=============================================================
Function Name:CtrlsDisable
Description:绂佺敤鎺т欢
Input:鏃?
Output:鏃?
Notes锛氭棤
==============================================================*/
static void CtrlsDisable(int PanelHandle)
{
    //绂佺敤鎺т欢
    SetCtrlAttribute(PanelHandle, PANEL_SEG_STR, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_LED3, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_LED2, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_LED1, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_LED0, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_MADD, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_HADD, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_SET, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_CBTN_RESET, ATTR_DIMMED, 1);
    SetCtrlAttribute(PanelHandle, PANEL_BINBEEPCTRL, ATTR_DIMMED, 1);

    SetCtrlAttribute(PanelHandle, PANEL_TBN_COM, ATTR_DIMMED, 1);
}

//===========================CallBack Function=======================================
int CVICALLBACK CbtnResetCallBack(int panel, int control, int event,
                                  void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
    case EVENT_COMMIT:
		  if(gComParam.IsComOpen == 1)
		  {
		  	  gComParam.SendData[1] = 0x0a;
              ComWrt(gComParam.PortNum, gComParam.SendData, 6);
		  }
        break;
    }
    return 0;
}

int CVICALLBACK CbtnSetCallBack(int panel, int control, int event,
                                void *callbackData, int eventData1, int eventData2)
{
    int CurrentVal = 0;

    switch (event)
    {
    case EVENT_COMMIT:
        GetCtrlVal(panel, PANEL_BINPOWCTRL, &CurrentVal);
        if (CurrentVal == 1 && gComParam.IsComOpen == 1)
        {
            gComParam.IsSetBtnOk = 1;
            gComParam.SendData[1] = 0x0b;
            ComWrt(gComParam.PortNum, gComParam.SendData, 6);
        }
        else if(CurrentVal == 0)
        {
            gComParam.IsSetBtnOk = 0;
        }

        break;
    }
    return 0;
}

int CVICALLBACK CbtnHaddCallBack(int panel, int control, int event,
                                 void *callbackData, int eventData1, int eventData2)
{
    int CurrentVal = 0;

    switch (event)
    {
    case EVENT_COMMIT:
        GetCtrlVal(panel, PANEL_BINPOWCTRL, &CurrentVal);

        if (CurrentVal == 1 && gComParam.IsComOpen == 1 && gComParam.IsSetBtnOk == 1)
        {
            gComParam.SendData[1] = 0x0d;
            ComWrt(gComParam.PortNum, gComParam.SendData, 6);
        }
        else
        {
            /* code */
        }

        break;
    }
    return 0;
}

int CVICALLBACK CbtnMaddCallBack(int panel, int control, int event,
                                 void *callbackData, int eventData1, int eventData2)
{
    int CurrentVal = 0;

    switch (event)
    {
    case EVENT_COMMIT:

        GetCtrlVal(panel, PANEL_BINPOWCTRL, &CurrentVal);

        if (CurrentVal == 1 && gComParam.IsComOpen == 1 && gComParam.IsSetBtnOk == 1)
        {
            gComParam.SendData[1] = 0x0e;
            ComWrt(gComParam.PortNum, gComParam.SendData, 6);
        }
        else
        {
            /* code */
        }
        break;
    }
    return 0;
}

int CVICALLBACK BinbtnOporClCallBack(int panel, int control, int event,
                                     void *callbackData, int eventData1, int eventData2)
{
    int currentVal;

    switch (event)
    {
    case EVENT_COMMIT:
        GetCtrlVal(panel, PANEL_BINPOWCTRL, &currentVal);
        if (currentVal)
        {
            CtrlsEnable(panel);

        }
        else
        {
            CtrlsDisable(panel);
			
        }

        break;
    }
    return 0;
}

int CVICALLBACK BinBeepCallBack(int panel, int control, int event,
                                void *callbackData, int eventData1, int eventData2)
{

    switch (event)
    {
    case EVENT_COMMIT:
			if(gComParam.IsComOpen == 1)
			{
				gComParam.SendData[1] = 0x10;
				ComWrt(gComParam.PortNum, gComParam.SendData, 6);
			}

        break;
    }
    return 0;
}

int CVICALLBACK CbtnHelpCallBack(int panel, int control, int event,
                                 void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
    case EVENT_COMMIT:
		MessagePopup("帮助",HelpText);
        break;
    }
    return 0;
}

//===========================CallBack Function=======================================

int CVICALLBACK ComBtnCallBack(int panel, int control, int event,
                               void *callbackData, int eventData1, int eventData2)
{
    int currentVal;
    int i = 0;

    switch (event)
    {
    case EVENT_COMMIT:
        GetCtrlVal(panel, PANEL_TBN_COM, &currentVal);
        if (currentVal)
        {
            gComParam.IsComOpen = 1;
            //enable the input of the  port config
            for (i = 16; i < 21; i++)
            {
                SetCtrlAttribute(panel, i, ATTR_DIMMED, 1);
            }

            //get the com configration
            GetCtrlVal(panel, PANEL_NUMERIC_PORT, &gComParam.PortNum);
            GetCtrlVal(panel, PANEL_RING_BDRATE, &gComParam.BaudRate);
            GetCtrlVal(panel, PANEL_RING_DB, &gComParam.DataBit);
            GetCtrlVal(panel, PANEL_RING_PAR, &gComParam.Parity);
            GetCtrlVal(panel, PANEL_RING_SP, &gComParam.StopBit);

            //open the port according to the parameter above
            OpenComConfig(gComParam.PortNum, "", gComParam.BaudRate, gComParam.Parity,
                          gComParam.DataBit, gComParam.StopBit, 100, 100);

            FlushInQ(gComParam.PortNum);
            FlushOutQ(gComParam.PortNum);

            SetCtrlAttribute(panel, PANEL_TIMER, ATTR_ENABLED, 1); //enable the timer
        }
        else
        {
            gComParam.IsComOpen = 0;
            //disable the input of the  port config
            for (i = 16; i < 21; i++)
            {
                SetCtrlAttribute(panel, i, ATTR_DIMMED, 0);
            }

            FlushInQ(gComParam.PortNum);
            FlushOutQ(gComParam.PortNum);
            //close the port due to the port number
            CloseCom(gComParam.PortNum);

            SetCtrlAttribute(panel, PANEL_TIMER, ATTR_ENABLED, 0); //disable the timer
        }

        break;
    }
    return 0;
}

int CVICALLBACK TimerCallBack(int panel, int control, int event,
                              void *callbackData, int eventData1, int eventData2)
{
    int StrLength = 0;
    char ShowData[100] = {00};

    switch (event)
    {
    case EVENT_TIMER_TICK:
        StrLength = GetInQLen(gComParam.PortNum);
        if (StrLength != 0)
        {
            //If it receives too much data to clean up, it will block the serial port
            ComRd(gComParam.PortNum, gComParam.RecvData, StrLength);
            // Is the time data ?
            if (gComParam.RecvData[0] == 0xbb && gComParam.RecvData[4] == 0xee)
            {
                sprintf(ShowData, "%02x:%02x:%02x", gComParam.RecvData[1],
                        gComParam.RecvData[2], gComParam.RecvData[3]);
                SetCtrlVal(panel, PANEL_SEG_STR, ShowData); //show the data
                //blink the led
                if (gComParam.RecvData[2] == 0x59 && gComParam.RecvData[3] >= 0x56)
                {
                    SetCtrlVal(panel, PANEL_LED0, ((gComParam.RecvData[3] == 0x56) ? 1 : 0));
                    SetCtrlVal(panel, PANEL_LED1, ((gComParam.RecvData[3] == 0x57) ? 1 : 0));
                    SetCtrlVal(panel, PANEL_LED2, ((gComParam.RecvData[3] == 0x58) ? 1 : 0));
                    SetCtrlVal(panel, PANEL_LED3, ((gComParam.RecvData[3] == 0x59) ? 1 : 0));
                }
                if (gComParam.RecvData[3] == 0x00)
                {
                    SetCtrlVal(panel, PANEL_LED3, 0); //Clear the last LED
                }
            }
            //Is the Command Data
            else if (gComParam.RecvData[0] == 0xaa && gComParam.RecvData[4] == 0xdd)
            {
                //
            }
            //Removes all characters from the input queue of the specified port.
            FlushInQ(gComParam.PortNum);
            FlushOutQ(gComParam.PortNum);
            memset(gComParam.RecvData, 0, sizeof(gComParam.RecvData));
        }
        break;
    }
    return 0;
}

头文件

/**************************************************************************/
/* LabWindows/CVI User Interface Resource (UIR) Include File              */
/*                                                                        */
/* WARNING: Do not add to, delete from, or otherwise modify the contents  */
/*          of this include file.                                         */
/**************************************************************************/

#include <userint.h>

#ifdef __cplusplus
    extern "C" {
#endif

     /* Panels and Controls: */

#define  PANEL                            1       /* callback function: panelCB */
#define  PANEL_SEG_STR                    2       /* control type: string, callback function: (none) */
#define  PANEL_LED3                       3       /* control type: LED, callback function: (none) */
#define  PANEL_LED2                       4       /* control type: LED, callback function: (none) */
#define  PANEL_LED1                       5       /* control type: LED, callback function: (none) */
#define  PANEL_LED0                       6       /* control type: LED, callback function: (none) */
#define  PANEL_CBTN_MADD                  7       /* control type: command, callback function: CbtnMaddCallBack */
#define  PANEL_CBTN_HADD                  8       /* control type: command, callback function: CbtnHaddCallBack */
#define  PANEL_CBTN_HELP                  9       /* control type: command, callback function: CbtnHelpCallBack */
#define  PANEL_CBTN_SET                   10      /* control type: command, callback function: CbtnSetCallBack */
#define  PANEL_CBTN_RESET                 11      /* control type: command, callback function: CbtnResetCallBack */
#define  PANEL_BINPOWCTRL                 12      /* control type: binary, callback function: BinbtnOporClCallBack */
#define  PANEL_BINBEEPCTRL                13      /* control type: binary, callback function: BinBeepCallBack */
#define  PANEL_DECORATION1                14      /* control type: deco, callback function: (none) */
#define  PANEL_DECORATION                 15      /* control type: deco, callback function: (none) */
#define  PANEL_NUMERIC_PORT               16      /* control type: numeric, callback function: (none) */
#define  PANEL_RING_BDRATE                17      /* control type: ring, callback function: (none) */
#define  PANEL_RING_PAR                   18      /* control type: ring, callback function: (none) */
#define  PANEL_RING_DB                    19      /* control type: ring, callback function: (none) */
#define  PANEL_RING_SP                    20      /* control type: ring, callback function: (none) */
#define  PANEL_TBN_COM                    21      /* control type: textButton, callback function: ComBtnCallBack */
#define  PANEL_DECORATION_2               22      /* control type: deco, callback function: (none) */
#define  PANEL_DECORATION_3               23      /* control type: deco, callback function: (none) */
#define  PANEL_TIMER                      24      /* control type: timer, callback function: TimerCallBack */


     /* Control Arrays: */

          /* (no control arrays in the resource file) */


     /* Menu Bars, Menus, and Menu Items: */

          /* (no menu bars in the resource file) */


     /* Callback Prototypes: */

int  CVICALLBACK BinBeepCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK BinbtnOporClCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK CbtnHaddCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK CbtnHelpCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK CbtnMaddCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK CbtnResetCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK CbtnSetCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK ComBtnCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK panelCB(int panel, int event, void *callbackData, int eventData1, int eventData2);
int  CVICALLBACK TimerCallBack(int panel, int control, int event, void *callbackData, int eventData1, int eventData2);


#ifdef __cplusplus
    }
#endif

6. 总结

本次食盐主要是对FPGA的Verilog语言编程的进一步学习,以及最近正好在学CVI,正好实践一下。项目的大部分代码及全部的思路已经在博文里面站下,若是需要源码的朋友,可以私信我。代码写的也不是很好,一起进步吧。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值