这一篇文章是我前一篇文章的续集,主要是为了弥补 CCS无法实时捕捉数据至上位机的缺陷(可能CCS有,但是我却没找到,如果有读者知道具体答案,请留言告诉我。)。当然串口传输来的数据也有不足的地方,就是这些数据只能让我们感性的观看,如果想做数据分析,如FFT等,可能数据的采样精度就不够了。所以这也是一个不足的地方,希望日后能有解决的办法。下面开始正文部分吧!

废话不多说,先来张效果图:

图1是DSP_demo板加Lcd12864的显示。显示的比较粗糙,026.56就是26.56℃,一些细节没有做好,主要是功能的实现。


图2是使用Matlab2017b的AppDesigner制作的串口通信上位机软件,具体功能有:发送(TX)、接收(RX)、实时绘图、数据实时保存等。其中COM口和波特率需要设置,其他的如:数据位、校验位、停止位等等,已经在代码中默认设置了,因为只是这个小设计的定制版本,也没有高兴将所有功能都全部放置在界面上。

图像中,出现了34℃,那是我用手拿住了 Ds18b20。目前是6月底,江苏黄梅天,今天室温就是27℃左右。


图3是采集到的数据。只是展示了部分,刚开机的时候是没有打开文本存储按钮的,因此第一个数据与图2中接收数据框中前几个数据不是对应的。


图1                                                         图2                                                                    图3


效果展示完了,那么接下来就是代码部分:

