今天这个跟踪函数比之前的捕获函数更有难度,我看了整整两天,才弄明白了大部分程序的含义,以下是学习记录(程序中涉及的次重点函数将在后文展示,详见目录)。

目录

Tracking.m跟踪函数

① 初始化结果的结构体

② 初始化追踪函数的变量

③ 处理被捕获通道的信号

④ 启动GUI显示处理进度条

⑤ 将数据每M个采样点分为一个“codePhaseStep”的小块(block)

⑥ 提前建立所有码相位跟踪需要使用的数据

⑦ 将中频信号混频后到基带

⑧ 产生6组积分值I/Q各三组

⑨ 计算载波环路的输入信号与复制信号的相位差异,并生成NCO(数控振荡器)命令

⑩ 码环鉴别器

⑪ 记录最终的结果值

plotTracking.m


Tracking.m跟踪函数

捕获仅能提供对频率和码相位参数的粗略估计。跟踪的主要目的是使这些估计值精确化,并保持跟踪,然后从跟踪到的卫星信号中解调出导航数据(同时提供伪距估计)。

该函数跟踪分配到每一通道中的 GPS信号,此函数需要如下参数:从前端获得的一段数据,结构变量Channel,正弦函数,余弦函数和C/A码表。此函数处理采样数据并返回两个结构变量:跟踪结果TeackResuls和更新的结构变量Channel

function [trackResults, channel]= tracking(fid, channel, settings)

Channel结构变量用来传递每个通道的初始信息并存储当前通道的信息,其另外一个目的是使跟踪具有连贯性。用这种方法,处理两个或者更多的数据段可以连续进行。该结构包含当前(处理上1ms数据)的载波频率、码相位、跟踪卫星号、环路滤波器的临时参数和本地信号发生器的信息。

Settings结构中的载波跟踪参数包括:

(1) PLL _dampingRatio :阻尼比。

(2) PLL _noiseBandwidth PLL:噪声带宽。

Sttings结构中的码跟踪的参数包括:

(1) DLL CACorelatorSpacing:超前和滞后相关器的间距,单位是码片。

(2) DLL _damplingRatio DLL:阻尼比。

(3) DLL_ noiseBandwidth DLL:噪声带宽

trackResults结构是跟踪函数的主要输出,包含所有通道每1ms的跟踪结果:信号属性信息(载波频率和码相位)和6个相关器及环路鉴别器的输出。

跟踪结果将作为雨数postNavigation的输人,Plotracking用来绘制每一通道的结果,其余信息用于绘制跟踪结果并分析接收机性能。


下图是一种典型的接收机跟踪环路原理图,本程序主要的流程均依据此图进行。其中该如包含了一个典型的载波环(相位锁定环路)和一个典型的码环。

首先整理一下该程序分为11大块:

① Initialize result structure 初始化结果结构体

② Initialize tracking variables 初始化追踪函数的变量

③ Start processing channels 处理被捕获通道的信号

④ GUI update 启动GUI显示处理进度条

⑤ Read next block of data 将数据每M个采样点分为一个“codePhaseStep”个小块(block)

⑥ Set up all the code phase tracking information 提前建立所有码相位跟踪需要使用的数据

⑦ Generate the carrier frequency to mix the signal to baseband 通过载频将中频信号混频后到基带

⑧ Generate the six standard accumulated values  产生6组积分值I/Q各三组

⑨ Find PLL error and update carrier NCO 计算载波环路的输入信号与复制信号的相位差异,并生成NCO(数控振荡器)命令

⑩ Find DLL error and update code NCO 码环鉴别器

⑪ Record various measures to show in postprocessing 记录最终的结果值

通过对程序的分块,也可以大致了解该程序的思路,由于程序过长,因此将对程序分11块分别解读:


① Initialize result structure 初始化结果的结构体

在该段代码中,初始化了下列参数:

trackResults.status    信道状态

trackResults.absoluteSample    (The absolute sample in the record of the C/A code start)暂未理解,待后续补充

