K230D BOX 是正点原子推出的以 K230D 为核心的人工智能开发板,它适于人工智能、机器视觉等应用开发场景,其提供的资源也十分丰富,从而利于对 K230D 的开发与学习。
K230D BOX 的开发工具为CanMV IDE,所采用的编程语音为Python。
该K230D BOX配有LCD显示器,其显示分辨率为640 * 480,且支持触摸操作。
利用这种资源结合串口,可实现具有支持触摸操作的带中文菜单的音乐播放器,其操作界面如图1所示。

图1 操作界面
在K230D BOX上提供了2个串口,其中串口2的电路见图2所示。

图2 串行接口
通过串口可控制MP3播放模块来播放音乐,其电路连接如图3所示。

图3 播放电路
实现音乐播放功能的程序为:
import time, os, urandom, sys
from media.display import *
from media.media import *
from machine import FPIOA
from machine import TOUCH
from machine import UART
# 实例化FPIOA
fpioa = FPIOA()
fpioa.set_function(44,FPIOA.UART2_TXD)
fpioa.set_function(45,FPIOA.UART2_RXD)
Buf1 = b'\x7e\xff\x06\x03\x00\x00\x01\xfe\xf7\xef'
Buf2 = b'\x7e\xff\x06\x03\x00\x00\x02\xfe\xf6\xef'
Buf3 = b'\x7e\xff\x06\x03\x00\x00\x03\xfe\xf5\xef'
Buf4 = b'\x7e\xff\x06\x03\x00\x00\x04\xfe\xf4\xef'
Buf5 = b'\x7e\xff\x06\x03\x00\x00\x05\xfe\xf3\xef'
Buf6 = b'\x7e\xff\x06\x16\x00\x00\x00\xfe\xe5\xef'
uart2 = UART(UART.UART2, baudrate=9600, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# 实例化TOUCH设备0
tp = TOUCH(0)
f=0
b=0
def load_draw_dialog():
img.clear()
# 清屏
#img.draw_string_advanced(640 - 52, 0, 30, "RST", color = (255, 0, 0))
img.draw_string_advanced(600 - 52, 0, 30, "清除", color = (255, 0, 0))
uart2.write(Buf6)
t=0
for t in range(0,639): # 画线输出
img.draw_circle(t, 40,1, color = (255, 255, 255)) # 画点
img.draw_string_advanced(60, 0, 30, " MP3音乐播放器", color = (255, 0, 0))
img.draw_string_advanced(40, 50, 30, "1 -- 野百合也有春天", color = (255, 255, 0))
img.draw_string_advanced(40, 100, 30, "2 -- 乡恋", color = (255, 255, 0))
img.draw_string_advanced(40, 150, 30, "3 -- 心中的玫瑰", color = (255,255, 0))
img.draw_string_advanced(40, 200, 30, "4 -- 凤凰花的时候", color = (255, 255, 0))
img.draw_string_advanced(40, 250, 30, "5 -- 明天你好", color = (255, 255, 0))
img.draw_string_advanced(40, 300, 30, "2 -- 城里的月光", color = (255, 255, 0))
img.draw_string_advanced(40, 350, 30, "5 -- 外婆的澎湖湾", color = (255, 255, 0))
t=0
for t in range(0,639): # 画线输出
img.draw_circle(t, 410,1, color = (255, 255, 255)) # 画点
img.draw_string_advanced(40, 420, 30, "[ 加大音量 ]", color = (0, 200, 255)) #255, 100, 0
img.draw_string_advanced(260, 420, 30, "[ 减小音量 ]", color = (0, 200, 255))
def lcd_draw_bline(x1,y1,x2,y2,size,color):
t = 0
xerr = 0
yerr = 0
delta_x = 0
delta_y = 0
distance = 0
incx = 0
incy = 0
row = 0
col = 0
delta_x = x2 - x1 # 计算坐标增量
delta_y = y2 - y1
row = x1
col = y1
if delta_x > 0:
incx = 1 # 置单步方向
elif delta_x == 0:
incx = 0 # 垂直线
else:
incx = -1
delta_x = -delta_x
if delta_y > 0:
incy = 1
elif delta_y == 0:
incy = 0 # 水平线
else:
incy = -1
delta_y = -delta_y
if delta_x > delta_y:
distance = delta_x; # 选取基本增量坐标轴
else:
distance = delta_y
for t in range(0,distance + 1): # 画线输出
img.draw_circle(row, col, size, color) # 画点
xerr += delta_x
yerr += delta_y
if xerr > distance:
xerr -= distance
row += incx
if yerr > distance:
yerr -= distance
col += incy
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE)
img = image.Image(640, 480, image.RGB888)
Display.init(Display.ST7701, width=640, height=480, to_ide=True)
MediaManager.init()
lastpos = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] #最后一次的数据
# 清空屏幕并在右上角显示"RST"
load_draw_dialog()
Display.show_image(img, 640, 480)
try:
while True:
# 获取TOUCH数据
#p = tp.read(5)
p = tp.read(5)
if p == (): # 发生触摸事件
lastpos = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] # 重新清空所有点
for i in range(len(p)): # 打印每个点坐标信息,最大5点。
if (p[i].x < 640 and p[i].y < 480):
print(p[i].x)
print(p[i].y)
if lastpos[i][0] == 0x0 and lastpos[i][1] == 0x0:
lastpos[i][0] = p[i].x
lastpos[i][1] = p[i].y
lastpos[i][0] = p[i].x
lastpos[i][1] = p[i].y
if (p[i].x > (640 - 50) and p[i].y < 30):
load_draw_dialog()
lastpos[i][0] = 0
lastpos[i][1] = 0
if (p[i].x > 40 and p[i].y > 50 and p[i].y < 100):
img.draw_string_advanced(500, b*50, 30, "OK", color = (0, 0, 0))
f=1
img.draw_string_advanced(500, f*50, 30, "OK", color = (0, 255, 0))
b=f
if (p[i].x > 40 and p[i].y > 100 and p[i].y < 150):
img.draw_string_advanced(500, b*50, 30, "OK", color = (0, 0, 0))
f=2
img.draw_string_advanced(500, f*50, 30, "OK", color = (0, 255, 0))
b=f
if (p[i].x > 40 and p[i].y > 150 and p[i].y < 200):
img.draw_string_advanced(500, b*50, 30, "OK", color = (0, 0, 0))
f=3
img.draw_string_advanced(500, f*50, 30, "OK", color = (0, 255, 0))
b=f
if (p[i].x > 40 and p[i].y > 200 and p[i].y < 250):
img.draw_string_advanced(500, b*50, 30, "OK", color = (0, 0, 0))
f=4
img.draw_string_advanced(500, f*50, 30, "OK", color = (0, 255, 0))
b=f
if (p[i].x > 40 and p[i].y > 250 and p[i].y < 300):
img.draw_string_advanced(500, b*50, 30, "OK", color = (0, 0, 0))
f=5
img.draw_string_advanced(500, f*50, 30, "OK", color = (0, 255, 0))
b=f
# UART发送字节数据
if f==1:
uart2.write(Buf3)
if f==2:
uart2.write(Buf1)
if f==3:
uart2.write(Buf2)
if f==4:
uart2.write(Buf4)
if f==5:
uart2.write(Buf5)
f=0
else:
lastpos[i][0] = 0x0
lastpos[i][1] = 0x0
# 刷新到显示器上
Display.show_image(img)
time.sleep_ms(1000)
os.exitpoint()
except KeyboardInterrupt as e:
print("user stop: ", e)
except BaseException as e:
print(f"Exception {e}")
# deinit display
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
# release media buffer
MediaManager.deinit()经程序运行,其输出的测试结果见图4所示。

图4 输出测试内容
在使用串口来观察输出指令时,其结果如图5所示,说明程序工作正常,在连接MP3播放模块时即可得到预期效果。

图5 输出播放指令

图6 播放状态
视频演示:
我要赚赏金