/** 功能:1.DS18B20进行温度采集,并使用12864进行显示*       2.将采集到的温度 通过SCIA传输,因为SCIB的9口被12864占用,所以不能用SCIB*       3.SCIA使用CpuTimer0中断,1s传输一次温度数据给PC,未使用FIFO中断* 波特率:9600  8位数据位,1位停止位,无校验位*/#include "DSP2833x_Project.h"
#include "math.h"#include "lcd12864.h"
#include "ds18b20_para.h"#define uchar  unsigned charvoid init_port(void);
uchar Init_DS18B20();
uchar ReadOneChar(void);
void WriteOneChar(uchar dat);
float ReadTemperature();
void lcd_init(void);
void lcd_write_cmd(uchar cmd);
void lcd_write_dat(uchar dat);
void LCD12864SetAddress_f( uchar x, uchar y );   //地址转换
void show(uchar x, uchar y, uchar * data);  void scia_init(void);
void GPIO_init();
interrupt void Timer0_ISR(void);uchar table[7];int main(void)
{float tt;int tt1;InitSysCtrl();init_port();   //ds18b20 & 12864 端口初始化DINT;InitPieCtrl();   //初始化中断控制IER = 0x0000;IFR = 0x0000;InitPieVectTable();//初始化中断矢量表GPIO_init();  //配置端口为SCIEALLOW;        // This is needed to write to EALLOW protected registersPieVectTable.TINT0 = &Timer0_ISR;//将定时器0中断服务函数入口放入中断向量表EDIS;   // This is needed to disable write to EALLOW protected registersInitCpuTimers();ConfigCpuTimer(&CpuTimer0, 150, 1000000);  //定时器0定时时间为 1sscia_init();  //SCIA端口初始化lcd_init();PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE blockPieCtrlRegs.PIEIER1.bit.INTx7=1;     // PIE Group 1, INT7IER = 0x001;EINT;CpuTimer0Regs.TCR.bit.TSS = 0;  // 启动定时器0while (1){tt=ReadTemperature();tt1=tt*100+0.5;//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就//算加上0.5,还是在小数点后面。table[0]=tt1/10000+0x30;  //百位table[1]=tt1%10000/1000+0x30;//十位table[2]=tt1%1000/100+0x30;//个位table[3]='.';table[4]=tt1%100/10+0x30;//十分位;table[5]=tt1%10+0x30;//百分位;table[6]='\0';  //用来中止一组显示数据show(0,0,table);}}//----------------------
//--- 12864 及  DS18B20 的初始化
//----------------------
void init_port(void)
{EALLOW;GpioCtrlRegs.GPBPUD.bit.GPIO40 = 0;    // 使能GPIO10 引脚内部上拉GpioCtrlRegs.GPBMUX1.bit.GPIO40 =0;   // 配置GPIO10为通用I/O口GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 0;    // GPIO40与系统时钟SYSCLKOUT 同步//lcd12864 useGpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;    // 使能GPIO0 引脚内部上拉GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;   // 禁止GPIO1 引脚内部上拉GpioCtrlRegs.GPAQSEL1.all = 0x0000;    // GPIO0-GPIO15与系统时钟SYSCLKOUT 同步GpioCtrlRegs.GPADIR.all = 0x003FF;// 配置GPIO0-GPIO9为输出引脚//输出数据LCD_RW和LCD_EN清零GpioDataRegs.GPADAT.bit.GPIO0 = 1;GpioDataRegs.GPADAT.bit.GPIO1 = 0;EDIS;
}//----------------------
//---SCI的初始化
//----------------------
void GPIO_init()
{EALLOW;GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0;     // Enable pull-up for GPIO35  (SCITXDA)GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 1;    // GPIO35 for SCITXDA operationGpioCtrlRegs.GPBPUD.bit.GPIO36 = 0;    // Enable pull-up for GPIO36 (SCIRXDA)GpioCtrlRegs.GPBQSEL1.bit.GPIO36 = 3;  // Asynch input GPIO36 (SCIRXDA)GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 1;   // GPIO36 for SCIRXDA operationEDIS;
}void scia_init(void)
{SciaRegs.SCICCR.all =0x0007;    // 1 stop bit,// No parity,8 char bits,// async mode, idle-line protocolSciaRegs.SCICTL1.all =0x0003;   // enable TX, RX, internal SCICLK,// Disable RX ERR, SLEEP, TXWAKESciaRegs.SCIHBAUD    =0x0001;SciaRegs.SCILBAUD    =0x00E7;   //构成 0x01e7=487 波特率计算为   37.5M/[(487+1)*8]=9605 近似等于9600SciaRegs.SCICTL1.bit.SWRESET=1;//Relinquish SCI from Reset}interrupt void Timer0_ISR(void)
{int i=0;while(table[i] != '\0')            //不断发送,直到1组温度数据发送完毕{SciaRegs.SCITXBUF=table[i];  //发送数据DELAY_US(1000);              //若不加,会出现数据丢失i++;}SciaRegs.SCITXBUF='\n';           //每接收一组数据后,换行PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//PIE组1应答
}

以上是DSP上的代码。接下来是上位机代码,供大家学习。这其中的一部分代码,我也是从网上寻找来的,因此在此要感谢那位哥们开放的串口软件。Appdesigner比较新,界面也不错,如果大家喜欢,可以自己做出修改,但是我希望大家在我这个版本基础上修改后,能在留言处开源自己的内容,让大家一起进步。首先将app的链接给出:


链接:https://pan.baidu.com/s/1NEqKQJX87mv86V9ENZ2kkA 
提取码:x3y0

或  https://download.csdn.net/download/wx_simba/11259531


以下是代码,有Matlab的朋友可以直接用 Appdesigner打开查看。注意,至少需要 2016a版本才具有Appdesigner功能。

***这是回头打的字,插入代码居然没有Matlab的m语言格式。。。还有下面代码看着多,其实估计80%都是系统生成的,我们是无法修改的,实现功能的代码其实不多。

classdef app2 < matlab.apps.AppBase% Properties that correspond to app componentsproperties (Access = public)UIFigure             matlab.ui.FigurepbOpenSerial         matlab.ui.control.StateButtonRXLabel              matlab.ui.control.LabelTXLabel              matlab.ui.control.LabelLabel_RX             matlab.ui.control.LabelLabel_TX             matlab.ui.control.LabelReceiveView          matlab.ui.control.TextAreaButton_Send          matlab.ui.control.ButtontransmitView         matlab.ui.control.TextAreaButton_Clear         matlab.ui.control.ButtonDropDownLabel        matlab.ui.control.LabelppCOM                matlab.ui.control.DropDownLabel                matlab.ui.control.LabelLabel_2              matlab.ui.control.LabelLamp                 matlab.ui.control.LampLabel_3              matlab.ui.control.LabelppCOM_2              matlab.ui.control.DropDownPanel                matlab.ui.container.PanelLabel_5              matlab.ui.control.LabeltxtStoreSwich        matlab.ui.control.SwitchLabel_6              matlab.ui.control.LabeltxtStoreFlag         matlab.ui.control.LampUIAxes               matlab.ui.control.UIAxesUartsEditFieldLabel  matlab.ui.control.LabelUartsEditField       matlab.ui.control.NumericEditFieldendproperties (Access = public)COM;    % 端口号Baud_Rate; %波特率s  ;    %端口设置句柄RX_num; %接收统计TX_num; %发送统计RX_once;%一次接收的数据RX_Date;%接收的所有数据is_open;%是否打开串口标志位Flag_i %绘图横坐标的点endmethods (Access = public)function  EveBytesAvailableFcn(app, src, event)n = src.BytesAvailable;%获取接收到的字符个数if n>0%n>0才继续执行,因为0也会触发中断app.RX_num=app.RX_num+n;app.Label_RX.Text=num2str(app.RX_num);%将数字转化为字符串输出app.RX_once=fread(src,n,'uchar');%读取函数,读取后矩阵为一列app.RX_Date =strcat(app.RX_Date, app.RX_once');%字符串拼接,需要转置化为一行app.ReceiveView.Value= app.RX_Date;%textarea的设置格式为cell,或单行字符串app.Flag_i=app.Flag_i+1;t=app.Flag_i*app.UartsEditField.Value;y=str2double(char(app.RX_once'));    plot(app.UIAxes,t,y,'marker','+','linewidth',5,'linestyle','--');hold(app.UIAxes,'on');if strcmp(app.txtStoreSwich.Value,'On')app.txtStoreFlag.Color=[0 1 0];name_ref=['wx',datestr(now,29),'.txt']; % name_ref=['wx',datestr(now,29),'.xls'];fid = fopen(name_ref,'a'); %fid = fopen('c.xls','a');fprintf(fid,'%s\r\n',app.RX_once');  %需要转置,进行换行处理,txt换行 要\r\n..xls只\n就可以换行fclose(fid);elseapp.txtStoreFlag.Color=[0 0 0];endendendendmethods (Access = private)% Code that executes after component creationfunction startupFcn(app)app.RX_num=0;app.TX_num=0;app.is_open=0;app.Flag_i=0;scoms = instrfind;%获取占用的串口号if scoms ~= 0%如果存在则关闭,否则不能打开stopasync(scoms);fclose(scoms);delete(scoms);endend% Button pushed function: Button_Sendfunction Button_SendPushed(app, event)val=app.transmitView.Value;if length(val{1})>0%textarea控件是cell格式,获取需要用{1}app.TX_num=app.TX_num+length(val{1});app.Label_TX.Text=num2str(app.TX_num);fwrite(app.s, char(val), 'uint8', 'async');%需要将val转化为charendend% Value changed function: pbOpenSerialfunction pbOpenSerialValueChanged2(app, event)app.COM=get(app.ppCOM,'Value');app.Baud_Rate=get(app.ppCOM_2,'Value');if strcmp(get(app.pbOpenSerial,'Text'),'打开串口')tryapp.s=serial(app.COM);app.s.BaudRate=str2double(app.Baud_Rate);%设置波特率,str2double 很重要app.s.DataBits=8;%设置数据长度app.s.StopBits=1;%设置停止位长度app.s.InputBufferSize=1024000;%设置输入缓冲区大小为1Mapp.s.BytesAvailableFcnMode='byte';  %串口事件回调设置%  app.s.Terminator='CR/LF';app.s.BytesAvailableFcnCount=1; %输入缓冲区存在10个字节触发回调函数app.s.BytesAvailableFcn={@app.EveBytesAvailableFcn};%回调函数的指定fopen(app.s);%打开串口app.is_open=1;app.pbOpenSerial.Text='关闭串口';app.Lamp.Color=[0 1 0];catch errmsgbox('打开失败');endelsetryfclose(app.s);app.pbOpenSerial.Text='打开串口';app.Lamp.Color=[0.15 0.15 0.15];catch errmsgbox('关闭失败');enddelete(app.s);app.is_open=0;endend% Close request function: UIFigurefunction UIFigureCloseRequest(app, event)delete(app)end% Button pushed function: Button_Clearfunction Button_ClearPushed(app, event)app.RX_Date ='';app.ReceiveView.Value= app.RX_Date;app.TX_num=0;app.RX_num=0;app.Label_TX.Text=num2str(app.TX_num);app.Label_RX.Text=num2str(app.RX_num);cla(app.UIAxes,'reset');end% Value changed function: txtStoreSwichfunction txtStoreSwichValueChanged(app, event)value = app.txtStoreSwich.Value;if strcmp(value,'On')app.txtStoreFlag.Color=[0 1 0];elseapp.txtStoreFlag.Color=[0 0 0];endendend% App initialization and constructionmethods (Access = private)% Create UIFigure and componentsfunction createComponents(app)% Create UIFigureapp.UIFigure = uifigure;app.UIFigure.Position = [500 300 895 521];app.UIFigure.Name = 'UI Figure';app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @UIFigureCloseRequest, true);% Create pbOpenSerialapp.pbOpenSerial = uibutton(app.UIFigure, 'state');app.pbOpenSerial.ValueChangedFcn = createCallbackFcn(app, @pbOpenSerialValueChanged2, true);app.pbOpenSerial.Text = '打开串口';app.pbOpenSerial.FontSize = 16;app.pbOpenSerial.FontWeight = 'bold';app.pbOpenSerial.Position = [740 311 81 27];% Create RXLabelapp.RXLabel = uilabel(app.UIFigure);app.RXLabel.Position = [42 60 25 15];app.RXLabel.Text = 'RX:';% Create TXLabelapp.TXLabel = uilabel(app.UIFigure);app.TXLabel.Position = [102 60 25 15];app.TXLabel.Text = 'TX:';% Create Label_RXapp.Label_RX = uilabel(app.UIFigure);app.Label_RX.Position = [66 60 37 15];app.Label_RX.Text = '0';% Create Label_TXapp.Label_TX = uilabel(app.UIFigure);app.Label_TX.Position = [126 60 82 15];app.Label_TX.Text = '0';% Create ReceiveViewapp.ReceiveView = uitextarea(app.UIFigure);app.ReceiveView.Position = [25 192 161 270];% Create Button_Sendapp.Button_Send = uibutton(app.UIFigure, 'push');app.Button_Send.ButtonPushedFcn = createCallbackFcn(app, @Button_SendPushed, true);app.Button_Send.FontSize = 16;app.Button_Send.FontWeight = 'bold';app.Button_Send.Position = [716 96 100 27];app.Button_Send.Text = '发送';% Create transmitViewapp.transmitView = uitextarea(app.UIFigure);app.transmitView.Position = [27 88 159 60];% Create Button_Clearapp.Button_Clear = uibutton(app.UIFigure, 'push');app.Button_Clear.ButtonPushedFcn = createCallbackFcn(app, @Button_ClearPushed, true);app.Button_Clear.FontSize = 16;app.Button_Clear.FontWeight = 'bold';app.Button_Clear.Position = [716 49 100 27];app.Button_Clear.Text = '清空';% Create DropDownLabelapp.DropDownLabel = uilabel(app.UIFigure);app.DropDownLabel.HorizontalAlignment = 'right';app.DropDownLabel.FontName = 'Calibri';app.DropDownLabel.FontSize = 18;app.DropDownLabel.Position = [684 422 41 24];app.DropDownLabel.Text = '串口';% Create ppCOMapp.ppCOM = uidropdown(app.UIFigure);app.ppCOM.Items = {'COM1', 'COM2', 'COM3', 'COM4'};app.ppCOM.FontName = 'Calibri';app.ppCOM.FontSize = 18;app.ppCOM.Position = [740 424 76 25];app.ppCOM.Value = 'COM1';% Create Labelapp.Label = uilabel(app.UIFigure);app.Label.FontSize = 18;app.Label.FontWeight = 'bold';app.Label.Position = [39 475 42 23];app.Label.Text = '接收';% Create Label_2app.Label_2 = uilabel(app.UIFigure);app.Label_2.FontSize = 18;app.Label_2.FontWeight = 'bold';app.Label_2.Position = [39 151 42 23];app.Label_2.Text = '发送';% Create Lampapp.Lamp = uilamp(app.UIFigure);app.Lamp.Position = [695 317 20 20];app.Lamp.Color = [0.149 0.149 0.149];% Create Label_3app.Label_3 = uilabel(app.UIFigure);app.Label_3.HorizontalAlignment = 'right';app.Label_3.FontName = 'Calibri';app.Label_3.FontSize = 18;app.Label_3.Position = [682 373 59 24];app.Label_3.Text = '波特率';% Create ppCOM_2app.ppCOM_2 = uidropdown(app.UIFigure);app.ppCOM_2.Items = {'300', '600', '1200', '2400', '4800', '9600', '19200', '38400', '115200'};app.ppCOM_2.FontName = 'Calibri';app.ppCOM_2.FontSize = 18;app.ppCOM_2.Position = [756 375 60 25];app.ppCOM_2.Value = '9600';% Create Panelapp.Panel = uipanel(app.UIFigure);app.Panel.Position = [655 173 231 87];% Create Label_5app.Label_5 = uilabel(app.Panel);app.Label_5.HorizontalAlignment = 'center';app.Label_5.Position = [136 24 77 15];app.Label_5.Text = '文本存储按钮';% Create txtStoreSwichapp.txtStoreSwich = uiswitch(app.Panel, 'slider');app.txtStoreSwich.ValueChangedFcn = createCallbackFcn(app, @txtStoreSwichValueChanged, true);app.txtStoreSwich.Position = [151 54 45 20];% Create Label_6app.Label_6 = uilabel(app.Panel);app.Label_6.HorizontalAlignment = 'right';app.Label_6.Position = [26 24 77 15];app.Label_6.Text = '文本存储指示';% Create txtStoreFlagapp.txtStoreFlag = uilamp(app.Panel);app.txtStoreFlag.Position = [52 45 29 29];app.txtStoreFlag.Color = [0 0 0];% Create UIAxesapp.UIAxes = uiaxes(app.UIFigure);title(app.UIAxes, 'Figure')xlabel(app.UIAxes, 'time')ylabel(app.UIAxes, 'Y')app.UIAxes.LineStyleOrder = {'- '};app.UIAxes.NextPlot = 'add';app.UIAxes.Position = [197 46 445 438];% Create UartsEditFieldLabelapp.UartsEditFieldLabel = uilabel(app.UIFigure);app.UartsEditFieldLabel.HorizontalAlignment = 'right';app.UartsEditFieldLabel.Position = [262 18 121 15];app.UartsEditFieldLabel.Text = 'Uart发送数据的周期/s';% Create UartsEditFieldapp.UartsEditField = uieditfield(app.UIFigure, 'numeric');app.UartsEditField.Limits = [0 Inf];app.UartsEditField.Position = [398 14 49 22];app.UartsEditField.Value = 1;endendmethods (Access = public)% Construct appfunction app = app2% Create and configure componentscreateComponents(app)% Register the app with App DesignerregisterApp(app, app.UIFigure)% Execute the startup functionrunStartupFcn(app, @startupFcn)if nargout == 0clear appendend% Code that executes before app deletionfunction delete(app)% Delete UIFigure when app is deleteddelete(app.UIFigure)endend
end

DSP28335驱动Lcd12864显示Ds18b20采集到的温度,并通过Sci方式传输至PC,使用Matlab制作上位机软件进行数据保存与显示相关推荐

  1. mfc上位机网络接收图片并显示_工控机上位机软件的开发历程

    微信号 :thinger_swj微博:@新阁程序园扫码关注 上位机软件的主要功能是采集各仪器的数据,然后存储起来,并传送到环保局平台. 刚开始使用的是组态软件(用以显示流程图),然后再开发了报表软件. ...

  2. 【USB网络摄像头】基于mjpeg-streamer的视频采集与播放【QT上位机软件】

    前言 最近一直在尝试制作一个,网络摄像头,先后分别尝试了使用QT包装的UDP类TCP类,和LINUX中的socket编程等方式,但是非常遗憾,都没有取得非常好的播放效果.以为只要一帧一帧的传输视频数据 ...

  3. 串口数据波形显示_【专题教程第6期】SEGGER的J-Scope波形上位机软件,RTT模式波形上传可飙到500KB/S...

    [专题教程第6期]SEGGER的J-Scope波形上位机软件,RTT模式波形上传速度可狂飙到500KB/S左右 说明: 1.在实际项目中,很多时候,我们需要将传感器或者ADC的数值以波形的形式显示.通 ...

  4. LED显示行业之上位机软件编程篇:

    本人非上位机专业编程人士,没有参与编程,所以,准确性不足. 这里描述一下:上位机涉及的整体构架. 这里仅仅是简单的描述了接收卡里面的基本框架. 里面的命名和逻辑连接.我都觉得有点乱.调理不够.这里呢? ...

  5. 【QT上位机设计——串口收发和波形显示】

    一.简介 最近粗略地学习了一下上位机的编程,大致了解了底层硬件与上位机之间的串口通信逻辑,TCP通信和UDP通信暂时还未学习. 本次把学习思路分享一下,主要学习视频是b站上北京迅为的QT教学视频,我的 ...

  6. 通过串口打印DS18B20采集到的温度

    我这里是在LCD屏和串口中都要进行打印温度的 main.c usart.c 首先要进行端口设置,时钟使能 之后是串口中断函数 接下来看DS18B20.c 一下附上DS18B20.c的源码. //¸´Î ...

  7. LED显示行业之上位机软件使用篇

    灰度等级在全彩屏这里没有现象.输出方式是针对不同的驱动的,错了就黑屏.低辉效果,显示正常. 毛华望   微信15889765314 这里的扫描方式,几扫,几行没问题.是Z型扫描还是--向扫描,要看驱动 ...

  8. MATLAB数字图像处理(一)——图像打开、保存与显示

    文章目录 准备工作 读入与显示图像 分离RGB图像 添加噪声 准备工作 本篇博客所用图像都保存在Matlab安装目录下的\toolbox\images\imdemos子目录中.我们在当前matlab新 ...

  9. 试试用pyqt做一个上位机软件,但愿不会烂尾(七):费了九牛二虎之力的进度条显示

    pyqt的进度条显示只能接受整数输入,不能直接显示小数,搜索了很多文章,试验了很多种办法都没能实现小数显示.最终采用了折中的办法,重新定义了进度条的text()函数.然后将输入的整数除以10的倍数,传 ...

最新文章

  1. jdk是什么?jdk1.8安装配置方法
  2. JSP学习——语法(二)
  3. 静电对于机电设备的影响
  4. 动态修改数据窗口的数据源
  5. HBase cell
  6. [POJ2342]Anniversary party(树dp)
  7. 编写react组件_s! 这就是为什么ReasonReact是编写React的最佳方法的原因
  8. Datadog Agent是啥?它消耗什么资源?
  9. 效率 用div做表格和tr_表格也能用Word做?别不信,利用这些小技巧分分钟做出完美表格...
  10. Azure Active Directory中的特权身份管理如何运作?
  11. 【广工考试笔记】计算机系统结构考试速成笔记
  12. Excel图表1——双坐标图(双柱图)
  13. markdown如何设置图片大小_Markdown 调整图片位置与大小
  14. http://baiy.cn/doc/cpp/index.htm#代码风格与版式_函数
  15. 最新Java面试题整理!java字符大写转小写
  16. access行列转换。
  17. 原生js删除html,javascript删除一个html元素节点的方法
  18. Android之原始的QQ好友分组实现
  19. RISC-V E300 SOC架构介绍——1.总体介绍
  20. UE4 Sequence在蓝图中播放和结束

热门文章

  1. 保安休息排序编程C语言,c语言课程设计保安值班安排系统
  2. HeaderElements must be namespace qualified
  3. 3年前离职,写下“世界那么大,我想去看看”的女教师,现在怎么样了?
  4. 海思3531DV200 --mpp学习
  5. 群晖NAS写入110MB/s读取2.1MB/s解决方法
  6. 千年虎丘:用文物数字化的方式定格岁月
  7. JAVA设计模式之单例模式详细分析(全)
  8. 【满分】【华为OD机试真题2023 JS】猜字谜
  9. vs2022 编译libmodbus源码
  10. 惊恐测试人员——Jmeter接口测试之TCP最大连接数