trackResults.codeFreq    C/A码的频率

trackResults.carrFreq    追踪载波的频率

trackResults.I_P 即时通道实部信号

trackResults.I_E  超前通道实部信号

trackResults.I_L  滞后通道实部信号

trackResults.Q_E  超前通道虚部信号

trackResults.Q_P  即时通道虚部信号

trackResults.Q_L  滞后通道虚部信号

trackResults.dllDiscr   码输入信号与复制信号的相位差异

trackResults.dllDiscrFilt  码NCO偏移量

trackResults.pllDiscr   载波输入信号与复制信号的相位差异

trackResults.pllDiscrFilt  载波NCO偏移量

代码注释如下,为节约空间,省去英文代码注释(下同),详细版注释随后会在文末链接附上(待更)

function [trackResults, channel]= tracking(fid, channel, settings)%% Initialize result structure 初始化结果结构体 =======================% 信道状态
trackResults.status         = '-';      % 没有追踪到信号,或者失锁% The absolute sample in the record of the C/A code start:
trackResults.absoluteSample = zeros(1, settings.msToProcess);trackResults.codeFreq       = inf(1, settings.msToProcess); % C/A码的频率trackResults.carrFreq       = inf(1, settings.msToProcess);  % 追踪函数载波的频率% Outputs from the correlators (In-phase):  相关器的输出-I
trackResults.I_P            = zeros(1, settings.msToProcess);
trackResults.I_E            = zeros(1, settings.msToProcess);
trackResults.I_L            = zeros(1, settings.msToProcess);% Outputs from the correlators (Quadrature-phase):  相关器的输出-Q
trackResults.Q_E            = zeros(1, settings.msToProcess);
trackResults.Q_P            = zeros(1, settings.msToProcess);
trackResults.Q_L            = zeros(1, settings.msToProcess);% Loop discriminators  跟踪回路
trackResults.dllDiscr       = inf(1, settings.msToProcess);
trackResults.dllDiscrFilt   = inf(1, settings.msToProcess);
trackResults.pllDiscr       = inf(1, settings.msToProcess);
trackResults.pllDiscrFilt   = inf(1, settings.msToProcess);%--- Copy initial settings for all channels 将这些初始化复制到所有信道-------
trackResults = repmat(trackResults, 1, settings.numberOfChannels);

② Initialize tracking variables 初始化追踪函数的变量

在这段代码中,需要提前设置好C/A码跟踪回路载波跟踪环路的参数,其中有一个calcLoopCoef是用于计算滤波器参数的(  [tau1, tau2] = calcLoopCoef(LBW, zeta, k)  ),送入噪声带宽,阻尼系数和环路增益,返回二阶PLL的系数C1和C2。(参考文献《软件定义的GPS和伽利略接收机》P81)

%% 初始化tracking函数的变量 ====================================codePeriods = settings.msToProcess;   % 要处理的毫秒数使用36000 +任何瞬态,以确保导航子帧被提供%--- DLL variables C/A码跟踪回路-----------------
% Define early-late offset (in chips)
earlyLateSpc = settings.dllCorrelatorSpacing;  %码相关器间距% 求和间隔
PDIcode = 0.001;% 计算滤波系数值 需要调用calcLoopCoef函数
[tau1code, tau2code] = calcLoopCoef(settings.dllNoiseBandwidth, ...settings.dllDampingRatio, ...1.0);% 载波跟踪环路参数-----------------------
% Summation interval 求和间隔
PDIcarr = 0.001;% 计算载波环路滤波系数值
[tau1carr, tau2carr] = calcLoopCoef(settings.pllNoiseBandwidth, ...settings.pllDampingRatio, ...0.25);
hwb = waitbar(0,'Tracking...');

③ Start processing channels 处理被捕获通道的信号

首先需要判断出被捕获卫星的通道数,然后初始化该通道的码追踪环偏差和载波追踪环的偏差(设为0.0),最后进入信号处理阶段(以毫秒为单位,共计循环36000 +任何瞬态毫秒)

