最近在研究和制作数字示波器,其中涉及一个小算法:需要将 ADC 采样的数值在 TFT LCD 屏幕上面显示并且用“线”连接起来。
ADC 按照时序对输入电压采样后,记录的是一个个的数值,如果显示的时候不用“线”连接它们,那么他们看上去就是这样的:
用直线连接以后,看上去就是这样了(垃圾 LM324 运放的模拟前端,方波波形变形严重到令人发指):
X 轴(时间轴)的放大比率确定以后,ADC 采样值的相邻 2 点在屏幕上的间距也就确定了,连线算法要做的事情,就是将位于这两点间的直线上的 LCD 小点一个个点亮。
说实话,不是做数字示波器,我还真不太会用得到这个算法。我也没有查资料,直接就想到了“2分法”+ 递归来处理:
算法是有了,但是,要到数字示波器上面直接调试,还挺麻烦的,因为要对记录 ADC 采样值的数组、LCD 屏幕显存数组、LCD 驱动程序等等软硬件相关的部分同时修改,并且还要硬件上调试才能看到结果。昨天硬件又不在手边,也没法调试。所以,就想到了 Excel。Excel 那些格子(Cell)模拟 LCD 界面那是极方便的,以前干过很多次了。
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。这样的微调是为了让两点间的连线看上去更加均直、美观。如果去掉,那么,绘制的连线会“扭”向起点那一边,不美观。
效果就是这样的:
还有使用起来非常爽的操作视频:
这次做的数字示波器比上一个版本复杂点儿,采样率更高、控制也会更精细。所以,制作过程中借用了上一个版本的成果(用工具来制作工具,与软件开发也是相通的道理):