最近在研究和制作數字示波器,其中涉及一個小算法:需要將 ADC 采樣的數值在 TFT LCD 屏幕上面顯示並且用“線”連接起來。
ADC 按照時序對輸入電壓采樣后,記錄的是一個個的數值,如果顯示的時候不用“線”連接它們,那么他們看上去就是這樣的:
用直線連接以后,看上去就是這樣了(垃圾 LM324 運放的模擬前端,方波波形變形嚴重到令人發指):
X 軸(時間軸)的放大比率確定以后,ADC 采樣值的相鄰 2 點在屏幕上的間距也就確定了,連線算法要做的事情,就是將位於這兩點間的直線上的 LCD 小點一個個點亮。
說實話,不是做數字示波器,我還真不太會用得到這個算法。我也沒有查資料,直接就想到了“2分法”+ 遞歸來處理:
- 將起點(X1,Y1)和終點的坐標(X2,Y2)傳入處理函數(命名叫 Process 吧)
- Process 計算這兩個點的 X 軸和 Y 軸間距 dX =(X2 - X1)和 dY = (Y2 – Y 1)
- 如果 dX、dY 都等於 0,那么說明起點和重點已經連上了,結束處理
- 否則,得到中點(nX,nY)=(X1 + dX,Y1 + dY)
- 把中點(nX,nY)點亮
- 將起點、中點作為新的參數調用 Process
- 將中點、終點作為新的參數調用 Process
- 搞定。
算法是有了,但是,要到數字示波器上面直接調試,還挺麻煩的,因為要對記錄 ADC 采樣值的數組、LCD 屏幕顯存數組、LCD 驅動程序等等軟硬件相關的部分同時修改,並且還要硬件上調試才能看到結果。昨天硬件又不在手邊,也沒法調試。所以,就想到了 Excel。Excel 那些格子(Cell)模擬 LCD 界面那是極方便的,以前干過很多次了。
- 首先,在 Excel 上面框出來一片格子(Cells)當作顯示器屏幕(B2~V18,對應列 2~22,行 2~18)
- 然后,放入 2 個按鈕。1 個用來繪制連線,1 個用來清除屏幕
- 接着,定義起點(綠色,5287963 :)和終點(紅色)的顏色。用顏色標識會比較醒目一點兒
- 最后,把上面的算法寫進按鈕的 VBA 代碼中即可
1: Sub cmdConnectPoints()
2: For c = 2 To 22
3: For r = 2 To 18
4: If Cells(r, c).Interior.Color = 5287936 Then
5: x1 = c
6: y1 = r
7: End If
8: If Cells(r, c).Interior.Color = RGB(255, 0, 0) Then
9: x2 = c
10: y2 = r
11: End If
12: Next
13: Next
14: Process x1, y1, x2, y2
15: End Sub
16:
17: Sub Process(x1, y1, x2, y2)
18: dx = Fix((x2 - x1) / 2)
19: dy = Fix((y2 - y1) / 2)
20: If dx = 0 And dy = 0 Then
21:
22: Else
23: nx = x1 + dx
24: If dx <= (x2 - nx) Then
25: ny = y1 + dy
26: Else
27: ny = y2 - dy
28: End If
29: Cells(ny, nx).Interior.Color = RGB(0, 0, 0)
30: Call Process(x1, y1, nx, ny)
31: Call Process(nx, ny, x2, y2)
32: End If
33: End Sub
34:
35: Sub cmdClear()
36: For c = 2 To 22
37: For r = 2 To 18
38: Cells(r, c).Interior.Color = RGB(255, 255, 255)
39: Next
40: Next
41: End Sub
上面的代碼中,有一段按照中點的 X 坐標距離起點和終點的遠近來改變中點 Y 坐標計算方法的代碼。如果中點 X 距離起點更近,那么 nY = Y1 + dY;否則,nY = Y2 - dY。這樣的微調是為了讓兩點間的連線看上去更加均直、美觀。如果去掉,那么,繪制的連線會“扭”向起點那一邊,不美觀。
效果就是這樣的:
還有使用起來非常爽的操作視頻:
這次做的數字示波器比上一個版本復雜點兒,采樣率更高、控制也會更精細。所以,制作過程中借用了上一個版本的成果(用工具來制作工具,與軟件開發也是相通的道理):