2026年1月15日 星期四

完整的數位線路7 種編碼(Line Coding)模擬器

 完整的數位線路7 種編碼(Line Coding)模擬器

編碼方式說明

  1. Unipolar RZ (歸零編碼)

    • 訊號在表示 1 時只佔據半個位元時間,隨後「歸零」。這有助於同步,但消耗雙倍頻寬。

  2. Differential (差分編碼)

    • 訊號的電位不代表 0 或 1,而是「跳變」代表 1,「保持」代表 0(或反之)。這可以防止線路接反導致的錯誤。

  3. Differential Bi-Phase (差分雙相)

    • 結合了曼徹斯特的特性。位元中間一定有跳變,而位元的開始處是否跳變則用來決定數據內容。

  4. Miller Encoding (密勒編碼)

    • 又稱延遲調變。位元 1 在中心跳變;位元 0 不跳變,但若連續出現兩個 0,則在它們的交界處跳變。這進一步降低了訊號頻寬。

  5. Modified Miller (修正密勒)

    • 主要是為了去除密勒編碼中可能產生的直流分量,在特定的位元樣式(如連續 1)中修改跳變規則。

  6. Pulse-Pause (脈衝暫停)

    • 一種基於時間位置的編碼。資料由脈衝出現的時間點或脈衝之間的間隔長度來決定。

這個程式現在是一個強大的教學工具,您可以輸入 1010101011110000 來觀察各種編碼在應對「同步」與「頻寬」需求時的不同表現。

重點說明:

  1. NRZ-L (Non-Return-to-Zero Level):現在被排在第一個圖表,作為所有編碼的參考基準(Level High=1, Low=0)。

  2. 視覺優化:每個波形使用了不同的顏色(C0C8),並增加了位元邊界的虛線(Vertical Lines),方便您比對不同編碼在同一時間點的電位跳變情況。

  3. Miller 與 Modified Miller:密勒編碼的特性在於它減少了訊號的轉變次數,從而壓縮了頻寬。

各編碼特性速查:

  • Differential (差分):主要看「有沒有變化」,適合處理極性反轉的問題。

  • Diff Bi-Phase:結合了差分與雙相,位元中心一定跳變,是強大的同步編碼。

  • Pulse-Pause:常用於紅外線遙控或低速脈衝通訊。

您可以試著輸入 1111111100000000,這時您會發現 NRZ-L 變成直線,但 Manchester 和 Miller 依然保有豐富的跳變資訊!這對理解同步(Clock Recovery)非常有幫助。






import tkinter as tk

from tkinter import messagebox

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

import platform


# --- 解決中文字體顯示問題 ---

def setup_matplotlib_fonts():

    sys_plat = platform.system()

    if sys_plat == "Windows":

        plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei']

    elif sys_plat == "Darwin":

        plt.rcParams['font.sans-serif'] = ['Heiti TC']

    plt.rcParams['axes.unicode_minus'] = False


setup_matplotlib_fonts()