程序注解如下所示:

%% 处理被捕获信道的信号 ========================================
for channelNr = 1:settings.numberOfChannels% 只处理被捕获通道的信号if (channel(channelNr).PRN ~= 0)% 保存每个通道被跟踪PRN卫星信号的信息trackResults(channelNr).PRN     = channel(channelNr).PRN;% 移动处理的起点,可用于在数据记录中的任何点开始信号处理。% 另外,跳过该数据文件以从适当的示例开始(适应于码相位)。 % 假设样本类型为schar(且每个样本1个字节)fseek(fid, ...settings.skipNumberOfBytes + channel(channelNr).codePhase-1, ...'bof');% 从某点(codePhase)开始处理数据%channel是prerun返回的结果,具体可以参考prerun.m% 生成指定卫星的C/A码caCode = generateCAcode(channel(channelNr).PRN);% 前后各加一个码caCode = [caCode(1023) caCode caCode(1)];%--- 执行初始化 ------------------------------codeFreq      = settings.codeFreqBasis;  %NCO(数控振荡器)初始化C/A码率remCodePhase  = 0.0;  %初始化码相位偏差% 定义一个贯穿捕获全过程的载波频率(即捕获的频率)carrFreq      = channel(channelNr).acquiredFreq;carrFreqBasis = channel(channelNr).acquiredFreq;remCarrPhase  = 0.0;   %初始化载波相位差% 码跟踪环参数设置oldCodeNco   = 0.0;oldCodeError = 0.0;% 载波跟踪环参数设置oldCarrNco   = 0.0;oldCarrError = 0.0;%=== Process the number of specified code periods =================% 处理相应码周期数(36000 +任何瞬态)for loopCnt =  1:codePeriods%注意:下面的模块处于for循环内

④ GUI update 启动GUI显示处理进度条

为了不总是占用任务进程,所以每50次循环更新一下任务进度条,通过waitbar函数,其作用是打开或者更新进度条,显示处理信息的进度。

%% GUI update -------------------------------------------------------------% GUI每50ms更新一次。通过这种方式Matlab GUI具有足够的响应能力。% 同时GUI并不总是占用任务进程。if (rem(loopCnt, 50) == 0) %每50次循环,执行一次if语句trywaitbar(loopCnt/codePeriods, ...hwb, ...['Tracking: Ch ', int2str(channelNr), ...' of ', int2str(settings.numberOfChannels), ...'; PRN#', int2str(channel(channelNr).PRN), ...'; Completed ',int2str(loopCnt), ...' of ', int2str(codePeriods), ' msec']); % waitbar作用是打开或者更新进度条,显示处理信息的进度catch% The progress bar was closed. It is used as a signal% to stop, "cancel" processing. Exit.disp('Progress bar closed, exiting...');returnendend

实际效果如图:


⑤ Read next block of data 将数据每M个采样点分为一个“codePhaseStep”的小块(block)

为了彻底剥离数字中频输入信号中的载波,使其从中频下变频到基带,载波环必定包含一个混频器,并且它所复制的载波必须与输人载波保持一致。如果载波环通过检测其复制载波与输入载波之间的相位差异,然后再相应地调节复制载波的相位,使两者的相位保持致,那么这种载波环的实现形式称为相位锁定环路;如果载波环通过检测其复制载波与输人载波之间的频率差异,然后再相应地调节复制载波的频率,使两者的频率保持一致, 那么这种载波环的实现形式称为频率锁定环路,本程序采用相位锁定环路

