/// <summary> /// 定时器Elapsed事件注册的委托所持有的方法 /// 每当定时时间到,会异步执行该方法,需要加锁 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TimerSend_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { lock (lock_TimerSend_Elapsed) //加锁,同一时间,只有唯一线程执行此代码,其余线程等待访问 { if (!this.TimerSend.Enabled) { return; } if (CanDevice.VCI_Transmit(this.currentDeviceInfo.m_devtype, this.currentDeviceInfo.m_devind, this.currentDeviceInfo.m_canind, ref this.TransmitCanFrame, 1) == 0) { ///如果数据帧传输失败: //设置定时器的使能 this.TimerSend.Enabled = false; //设置btnSend的状态 _form1.SetBtnSendEnableInvoke(true); //设置发送状态为false this.TransmitFlag = false; MessageBox.Show("数据发送错误,实际发送帧数为0", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } else { ///如果数据帧传输成功: //1.获取传输时间 this.TransmitTime = DateTime.Now.ToString("hh:mm:ss:fff"); //2.如果为固定次数发送时,每传输成功1次,发送次数-1 if (this.SendCount != -1 && --this.SendCount == 0) { //设置定时器的使能 this.TimerSend.Enabled = false; //设置btnSend的状态 _form1.SetBtnSendEnableInvoke(true); //设置发送状态为false this.TransmitFlag = false; } else if (SendCount == -1) //2.如果为无限循环发送,FrameCount == -1 { } } ///执行至此时,有一帧数据传输成功了,传输数据数+1,存储这帧数据 this.TransmitNum++; this._dataRecoder_FT.AddRows(this.TransmitCanFrame, this.TransmitTime, "发送"); } }
/// <summary> /// 窗体关闭前事件的注册函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (frameTransmiter.TransmitFlag) { MessageBox.Show("关闭前请先停止发送数据", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); e.Cancel = true; } else { this.frameReceiver.TimerReceive.Enabled = false; CanDevice.VCI_ResetCAN(currentDevice.m_devtype, currentDevice.m_devind, currentDevice.m_canind); CanDevice.VCI_CloseDevice(currentDevice.m_devtype, currentDevice.m_devind); this.Dispose(); Application.Exit(); } }
private void btnStartCan_Click(object sender, EventArgs e) { if (currentDevice.m_bOpen == 0) { return; } if (CanDevice.VCI_StartCAN(currentDevice.m_devtype, currentDevice.m_devind, currentDevice.m_canind) == 0) { MessageBox.Show("启动can失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { btnStartCan.Enabled = false; btnReset.Enabled = true; //使能循环显示定时器 timerDisplay.Enabled = true; //使能接收定时器 this.frameReceiver.TimerReceive.Enabled = true; } }
private void btnReset_Click(object sender, EventArgs e) { if (currentDevice.m_bOpen == 0) { return; } if (frameTransmiter.TransmitFlag) { //有数据在发送,弹窗提示,返回 MessageBox.Show("请先停止数据发送", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } //使能接收定时器为false this.frameReceiver.TimerReceive.Enabled = false; CanDevice.VCI_ResetCAN(currentDevice.m_devtype, currentDevice.m_devind, currentDevice.m_canind); btnStartCan.Enabled = true; btnReset.Enabled = false; //使能循环显示定时器false timerDisplay.Enabled = false; }
/// <summary> /// 接收定时器的elapsed事件注册的方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TimerReceive_Elapsed(object sender, ElapsedEventArgs e) { //获取指定接收缓冲区接收到但尚未被读取的帧数 this.ReceiveNum = CanDevice.VCI_GetReceiveNum(this.currentDeviceInfo.m_devtype, this.currentDeviceInfo.m_devind, this.currentDeviceInfo.m_canind); if (this.ReceiveNum == 0) { return; } //调用函数,从设备读取数据,读取出的数据从pt内存指针开始存 this.ReceiveNum = CanDevice.VCI_Receive(this.currentDeviceInfo.m_devtype, this.currentDeviceInfo.m_devind, this.currentDeviceInfo.m_canind, pt, con_maxlen, 100); this.ReceiveTime = DateTime.Now.ToString("hh:mm:ss:fff"); //遍历存储信息帧结构体的内存 for (int i = 0; i < this.ReceiveNum; i++) { this.ReceiveFrame = (VCI_CAN_OBJ)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(VCI_CAN_OBJ))), typeof(VCI_CAN_OBJ)); //存储这帧数据 this._dataRecoder_REC.AddRows(this.ReceiveFrame, this.ReceiveTime, "接收"); } //释放以前从进程的非托管内存中分配的内存。 //Marshal.FreeHGlobal(pt); }
/// <summary> /// 连接设备按钮点击事件的注册函数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnConnect_Click(object sender, EventArgs e) { if (currentDevice.m_bOpen == 1) { ///如果设备打开标志为1,即设备打开则执行关闭设备 //1.先判断是否处于数据发送中 if (frameTransmiter.TransmitFlag) { //有数据在发送,弹窗提示,返回 MessageBox.Show("请先停止数据发送", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } //2.没有数据在发送,则执行关闭设备 if (CanDevice.VCI_CloseDevice(currentDevice.m_devtype, currentDevice.m_devind) == 1) { //设备关闭成功,将设备打开标志位置0 currentDevice.m_bOpen = 0; //使能接收定时器为false this.frameReceiver.TimerReceive.Enabled = false; //复位can CanDevice.VCI_ResetCAN(currentDevice.m_devtype, currentDevice.m_devtype, currentDevice.m_devind); //传输数据次数清空 frameTransmiter.TransmitNum = 0; //发送次数清空 frameTransmiter.SendCount = 0; //接收数据数清空 dataRecoder.DataNum = 0; //设置按钮状态 btnStartCan.Enabled = true; btnReset.Enabled = false; //清空dataRecorder中的数据存储区datatable和datatablewatch和listid dataRecoder.dataTable.Clear(); dataRecoder.dataTableWatch.Clear(); dataRecoder.listId.Clear(); //使能循环显示定时器为false timerDisplay.Enabled = false; //清空dataGridview1 dataGridView1.Rows.Clear(); } else { //设备关闭失败,弹窗 MessageBox.Show("设备关闭失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } } else { //如果设备打开标志为0,即设备关闭则打开设备 //1.设置当前设备参数 currentDevice.m_devtype = currentDevice.m_arrdevtype[cboDeviceType.SelectedIndex]; currentDevice.m_devind = (UInt32)cboDevIndex.SelectedIndex; currentDevice.m_canind = (UInt32)cboCanIndex.SelectedIndex; //2.调用设备打开函数,打开设备 if (CanDevice.VCI_OpenDevice(currentDevice.m_devtype, currentDevice.m_devind, 0) == 0) { //设备打开失败,弹窗提示 MessageBox.Show("打开设备失败,请检查设备类型和设备索引号是否正确", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } try { //3.实例化currentDevice中的结构体成员config currentDevice.m_devConfig = new VCI_INIT_CONFIG(); //4.将验收码文本框中的文本以16进制数字字符串的形式转换为32位无符号整数,再赋值给初始化can配置结构体的对应成员 currentDevice.m_devConfig.AccCode = Convert.ToUInt32(txtAccCode.Text.Trim(), 16); //5.将屏蔽码文本框中的文本。。。 currentDevice.m_devConfig.AccMask = Convert.ToUInt32(txtAccMask.Text.Trim(), 16); //6.将定时器0的文本框中的文本以16进制数字字符串形式转换成8位无符号整数,再赋值给初始化can配置结构体的成员 currentDevice.m_devConfig.Timing0 = Convert.ToByte(txtTime0.Text.Trim(), 16); //7.将定时器1 currentDevice.m_devConfig.Timing1 = Convert.ToByte(txtTime1.Text.Trim(), 16); } catch { MessageBox.Show("can参数设置错误", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } //8.将模式下拉框选择项的索引号强制转换为字节数据,赋值给初始化can配置结构体的成员 currentDevice.m_devConfig.Mode = (byte)cboMode.SelectedIndex; //9.将滤波方式下拉框。。。 currentDevice.m_devConfig.Filter = (byte)cboFilter.SelectedIndex; //12.调用初始化can配置函数,初始化当前连接的设备 if (CanDevice.VCI_InitCAN(currentDevice.m_devtype, currentDevice.m_devind, currentDevice.m_devind, ref currentDevice.m_devConfig) == 0) { MessageBox.Show("初始化can配置错误", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } //13.设备打开成功,将设备打开标志位置1 currentDevice.m_bOpen = 1; } //通过设备打开标志,设置按钮文本 btnConnect.Text = currentDevice.m_bOpen == 1 ? "关闭设备" : "连接设备"; }