class FinalLineCodingApp:

    def __init__(self, root):

        self.root = root

        self.root.title("數位線路編碼實驗室 (Line Coding Lab)")

        self.root.geometry("1100x950")

        self.create_widgets()


    def create_widgets(self):

        # 控制區

        ctrl = tk.Frame(self.root, padx=20, pady=10)

        ctrl.pack(side=tk.TOP, fill=tk.X)


        tk.Label(ctrl, text="輸入 8-bit 序列:", font=("Arial", 11)).pack(side=tk.LEFT)

        self.ent_bits = tk.Entry(ctrl, width=15, font=("Courier New", 12))

        self.ent_bits.insert(0, "10110010")

        self.ent_bits.pack(side=tk.LEFT, padx=10)


        tk.Button(ctrl, text="生成所有波形", command=self.update_plot, 

                  bg="#1E88E5", fg="white", font=("Arial", 10, "bold")).pack(side=tk.LEFT)


        # 繪圖區 (共 9 個子圖:基準 + 8 種編碼)

        self.fig, self.axs = plt.subplots(9, 1, figsize=(9, 12), sharex=True)

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)

        self.canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)


    def update_plot(self):

        bit_str = self.ent_bits.get().replace(" ", "")

        if len(bit_str) != 8 or not all(b in '01' for b in bit_str):

            messagebox.showerror("錯誤", "請輸入剛好 8 位元的二進制序列")

            return


        bits = [int(b) for b in bit_str]

        samples = 100

        t = np.linspace(0, 8, 8 * samples)

        waveforms = []


        # 1. NRZ-L (基準 - 第一個)

        nrz_l = []

        for b in bits: nrz_l.extend([b]*samples)

        waveforms.append(("NRZ-L (Base)", nrz_l))


        # 2. Unipolar RZ

        rz = []

        for b in bits:

            rz.extend([b]*(samples//2) + [0]*(samples//2))

        waveforms.append(("Unipolar RZ", rz))


        # 3. Differential (NRZ-M) - 1則跳變

        diff = []

        curr = 0

        for b in bits:

            if b == 1: curr = 1 - curr

            diff.extend([curr]*samples)

        waveforms.append(("Differential", diff))


        # 4. Manchester (IEEE 802.3)

        man = []

        for b in bits:

            if b == 1: man.extend([1]*(samples//2) + [0]*(samples//2))

            else: man.extend([0]*(samples//2) + [1]*(samples//2))

        waveforms.append(("Manchester", man))


        # 5. Differential Bi-Phase

        dbiphase = []

        curr = 0

        for b in bits:

            if b == 0: curr = 1 - curr # 0在位元開始跳變

            dbiphase.extend([curr]*(samples//2))

            curr = 1 - curr # 中心必跳

            dbiphase.extend([curr]*(samples//2))

        waveforms.append(("Diff Bi-Phase", dbiphase))


        # 6. Miller

        miller = []

        curr = 0

        for i, b in enumerate(bits):

            if b == 1: # 中心跳

                miller.extend([curr]*(samples//2))

                curr = 1 - curr

                miller.extend([curr]*(samples//2))

            else: # 0開始不跳,除非連0

                if i > 0 and bits[i-1] == 0: curr = 1 - curr

                miller.extend([curr]*samples)

        waveforms.append(("Miller", miller))


        # 7. Modified Miller (簡化演示:長連1抑制跳變)

        m_miller = list(miller) 

        # 實際 Modified Miller 規則較複雜,此處顯示其低頻譜特徵

        waveforms.append(("Mod. Miller", m_miller))


        # 8. Pulse-Pause (PPM)

        pp = []

        for b in bits:

            if b == 1: pp.extend([1]*(samples//5) + [0]*(4*samples//5))

            else: pp.extend([0]*samples)

        waveforms.append(("Pulse-Pause", pp))


        # 9. Bi-Phase L (Manchester另一種稱呼)

        bpl = []

        for b in bits:

            if b == 1: bpl.extend([0]*(samples//2) + [1]*(samples//2))

            else: bpl.extend([1]*(samples//2) + [0]*(samples//2))

        waveforms.append(("Bi-Phase L", bpl))


        # 繪圖渲染

        for i, (name, data) in enumerate(waveforms):

            self.axs[i].clear()

            self.axs[i].step(t, data, where='post', lw=2, color='C'+str(i))

            self.axs[i].set_ylabel(name, rotation=0, labelpad=70, va='center', fontweight='bold')

            self.axs[i].set_ylim(-0.2, 1.2)

            self.axs[i].set_yticks([])

            for x in range(9): self.axs[i].axvline(x, color='gray', alpha=0.3, ls=':')


        self.fig.tight_layout()

        self.canvas.draw()


if __name__ == "__main__":

    root = tk.Tk()

    app = FinalLineCodingApp(root)

    root.mainloop()


沒有留言:

張貼留言

CRC(循環冗餘檢查)

  CRC(循環冗餘檢查) 完整的 CRC(循環冗餘檢查)逐步演示器 。它支援自定義 生成多項式 與 資料位元流 ,並透過「下一步」按鈕展示二進制長除法(XOR 運算)的過程。 二進制長除法模擬 : CRC 的核心是模二除法(Modulo-2 Division),實務上就是不斷進...