需要补充一点的是:环路的更新周期环路的更新周期是指环路每隔多长时间对其数控振荡器的输出频率进行一次控制调整,而更新周期的倒数称为更新率。需要说明的是,因为环路内部通常要对输入数据进行一定形式的积分,而且环路鉴别器又有可能需要检测多个时刻的数据点才输出一个相对可靠的鉴别结果,所以环路更新率并不一定等于输人到环路的中频数字信号数据率。由于将在稍后给予介绍的相干积分通常以1 ms为单元,因而包含相干积分功能块的接收机信号跟踪环路的更新周期长为整数个毫秒,比如少则几毫秒,多则上百个毫秒。同时,还路更新率必须高到能及时反映出接收信号内部任何变化的程度。(噪声带宽BL越大,则环路允许信号变化得越快,因而环路更新周期也就必须越短,否则会引起环路的失稳或者跟踪性能下降。环路更新率一般取值为噪声带宽BL的几倍以上,并至少满足奈奎斯特采样定理。以上的分析同时解释了这样一种常见现象:在同一-噪声带宽和环路更新周期的条件下,静态接收机比高动态接收机能更容易地锁定信号。

相应的代码注释如下:

特别提示:此处及之后代码理解有误(对blksize理解有误,此处理解错了,如果有原程序,设置断点跑一下就知道其具体含义了),正确理解请参考我的最新博客从零编写基于MATLAB的GNSS_SDR程序(GNSS软件接收机)——学习记录(2)_王少靖的博客-CSDN博客中的解释!

%% Read next block of data 将数据每M个采样点分为一个“codePhaseStep”的小块(block)----------         % Find the size of a "block" or code period in whole samples% 基于可变码率和固定采样频率来更新相位codePhaseStep = codeFreq / settings.samplingFreq;% 一个C/A码片被分割成了38个点% NCO(数控振荡器)初始化C/A码率 / 采样频率[Hz]% 1.023*10^6 / 38.192*10^6 等于38blksize = ceil((settings.codeLength-remCodePhase) / codePhaseStep);% (码片长度-初始化码相位差)/步长% (不太清楚其物理意义) (1023-0.0)/ 38%除38是为为了之后每38个数产生一个点% ceil取整函数(朝正向取整)% Read in the appropriate number of samples to process this% interation 读入适量的采样点进行迭代处理[rawSignal, samplesRead] = fread(fid, ...blksize, settings.dataType);% 将文件数据读取到维度为 blksize 的数组rawSignal中% samplesRead 读取的字符数rawSignal = rawSignal';  %transpose vector 转置%  如果没有读取足够的样本,那么可能是数据不足-最好退出if (samplesRead ~= blksize)disp('Not able to read the specified number of samples  for tracking, exiting!')fclose(fid);returnend

⑥ Set up all the code phase tracking information 提前建立所有码相位跟踪需要使用的数据

此部分功能是分别生成:超前、即时、滞后三种C/A码的矩阵

%% 建立所有码相位跟踪信息 -------------------------% 超前的C/A码,它生成的是超前码的C/A码矩阵tcode       = (remCodePhase-earlyLateSpc) : ...codePhaseStep : ...((blksize-1)*codePhaseStep+remCodePhase-earlyLateSpc);%产生的相位步长38,也就是说每38个采样点,生成一个C/A码值%按初始值看tcode=(0.0-0.5):38:((27-1)*38+0.0-0.5)%以38为步长,一毫秒可以分成27个采样点,这样做应该是方便下面的相关计算tcode2      = ceil(tcode) + 1;earlyCode   = caCode(tcode2);% 滞后的C/A码tcode       = (remCodePhase+earlyLateSpc) : ...codePhaseStep : ...((blksize-1)*codePhaseStep+remCodePhase+earlyLateSpc);tcode2      = ceil(tcode) + 1;lateCode    = caCode(tcode2);% 即时的C/A码tcode       = remCodePhase : ...codePhaseStep : ...((blksize-1)*codePhaseStep+remCodePhase);tcode2      = ceil(tcode) + 1;promptCode  = caCode(tcode2);remCodePhase = (tcode(blksize) + codePhaseStep) - 1023.0;

⑦ Generate the carrier frequency to mix the signal to baseband 将中频信号混频后到基带

该部分代码虽然较短,但比较重要,它实现了将中频信号混频到基带上的功能,并生成本地sin/cos载波混频到基带上。

%% Generate the carrier frequency to mix the signal to baseband -----------
% 通过载频将中频信号混频后到基带time    = (0:blksize) ./ settings.samplingFreq;% Get the argument to sin/cos functionstrigarg = ((carrFreq * 2.0 * pi) .* time) + remCarrPhase;%更新后的从(0:blksize)时刻时的载波相位remCarrPhase = rem(trigarg(blksize+1), (2 * pi)); %rem除后的余数,要的是余数,所以不管2*pi的部分% Finally compute the signal to mix the collected data to bandband% 生成本地sin/cos载波混频到基带上carrCos = cos(trigarg(1:blksize));carrSin = sin(trigarg(1:blksize));

⑧ Generate the six standard accumulated values  产生6组积分值I/Q各三组

通过上图(一种典型的接收机跟踪环路)可以看出,在将中频信号混频后到基带后,通过C/A码发生器将产生的超前、即时、滞后的信号与基带信号的I/Q支路相乘,最终得到6组积分值。

%% Generate the six standard accumulated values ---------------------
% 产生6组积分值% First mix to basebandqBasebandSignal = carrCos .* rawSignal;  %Q支路上的基带信号iBasebandSignal = carrSin .* rawSignal;% Now get early, late, and prompt values for eachI_E = sum(earlyCode  .* iBasebandSignal);Q_E = sum(earlyCode  .* qBasebandSignal);I_P = sum(promptCode .* iBasebandSignal);Q_P = sum(promptCode .* qBasebandSignal);I_L = sum(lateCode   .* iBasebandSignal);Q_L = sum(lateCode   .* qBasebandSignal);

⑨ Find PLL error and update carrier NCO 计算载波环路的输入信号与复制信号的相位差异,并生成NCO(数控振荡器)命令

其中,(s) 与u_f (s)分别代表 (t)与u_f (t)的拉氏变换。图11.3 描述了整个锁相环在拉氏频域内的信号传递关系,其中初相位theta_i(s)与(s)分别作为系统的输人与输出,鉴相器增益Kd的单位为V/rad,包含滤波增益Kf在内的环路滤波器的传递函数为F(s),压控振荡器增益Ko的单位为rad/V。我们可得锁相环的系统函数H(s)为

锁相环的相位差异信号与输入信号之间的传递函数为:

图11.3来源《GPS原理与接收机设计》

由于采样信号是离散的,因此需要将s域变换到z域,其中二姐线性数字PLL模型和锁相环滤波器的模型图如下图(图源:《软件定义的...》一书第81页)

由于可以调用函数calcLoopCoef求得C1和C2(F(z)和N(z)表达式已知,7.12和7.13),因此不难通过z域实现对载频信号的调整。

其中,F(z)为滤波器传递函数,N(z)为NCO传递函数。具体代码注释如下:

%% Find PLL error and update carrier NCO ----------------------------------% Implement carrier loop discriminator (phase detector)% 实现载波环路鉴相(鉴相器)carrError = atan(Q_P / I_P) / (2.0 * pi);  % atan反正切函数% φ_e(t) = arctan( Q_P(t) / I_P(t) )输入信号与复制信号的相位差异(式11.70)% Implement carrier loop filter and generate NCO command% 实现载波环路滤波器,生成NCO命令 锁频环carrNco = oldCarrNco + (tau2carr/tau1carr) * ...(carrError - oldCarrError) + carrError * (PDIcarr/tau1carr);oldCarrNco   = carrNco;oldCarrError = carrError;% Modify carrier freq based on NCO command 根据NCO命令修改载波频率carrFreq = carrFreqBasis + carrNco;trackResults(channelNr).carrFreq(loopCnt) = carrFreq;

⑩ Find DLL error and update code NCO 码环鉴别器

对NCO的调节方式同前,不做赘述。

%% Find DLL error and update code NCO 码环鉴别器----------------------codeError = (sqrt(I_E * I_E + Q_E * Q_E) - sqrt(I_L * I_L + Q_L * Q_L)) / ...(sqrt(I_E * I_E + Q_E * Q_E) + sqrt(I_L * I_L + Q_L * Q_L));% 码相位偏差% Implement code loop filter and generate NCO commandcodeNco = oldCodeNco + (tau2code/tau1code) * ...(codeError - oldCodeError) + codeError * (PDIcode/tau1code);oldCodeNco   = codeNco;oldCodeError = codeError;% Modify code freq based on NCO commandcodeFreq = settings.codeFreqBasis - codeNco;trackResults(channelNr).codeFreq(loopCnt) = codeFreq;

⑪ Record various measures to show in postprocessing 记录最终的结果值

保存下最终的结果,然后返回到for loopcnt那里,继续执行下一毫秒的跟踪,直至将全部跟踪结束。

%% Record various measures to show in postprocessing ----------------------% Record sample number (based on 8bit samples)trackResults(channelNr).absoluteSample(loopCnt) = ftell(fid);trackResults(channelNr).dllDiscr(loopCnt)       = codeError;trackResults(channelNr).dllDiscrFilt(loopCnt)   = codeNco;trackResults(channelNr).pllDiscr(loopCnt)       = carrError;trackResults(channelNr).pllDiscrFilt(loopCnt)   = carrNco;trackResults(channelNr).I_E(loopCnt) = I_E;trackResults(channelNr).I_P(loopCnt) = I_P;trackResults(channelNr).I_L(loopCnt) = I_L;trackResults(channelNr).Q_E(loopCnt) = Q_E;trackResults(channelNr).Q_P(loopCnt) = Q_P;trackResults(channelNr).Q_L(loopCnt) = Q_L;end % for loopCnt% If we got so far, this means that the tracking was successful% Now we only copy status, but it can be update by a lock detector% if implementedtrackResults(channelNr).status  = channel(channelNr).status;        end % if a PRN is assigned
end % for channelNr % Close the waitbar
close(hwb)

至此,跟踪函数结束。


plotTracking.m

先把运行的结果图放上

初看结果图(通道PRN03),感觉好像是跑错程序了,细看发现,好像是对的,这6副图清楚的显示了原始信号与追踪处理后的区别,首先可以知道,图1是相位锁定环路的I和Q信号的向量表达形式(详见图11.9《GPS原理与接收机设计》),图二是导航数据信息,其余四副小图分别是载波环路和码环路在滤波处理前后的对比图,中间靠右的图是记录了超前相位,滞后相位和即时相位的互相关结果图,能够反映出在某时刻真实的码相位与复制码相位的差异。

程序不做赘述,比较易读,相关注释标注在了代码后面。

附上本笔记使用的两个注释程序,完整的注释程序待更新。

链接:https://pan.baidu.com/s/1Ih1bdaVnByvcGLIZS4uwkg 
提取码:0000

基于MATLAB编写的GNSS_SDR(GNSS软件接收机)——自学笔记(3)相关推荐

  1. 基于MATLAB编写的GNSS_SDR(GNSS软件接收机)——自学笔记(4)

    继续来看伪距测量函数postNavigation.m函数和plotNavigation.m,其中伪距测量函数又包含了位置计算函数和伪距计算函数(leastSquarePos.m和calculatePs ...

  2. 基于MATLAB编写的GNSS_SDR(GNSS软件接收机)——自学笔记(2)

    上一篇中,由于初始化中涉及到了probeData()函数,因此本文就先了解一下probeData()函数,然后是重点,介绍了捕获.捕获后的绘图函数. 目录 probeData(varargin)函数 ...

  3. 那些年追过的开源GNSS软件接收机(二)

    4. SoftGNSS 时间:2006 网址:GNSS @ CCAR, CU Boulder 简介:Darius Plausinaitis和Dennis M. Akos主导,用matlab代码编写的开 ...

  4. 开源的GNSS软件接收机工程汇总

    开源的GNSS软件接收机工程汇总 作者微信公众号:小卫星 1.softgnss http://gps.aau.dk/ http://gnss-sdr.ru/index.php?blogid=2 htt ...

  5. 基于PYQT编写一个人脸识别软件(2)

    前言 以前在博客:基于PYQT编写一个人脸识别软件 中给出了我自己用PYQT编写的一个小软件.鉴于使用的是开源库--face_recogniton,尽管使用很简单,但是还有些问题,比如:识别黄种人时效 ...

  6. matlab浊音段和清音段,基于Matlab编写的语音端点检测1

    wavread 基于Matlab编写的语音端点检测 专业: 班级: 姓名: 指导教师: 2011年6月18日 一.实验目的 1.学会MATLAB的使用,掌握MATLAB的程序设计方法: 3.掌握语音处 ...

  7. 基于MATLAB的答题卡识别软件设计

    基于 MATLAB 的答题卡识别软件设计 课题意义 随着教育技术的飞速发展,考试普遍使用答题卡来记录答案,采用计算机自动识别答案卡信息,计算考生的成绩,可以减少阅卷人的工作量.本文利用 Matlab ...

  8. 基于Java编写的租房管理软件

    本文介绍的租房管理软件,是基于Java编写的主界面,采用访问数据库的方式,实现增加.删除.及保存信息等功能,因为是租房管理软件,所以点睛之笔是可以实现到期提醒功能.界面如下: 程序实现主要有三个子程序 ...

  9. 从零编写基于MATLAB的GNSS_SDR程序(GNSS软件接收机)——学习记录(2)

    在完成acquisition.m(信号捕获)之后,接下来需要对捕获的信号进行跟踪.本文包含编写Tracking.m.plotTracking.m及涉及到的相关函数的内容. 目录 Tracking.m程 ...

最新文章

  1. 计算机与材料成型与控制方面的应用,广东科技学院
  2. 掌握ASP.NET技术之捷径
  3. 【电信业务】【原则与规范】SOA 面向服务架构
  4. Microsoft和AWS推出免费的云优化服务
  5. 创建一个存储过程,返回指定员工的姓名和薪水
  6. Python内存管理方式和垃圾回收算法解析
  7. python 装饰函数
  8. 大剑无锋之post那么多优点,为什么还用get
  9. Magento教程 5:系统安装与备份
  10. 【java学习之路】(java框架)005.mybatis框架整合及逆向工厂
  11. 损失函数、tensorflow2实现——Python实战
  12. C语言圆周率(公式法)
  13. DTC标准故障码格式解析
  14. openwrt MT7621 支持512M内存
  15. imx 290 支持25fps
  16. 计算机检索的pdf格式,计算机检索基础.pdf
  17. 对潇潇暮雨洒江天,一番洗清秋。渐霜风凄紧,关河冷落,残照当楼。是处红衰翠减,苒苒物华休。唯有长江水,无语东流。不忍登高临远,望故乡渺邈,归思难收。叹年来踪迹,何事苦淹留?想佳人,妆楼颙望,误几回、天际
  18. 改善网页性能的5种方法
  19. Java是如何实现外卖订餐系统的
  20. 我要寄件 网上寄件

热门文章

  1. Element开发页面没有数据时,展示占位图片
  2. 013、静态网页开发
  3. 杭州(含嘉兴,绍兴,金华,湖州,义乌)Uber优步司机奖励政策(1月25日~1月31日)...
  4. ros机器人标定线速度与角速度
  5. Python虽然很火,为啥找工作这么难?
  6. 码农小汪-Volatile和Transient
  7. MTK平台Android Gsensor数据校准与数据获取
  8. app ui设计规范
  9. PAT1108 String复读机
  10. i58400升级可以换什么cpu_为什么明星经常换发型发质还那么好?只要学会这一点,你也可以...