C# WPF燃气报警器记录读取串口工具

embedded/2024/9/18 12:39:57/ 标签: c#, wpf, 开发语言

C# WPF燃气报警器记录读取串口工具

  • 概要
  • 串口帧数据
  • 布局文件
  • 代码文件
  • 运行效果
  • 源码下载

概要

  • 符合国标文件《GB+15322.2-2019.pdf》串口通信协议定义;
  • 可读取燃气报警器家用版设备历史记录信息等信息;
    在这里插入图片描述
    在这里插入图片描述

串口帧数据

串口通信如何确定一帧数据接收完成是个麻烦事,本文采用最后一次数据接收完成后再过多少毫秒认为一帧数据接收完成,开始解析出来。每次接收到数据更新一次recvTimems 。定时器mTimer定时周期10毫秒,定时器回调函数里判断接收时间超过20ms(这个时间的长短和串口波特率有关)认为一帧数据接收完成。接收数据时间差未超过20ms则将接收数据追加到rxBuf数据缓冲,

long recvTimems = 0;    // 用于计算串口接收完一帧数据
int rxLen = 0;  // 串口接收到的数据长度
byte[] rxBuff = new byte[128];  // 串口数据接收缓存
private static Timer mTimer;    // 定时器,10ms执行一次mTimer = new Timer(recvTimerCalback, null, 0, 10);  // 创建并启动定时器private void recvTimerCalback(object obj)
{//Console.WriteLine("timer callback!" + recvTimems);this.Dispatcher.Invoke(new Action(()=> {// UI线程分离,更新UI数据显示if (((Environment.TickCount - recvTimems) >= 20) && (rxLen > 0)){// 串口接收时间超过X ms认为一帧数据接收完成这里解析处理接收数据.....// 一帧数据处理结束清空数据缓冲Array.Clear(rxBuff, 0, rxBuff.Length);rxLen = 0;}}));  
}private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{SerialPort comPort = (SerialPort)sender;try{recvTimems = Environment.TickCount; // 更新串口数据接收时间//rxBuff[rxLen] = mSerialPort.ReadByte();int readCnt = mSerialPort.BytesToRead;Console.WriteLine("in readCnt:" + readCnt);mSerialPort.Read(rxBuff, rxLen, readCnt);rxLen += readCnt;Console.WriteLine("out rxLen:" + rxLen);}catch (Exception ce){MessageBox.Show(ce.Message);}            }

布局文件

XAML

<Window x:Class="GasAlarmTestTool.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:GasAlarmTestTool"mc:Ignorable="d"Title="燃气报警器接口工具" Height="600" Width="800"><Grid><TabControl><TabItem><TabItem.Header><StackPanel><Label>串口设置</Label></StackPanel></TabItem.Header><StackPanel Orientation="Horizontal"><GroupBox Header="串口" Width="200"><StackPanel><StackPanel Orientation="Horizontal"><Label Margin="3" Height="25" Width="50">端口号</Label><ComboBox x:Name="comboBoxCOM" Margin="3" Height="20" Width="130" DragDrop.Drop="comboBoxCOM_Drop"/></StackPanel><StackPanel Orientation="Horizontal"><Label Margin="3" Height="25" Width="50">波特率</Label><ComboBox x:Name="comboBoxBaudRate" Margin="3" Height="20" Width="130" SelectedIndex="0" IsEditable="True" ></ComboBox></StackPanel><StackPanel Orientation="Horizontal"><Label Margin="3" Height="25" Width="50">数据位</Label><ComboBox x:Name="comboBoxDataBit" Margin="3" Height="20" Width="130" SelectedIndex="3"><ComboBoxItem>5</ComboBoxItem><ComboBoxItem>6</ComboBoxItem><ComboBoxItem>7</ComboBoxItem><ComboBoxItem>8</ComboBoxItem></ComboBox></StackPanel><StackPanel Orientation="Horizontal"><Label Margin="3" Height="25" Width="50">停止位</Label><ComboBox x:Name="comboBoxStopBit" Margin="3" Height="20" Width="130" SelectedIndex="0"><ComboBoxItem>1位</ComboBoxItem><ComboBoxItem>1.5位</ComboBoxItem><ComboBoxItem>2位</ComboBoxItem></ComboBox></StackPanel><StackPanel Orientation="Horizontal"><Label Margin="3" Height="25" Width="50">校验位</Label><ComboBox x:Name="comboBoxSdd" Margin="3" Height="20" Width="130" SelectedIndex="0"><ComboBoxItem>无校验</ComboBoxItem><ComboBoxItem>奇校验</ComboBoxItem><ComboBoxItem>偶校验</ComboBoxItem><ComboBoxItem>1 校验</ComboBoxItem><ComboBoxItem>0 校验</ComboBoxItem></ComboBox></StackPanel><StackPanel Orientation="Horizontal"><Label Margin="3" Height="25" Width="50">流控位</Label><ComboBox x:Name="comboBoxlik" Margin="3" Height="20" Width="130" SelectedIndex="0" ><ComboBoxItem>无流控</ComboBoxItem><ComboBoxItem>RTS/CTS</ComboBoxItem><ComboBoxItem>XON/XOFF</ComboBoxItem></ComboBox></StackPanel><StackPanel Orientation="Horizontal" HorizontalAlignment="Center"><Button x:Name="btnOpenCloseCom" Margin="3" Width="80" Height="25" Click="btnOpenCloseCom_Click">打开串口</Button><Button x:Name="btnClearRecv" Margin="3" Width="80" Height="25" Click="btnClearRecv_Click">清空接收</Button></StackPanel></StackPanel></GroupBox><GroupBox Header="接收数据" MinWidth="590" MaxWidth="1000"><ScrollViewer><ScrollViewer.Content><TextBlock x:Name="textBlockRecv" MinWidth="300" MaxWidth="1000"></TextBlock></ScrollViewer.Content></ScrollViewer></GroupBox></StackPanel></TabItem><TabItem><TabItem.Header><StackPanel><Label>数据读取</Label></StackPanel></TabItem.Header><StackPanel Orientation="Horizontal"><StackPanel Orientation="Vertical"><GroupBox Header="记录总数"><StackPanel Orientation="Vertical"><Button x:Name="btnReadRecCount" Margin="3" Padding="5" Click="btnReadRecCount_Click">读取记录总数</Button><StackPanel Orientation="Horizontal"><Label>报警记录总数:</Label><TextBox x:Name="txtBoxWarningCount">0</TextBox></StackPanel><StackPanel Orientation="Horizontal"><Label>报警恢复记录总数:</Label><TextBox x:Name="txtBoxWarningRecoveryCount">0</TextBox></StackPanel><StackPanel Orientation="Horizontal"><Label>故障记录总数:</Label><TextBox x:Name="txtBoxFaultCount">0</TextBox></StackPanel><StackPanel Orientation="Horizontal"><Label>故障恢复记录总数:</Label><TextBox x:Name="txtBoxFaultRecoryCount">0</TextBox></StackPanel><StackPanel Orientation="Horizontal"><Label>掉电记录总数:</Label><TextBox x:Name="txtBoxPoweroffCount">0</TextBox></StackPanel><StackPanel Orientation="Horizontal"><Label>上电记录总数:</Label><TextBox x:Name="txtBoxPoweronCount">0</TextBox></StackPanel><StackPanel Orientation="Horizontal"><Label>传感器失效记录总数:</Label><TextBox x:Name="txtSensorInvalidCount">0</TextBox></StackPanel></StackPanel></GroupBox><GroupBox Header="日期时间"><StackPanel Orientation="Vertical"><Button x:Name="btnReadDateTime" Click="btnReadDateTime_Click">读取日期时间</Button><TextBox x:Name="txtBoxDateTime">0000-00-00 00:00</TextBox></StackPanel></GroupBox></StackPanel><StackPanel Orientation="Vertical"><GroupBox Header="读取指定记录"><StackPanel Orientation="Horizontal"><ComboBox x:Name="cmboxRecordType" Width="120" SelectedIndex="0"><ComboBoxItem>报警记录</ComboBoxItem><ComboBoxItem>报警恢复记录</ComboBoxItem><ComboBoxItem>故障记录</ComboBoxItem><ComboBoxItem>故障恢复记录</ComboBoxItem><ComboBoxItem>掉电记录</ComboBoxItem><ComboBoxItem>上电记录</ComboBoxItem><ComboBoxItem>传感器失效记录</ComboBoxItem></ComboBox><TextBox x:Name="txtBoxNumber" Width="50">1</TextBox><Button x:Name="btnReadRecord" Click="btnReadRecord_Click" ClickMode="Press">读取记录</Button><TextBox x:Name="txtBoxRecordInfo">0000/00/00  00:00</TextBox></StackPanel></GroupBox></StackPanel></StackPanel></TabItem></TabControl></Grid>
</Window>

代码文件

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace GasAlarmTestTool
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{private int warningCnt = 0;private int warningRecoveryCnt = 0;private int faultCnt = 0;private int faultRecoveryCnt = 0;private int poweroffCnt = 0;private int poweronCnt = 0;private int sensorInvalidCnt = 0;long recvTimems = 0;    // 用于计算串口接收完一帧数据int rxLen = 0;  // 串口接收到的数据长度byte[] rxBuff = new byte[128];  // 串口数据接收缓存private static Timer mTimer;    // 定时器,10ms执行一次SerialPort mSerialPort = new SerialPort(); private StringBuilder lineBuilder = new StringBuilder();    // 用于存放串口接收数据private List<string> baudrateList = new List<string> { "4800", "9600", "19200","38400","57600","115200","256000","1000000","2000000","3000000"};public MainWindow(){InitializeComponent();// 获取所有可用串口端口,并添加到comboBoxCOMstring[] ports = System.IO.Ports.SerialPort.GetPortNames();comboBoxCOM.ItemsSource = ports;comboBoxCOM.SelectedIndex = 0;  // 默认选择索引comboBoxBaudRate.ItemsSource = baudrateList;    // 波特率设置combobox数据源mTimer = new Timer(recvTimerCalback, null, 0, 10);  // 创建并启动定时器}/// <summary>/// 窗口关闭处理/// </summary>/// <param name="e"></param>protected override void OnClosing(System.ComponentModel.CancelEventArgs e){            if (MessageBox.Show("确定要退出吗?", "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes){// 用户选择“否”,取消关闭e.Cancel = true;}mSerialPort.Close();mTimer.Dispose();base.OnClosing(e);}private string RecordInfoString(byte[] buf){if (buf.Length < 11) {return "";}int index = buf[4];int year = buf[5] << 8 | buf[6];int month = buf[7];int day = buf[8];int hour = buf[9];int minute = buf[10];return  year.ToString() + "/" + month.ToString() + "/" + day.ToString() + "   " + hour.ToString() + ":" + minute.ToString();            }/// <summary>/// 串口接收处理定时器回调/// </summary>/// <param name="obj"></param>private void recvTimerCalback(object obj){//Console.WriteLine("timer callback!" + recvTimems);this.Dispatcher.Invoke(new Action(()=> {// UI线程分离,更新UI数据显示if (((Environment.TickCount - recvTimems) >= 20) && (rxLen > 0)){// 串口接收时间超过X ms认为一帧数据接收完成uint HEAD = rxBuff[0];uint C1 = rxBuff[1];uint C2 = rxBuff[2];uint L = rxBuff[3];uint CS = rxBuff[L + 4];uint END = rxBuff[L + 5];// 打印串口结束缓存数据uint _CS = 0;   // 计算接收数据校验和uint index = 0;UInt32 temp = 0;for (int i = 0; i < rxLen; i++){if (i < (rxLen - 2)){temp += rxBuff[i];}Console.WriteLine(rxBuff[i].ToString("X2"));}_CS = (uint)(temp % 0xFF);if ((0xAA == rxBuff[0]) && (0x55 == END)){// TODO: 接收到一帧完整数据Console.WriteLine("RS232 RECV ONE FRAME!" + CS.ToString("X2") + ", " + _CS.ToString("X2"));if (CS == _CS){// TODO: CHECKSUM8 校验和正确Console.WriteLine("CheckSum OK");if (0x00 == C2){if (0x00 == C1){// TODO: 查询各类记录总数warningCnt = rxBuff[4]; // 探测器报警记录总数warningRecoveryCnt = rxBuff[5]; // 探测器报警恢复记录总数faultCnt = rxBuff[6];   // 探测器故障记录总数faultRecoveryCnt = rxBuff[7]; // 探测器故障恢复记录总数poweroffCnt = rxBuff[8];    // 探测器掉电记录总数poweronCnt = rxBuff[9];     // 探测器上电记录总数sensorInvalidCnt = rxBuff[10];  // 传感器失效记录总数txtBoxWarningCount.Text = warningCnt.ToString();txtBoxWarningRecoveryCount.Text = warningRecoveryCnt.ToString();txtBoxFaultCount.Text = faultCnt.ToString();txtBoxFaultRecoryCount.Text = faultRecoveryCnt.ToString();txtBoxPoweroffCount.Text = poweroffCnt.ToString();  txtBoxPoweronCount.Text = poweronCnt.ToString();}}else if (0x01 == C2){// 报警记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x02 == C2){// 报警恢复记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x03 == C2){// 故障记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x04 == C2){// 故障恢复记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x05 == C2){// 掉电记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x06 == C2){// 上电记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x07 == C2){// 传感器失效记录txtBoxRecordInfo.Text = RecordInfoString(rxBuff);}else if (0x08 == C2){// TODO: 日期时间int year = rxBuff[4] << 8 | rxBuff[5];int month = rxBuff[6];int day = rxBuff[7];int hour = rxBuff[8];int minute = rxBuff[9];txtBoxDateTime.Text = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + "   "+hour.ToString() + ":"+minute.ToString();                                }}else{// TODO: CHECKSUM8 校验和有误Console.WriteLine("CheckSum ERR");}}Array.Clear(rxBuff, 0, rxBuff.Length);rxLen = 0;}}));                        }/// <summary>/// 串口数据接收函数/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e){SerialPort comPort = (SerialPort)sender;try{recvTimems = Environment.TickCount; // 更新串口数据接收时间//rxBuff[rxLen] = mSerialPort.ReadByte();int readCnt = mSerialPort.BytesToRead;Console.WriteLine("in readCnt:" + readCnt);mSerialPort.Read(rxBuff, rxLen, readCnt);rxLen += readCnt;Console.WriteLine("out rxLen:" + rxLen);#if falsebyte[] data = new byte[mSerialPort.BytesToRead];mSerialPort.Read(data, 0, data.Length);Console.WriteLine(data.Length);foreach (byte b in data){ Console.WriteLine(b.ToString("X2"));                    }
#endif}catch (Exception ce){MessageBox.Show(ce.Message);}            }private void btnOpenCloseCom_Click(object sender, RoutedEventArgs e){if (mSerialPort.IsOpen){mSerialPort.Close();btnOpenCloseCom.Content = "打开串口";Console.WriteLine("关闭串口成功");Debug.WriteLine("关闭串口成功");comboBoxBaudRate.IsEnabled = true;comboBoxCOM.IsEnabled = true;comboBoxDataBit.IsEnabled = true;comboBoxStopBit.IsEnabled = true;comboBoxSdd.IsEnabled = true;comboBoxlik.IsEnabled = true;}else{mSerialPort.PortName = comboBoxCOM.SelectedItem.ToString();mSerialPort.BaudRate = 4800; // 波特率mSerialPort.DataBits = 8;   // 数据位mSerialPort.StopBits = StopBits.One;    // 停止位mSerialPort.Parity = Parity.None;   // 校验位mSerialPort.Handshake = Handshake.None;//mSerialPort.ReadTimeout = 1500; // 读超时//mSerialPort.Encoding = Encoding.UTF8; // 编码方式//mSerialPort.RtsEnable = true;mSerialPort.DataReceived += SerialPort_DataReceived;Console.WriteLine("baudrate SelectedIndex:" + comboBoxBaudRate.SelectedIndex);Console.WriteLine("baudrate SelectedValue:" + comboBoxBaudRate.SelectedValue);Console.WriteLine("baudrate Text:" + comboBoxBaudRate.Text);if (comboBoxBaudRate.SelectedIndex < 0){mSerialPort.BaudRate = Convert.ToInt32(comboBoxBaudRate.Text);}else {switch (comboBoxBaudRate.SelectedValue){case "4800":mSerialPort.BaudRate = 4800;break;case "9600":mSerialPort.BaudRate = 9600;break;case "19200":mSerialPort.BaudRate = 19200;break;case "38400":mSerialPort.BaudRate = 38400;break;case "57600":mSerialPort.BaudRate = 57600;break;case "115200":mSerialPort.BaudRate = 115200;break;case "256000":mSerialPort.BaudRate = 256000;break;case "1000000":mSerialPort.BaudRate = 1000000;break;case "2000000":mSerialPort.BaudRate = 2000000;break;case "3000000":mSerialPort.BaudRate = 3000000;break;                       default:MessageBox.Show("波特率设置有误!");break;}}Console.WriteLine("端口:" + mSerialPort.PortName  + ",波特率:" + mSerialPort.BaudRate);// mSerialPort.Write("Hello world"); // 写字符串口// mSerialPort.Write(new byte[] { 0xA0, 0xB0, 0xC0}, 0, 3); // 写入3个字节数据//Debug.WriteLine("Hello world");//MessageBox.Show("端口名:" + mSerialPort.PortName);try{mSerialPort.Open();btnOpenCloseCom.Content = "关闭串口";Console.WriteLine("打开串口成功");Debug.WriteLine("打开串口成功");comboBoxBaudRate.IsEnabled = false;comboBoxCOM.IsEnabled = false;comboBoxDataBit.IsEnabled = false;comboBoxStopBit.IsEnabled = false;comboBoxSdd.IsEnabled = false;comboBoxlik.IsEnabled = false;}catch (Exception ex){MessageBox.Show(ex.Message);}}}private void btnClearRecv_Click(object sender, RoutedEventArgs e){lineBuilder.Clear();textBlockRecv.Text = lineBuilder.ToString();}private void comboBoxCOM_Drop(object sender, DragEventArgs e){string[] ports = System.IO.Ports.SerialPort.GetPortNames();comboBoxCOM.ItemsSource = ports;comboBoxCOM.SelectedIndex = 0;}private void comboBoxBaudRate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e){ComboBoxItem obj = (ComboBoxItem)sender;}private void btnReadRecCount_Click(object sender, RoutedEventArgs e){if (mSerialPort.IsOpen){mSerialPort.Write(new byte[] { 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x55 }, 0, 6); // 写入3个字节数据         }else{MessageBox.Show("请先打开串口!");}}private void btnReadDateTime_Click(object sender, RoutedEventArgs e){if (mSerialPort.IsOpen){mSerialPort.Write(new byte[] { 0xAA, 0x00, 0x08, 0x00, 0xB2, 0x55 }, 0, 6);}else{MessageBox.Show("请先打开串口!");}}private void btnReadRecord_Click(object sender, RoutedEventArgs e){            int index = Convert.ToInt32(txtBoxNumber.Text);if (index < 1 || index > 255){MessageBox.Show("记录索引:1~255!");}else {byte C1 = (byte)Convert.ToInt32(txtBoxNumber.Text);byte C2 = (byte)(cmboxRecordType.SelectedIndex);byte CS = (byte)((0xAA + C1 + C2)%0xFF);if (mSerialPort.IsOpen){byte[] Data = new byte[16];Data[0] = 0xAA;Data[1] = C1;   // 指定记录条数Data[2] = (byte)(C2 + 1);   // C2 记录分类从1开始Data[3] = 0x00;Data[4] = CS;Data[5] = 0x55;mSerialPort.Write(Data, 0, 6);}else{MessageBox.Show("请先打开串口!");}}}}
}

运行效果

在这里插入图片描述
在这里插入图片描述

源码下载

下载源码


http://www.ppmy.cn/embedded/111246.html

相关文章

【Hot100】LeetCode—322. 零钱兑换

目录 1- 思路动态规划 2- 实现⭐322. 零钱兑换——题解思路 3- ACM 实现 原题链接&#xff1a;322. 零钱兑换 1- 思路 动态规划 动规五部曲 1- 定义 dp 数组确定含义 dp[j] 代表凑到金钱为 j 的最少硬币个数 2- 递推公式 dp[j] Math.min(dp[j],dp[amount-]1) 3- 初始化 dp[…

数据库的操作:SQL运算符(算法/比较/逻辑/位)

常用运算符&#xff1a;算法运算符&#xff0c;比较运算符&#xff0c;逻辑运算符&#xff0c;位运算符 1.算法运算符 一般用于数值的运算 常见的算法运算符有&#xff1a;&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;div&#xff0c;%&#xff0c;mod select 11 …

GD32E230 RTC报警中断功能使用

GD32E230 RTC报警中断使用 GD32E230 RTC时钟源有3个&#xff0c;一个是内部RC振动器产生的40KHz作为时钟源&#xff0c;或者是有外部32768Hz晶振.,或者外部高速时钟晶振分频作为时钟源。 &#x1f516;个人认为最难理解难点的就是有关RTC时钟异步预分频和同步预分频的计算。在对…

物联网——模拟与数字转换器(ADC)

ADC&#xff08;常用于信号发生器&#xff0c;音频解码器&#xff09; 逐次逼近型ADC 利用逐次逼近寄存器SAR&#xff0c;二分法逼近未知电压&#xff0c;直到外部输入电压与输出电压保持一致&#xff1a;例如0~225V每次去中间值作为判断电压&#xff0c;逐次二分 stm32的AD…

MySQL:运维管理-主从复制

目录 一、主从复制的概述二、主从复制的工作原理三、搭建主从复制的结构3.1 环境准备3.2 搭建配置&#xff08;主库配置&#xff09;3.3 搭建配置&#xff08;从库配置&#xff09;3.4 测试 一、主从复制的概述 主从复制是指将主数据库中的DDL和DML操作的二进制文件保存到本地&…

【网络安全 | 渗透工具-目录FUZZ】ffuf安装使用详细教程

原创文章,不得转载。 文章目录 ffuf安装使用Wordlist工作模式配置请求的方式匹配和过滤选项显示和保存输出结果ffuf ffuf(Fuzz Faster U Fool) 是一个开源的命令行工具,用于进行网络应用程序的目录和文件枚举,特别是在渗透测试和安全研究中。它能够通过对目标应用程序发起大…

Nginx之日志切割,正反代理,HTTPS配置

1 nginx日志切割 1.1 日志配置 在./configure --prefixpath指定的path中切换进去&#xff0c;找到log文件夹&#xff0c;进去后找到都是对应的日志文件 其中的nginx.pid是当前nginx的进程号&#xff0c;当使用ps -ef | grep nginx获得就是这个nginx.pid的值 在nginx.conf中…

GPT-4与ChatGPT:人工智能对话的新时代【含国内可用gpt】

随着人工智能&#xff08;AI&#xff09;技术的不断突破&#xff0c;人与机器的交互方式正发生深刻的变革。在这股技术浪潮中&#xff0c;GPT-4和基于它的ChatGPT成为了令人瞩目的焦点&#xff0c;推动了对话式AI的快速发展。通过这些技术&#xff0c;我们不仅看到了AI在语言理…

Vue 67 vuex 四个map方法的使用

mapState方法&#xff1a;用于帮助我们映射state中的数据为计算属性 computed: {//借助mapState生成计算属性&#xff1a;sum、school、subject&#xff08;对象写法&#xff09;...mapState({sum:sum,school:school,subject:subject}),//借助mapState生成计算属性&#xff1a;…

flink中startNewChain() 的详解

在 Apache Flink 中&#xff0c;startNewChain() 是一个与算子链&#xff08;operator chaining&#xff09;相关的方法。与 disableChaining() 类似&#xff0c;它允许开发者控制算子链的创建方式&#xff0c;但 startNewChain() 的作用是从当前算子开始创建一个新的算子链&am…

Java笔试面试题AI答之单元测试JUnit(4)

文章目录 19. 简述JUnit org.junit.TestSuite类的作用 &#xff1f;1. 组织测试类2. 简化测试执行3. 灵活配置测试环境4. 嵌套测试套件注意事项 20. 在JUnit中Test注释的作用和用法 &#xff1f;作用用法 21. 简述Junit 基础注解&#xff08;BeforeClass、Before、Test、After、…

NAS黑群晖7.21折腾笔记

黑群晖引导制作 https://post.smzdm.com/p/a96d62xe/ 黑群晖基本使用教程 https://www.bilibili.com/video/BV1A3411f7WK/?spm_id_from333.337.search-card.all.click 重点&#xff1a; 1&#xff0c;存储管理器 --创建存储池 RAID类型选择&#xff1a; 2&#xff0c…

【软考】设计模式之抽象工厂模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无须指定它们具体的类。2.抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式。3.抽象工厂…

浅谈工业配电系统中漏电产生的成因以及应对方案

摘要 在现代工业厂房的配电系统中&#xff0c;绝缘检测仪作为保障电气设备安全运行的重要工具&#xff0c;发挥着关键作用。本文探讨了绝缘检测仪在工业厂房配电系统中的应用背景、工作原理、具体应用以及其对设备维护与安全管理的影响。通过分析绝缘检测仪在实际操作中的优势…

VScode相关问题与解决

1.写c文件时找不到头文件stdio.h 在linux下我们gcc命令来编译c文件时&#xff0c;会遇到找不到头文件的问题 解决方法&#xff1a;我们每写完一个文件记得保存一下文件即可&#xff0c;这样就解决了找不到头文件的问题&#xff01; 参考链接&#xff1a; /usr/bin/ld: /us…

备忘录模式memento

学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/memento 允许生成对象状态的快照并在以后将其还原。备忘录不会影响它所处理的对象的内部结构&#xff0c; 也不会影响快照中保存的数据。

“阡陌云旅”黄河九省文化旅游平台

“阡陌云旅”黄河九省文化旅游平台 GitHub地址&#xff1a;https://github.com/guoJiaQi-123/Yellow-River-Cloud-Journey 项目背景 “阡陌云旅”黄河九省文化旅游平台 “阡陌云旅” 黄河九省文化旅游平台是一个专注于黄河流域九省文化旅游资源整合与推广的项目。 黄河是中…

径向基函数神经网络RBFNN案例实操

简介 (来自ChatGPT的介绍,如有更正建议请指出) 径向基函数神经网络(Radial Basis Function Neural Network, RBFNN)是一种特殊的前馈神经网络,其结构和特点与其他常见的神经网络有所不同,主要表现在以下几个方面: 网络结构三层结构:RBF神经网络通常由三层组成:输入层…

C语言程序设计-练习篇

不知道结果仍义无反顾地才是勇士。 三&#xff0c;打印整数二进制的奇数位和偶数位 题目内容&#xff1a; 获取一个整数二进制序列中所有的奇数位和偶数位&#xff0c;分别打印出二进制序列 #include <stdio.h>//打印整数二进制的奇数位和偶数位 int main() {int i 0…

【Python机器学习】长短期记忆网络(LSTM)

目录 随时间反向传播 实践 模型的使用 脏数据 “未知”词条的处理 字符级建模&#xff08;英文&#xff09; 生成聊天文章 进一步生成文本 文本生成的问题&#xff1a;内容不受控 其他记忆机制 更深的网络 尽管在序列数据中&#xff0c;循环神经网络为对各种语言关系…