DMR协议物理层的系统模型
现代数字无线电通信系统要求数据传输具有高可靠性和高效率,尤其是在存在数据失真和失步风险的情况下。 专业移动无线电通信中使用的关键协议之一是DMR(数字移动无线电),它利用高效的调制和编码方法实现语音和数据的数字传输。
本项目探讨了DMR协议的系统模型,该模型涵盖了完整的信号处理链——从数据包生成到接收端的解调和同步。 对信号传输各阶段进行建模,有助于分析系统面对各类干扰和失真的抗干扰能力。
DMR协议与许多其他电信标准一样,采用类似于OSI(开放系统互连)模型的分层架构。DMR的主要层可划分为以下几类。
-
物理层(Physical Layer,PHY)。负责通过无线电信道传输和接收比特流,包括调制(4-FSK、FM)、 滤波、同步以及信道失真校正(编码也属于物理层,但在本例中不予讨论)。
-
数据链路层(Data Link Layer, DLL)。确保节点间数据的可靠传输,管理信道访问。包括DMR数据包的形成,例如语音和信令数据。 本例中展示了数据包。此外,该层还可包含错误控制(CRC、FEC)、逻辑信道管理(TDMA、两个时隙)以及寻址(用户和组的识别)。
-
网络层(Network Layer)。当DMR集成到包含互联网的更大系统中时,该层负责路由和网间交互。
-
在某些实现中还存在额外层:传输层(如果 DMR 基于 IP 运行)或例如应用层(Application Layer)——支持各项服务(语音、文本消息、遥测)。
DMR 标准主要关注物理层和信道层,因为正是这两个层决定了无线电信道的运行。网络功能通常在基础设施解决方案中实现(例如,在中继器和管理系统中)。
连接辅助功能以启动模型
function run_model( name_model)
Path = (@__DIR__) * "/" * name_model * ".engee"
if name_model in [m.name for m in engee.get_all_models()] # 检查模型加载到内核的条件
model = engee.open( name_model ) # 打开模型
model_output = engee.run( model, verbose=true ); # 运行模型
else
model = engee.load( Path, force=true ) # 加载模型
model_output = engee.run( model, verbose=true ); # 运行模型
engee.close( name_model, force=true ); # 关闭模型
end
sleep(5)
return model_output
end
启动模型并分析结果
我们实现的模型包含以下关键模块。
-
数据包生成——生成与 DMR 数据包类型相对应的信号序列和空帧。
-
4-FSK调制——DMR中用于有效利用频带的数字调制方式。
-
升余弦滤波器——用于限制信号频谱并最大限度地减少符号间干扰。
-
FM调制器——将数字信号转换为模拟信号,以便通过无线电信道进行传输。
-
模拟失步通信信道——模拟发射机与接收机之间的时序失步。
.png)
-
信号序列检测与帧同步——用于在接收端恢复数据包时间位置的算法。
.png)
为了测试俄语和英语消息的正确传输,我们将使用这两种语言的全字母句。
全字母句(源自希腊语,意为“所有字母”),或称全字母组合,是指使用字母表中所有或几乎所有字母、且尽可能不重复的短文本。
我们定义这样一条消息,并在模型中将其表示为字节形式以便于与信号交互,同时在消息末尾补零,使其元素数量为27的倍数(一个DMR数据包中包含216位数据)。 模型中的一部分代码如下所示。
En = "Red fox jumps over the lazy dog"
Ru = "再吃点这些松软的法式面包,再喝点茶吧"
inp_sms = "$En. $Ru."
println("输入消息:")
println(inp_sms)
println()
bytes = Int.(Vector{UInt8}(inp_sms))
remainder = length(bytes) % 27
bytes = vcat(bytes, remainder == 0 ? Int[] : zeros(Int, 27 - remainder))
println("字节表示法:")
println(bytes)
println()
println("消息的帧数:$(length(bytes)/27)")
下图展示了已实现的完整模型。
.png)
让我们在 SNR = 25 的条件下运行该模型,以观察错误最少的结果。 如果您对系统的抗噪能力感兴趣,可以自行调整该参数进行实验。
snr = 25
run_model("DMR") # 启动模型。
接下来对结果进行分析。首先,我们展示输入和输出文本消息的字节表示,以及按字节统计的错误数量。
println("SNR: $snr")
error_bytes = reduce(vcat,collect(simout["DMR/err_symbol"]).value)
println("错误数量:$(sum(error_bytes.>0))")
Delay = reduce(vcat,collect(simout["DMR/Frame_Synchronization.Delay"]).value)
println("位延迟:$(Int.(Delay[end]))")
Input = reduce(vcat,collect(simout["DMR/Inp"]).value)
plot(Input, seriestype = :steppre, label = "Input")
Output = reduce(vcat,collect(simout["DMR/Out"]).value)
plot!(Output, seriestype = :steppre, label = "Output")
如我们所见,当 SNR = 25 时未观察到错误,因此我们可以无误地解码文本消息。
SMS_sim = reduce(vcat, collect(SMS_out).value)
SMS = filter(x -> x != 0x00000000, SMS_sim)
SMS = String(UInt8.(SMS))
println("恢复后的字符串: ", SMS) # 多余的零将被忽略
结论
本例分析了DMR系统模型,仅涉及协议的物理层。今后,如果社区对该主题感兴趣,我们将探讨该协议的其他层,并展示其各个组成部分的实现。