Skip to content

Commit f2a409f

Browse files
committed
Add code file of LCD driver.
1 parent a70bff4 commit f2a409f

File tree

7 files changed

+1894
-0
lines changed

7 files changed

+1894
-0
lines changed

libraries/LCD/LCD.py

+320
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
from usr import LCDPublic
2+
3+
class CustomError(Exception):
4+
def __init__(self, ErrorInfo):
5+
super().__init__(self)
6+
self.errorinfo = ErrorInfo
7+
8+
def __str__(self):
9+
return self.errorinfo
10+
11+
12+
class Peripheral_LCD(object):
13+
'''
14+
LCD通用类,定义LCD屏的通用行为
15+
开放接口:
16+
DrawPoint(x, y, color),DrawLine(x0, y0, x1, y1, color),DrawRectangle(x0, y0, x1, y1, color)
17+
Clear(color),DrawCircle(x0, y0, r, color),ShowChar(x, y, xsize, ysize, ch_buf, fc, bc)
18+
ShowAscii(x, y, xsize, ysize, ch, fc, bc),ShowAsciiStr(x, y, xsize, ysize, str_ascii, fc, bc)
19+
ShowJpg(name, start_x, start_y), lcd_show_chinese(x, y, xsize, ysize, ch, fc, bc),
20+
lcd_show_chinese_str(x, y, xsize, ysize, str_ch, fc, bc),lcd_show_image(image_data, x, y, width, heigth)
21+
lcd_show_image_file(path, x, y, width, heigth, h)
22+
'''
23+
def __init__(self, child_self=None):
24+
25+
if child_self is None:
26+
raise CustomError("child LCD should be init first. ")
27+
else:
28+
self._child_self = child_self
29+
30+
def DrawPoint(self, x, y, color):
31+
'''
32+
画点
33+
:param x: x
34+
:param y: y
35+
:param color: color
36+
'''
37+
tmp = color.to_bytes(2, 'little')
38+
self._child_self._lcd.lcd_write(bytearray(tmp), x, y, x, y)
39+
40+
41+
def Clear(self, color):
42+
'''
43+
清屏
44+
:param color: color
45+
'''
46+
self._child_self._lcd.lcd_clear(color)
47+
48+
def Fill(self, x_s, y_s, x_e, y_e, color):
49+
'''
50+
填充以起始坐标和结束坐标为对角线的矩形
51+
:param x_s: 起始x坐标
52+
:param y_s: 起始y坐标
53+
:param x_e: 结束x坐标
54+
:param y_e: 结束y坐标
55+
:param color: color
56+
'''
57+
tmp = color.to_bytes(2, 'little')
58+
count = (x_e - x_s + 1)*(y_e - y_s + 1)
59+
60+
color_buf = bytearray(0)
61+
62+
for i in range(count):
63+
color_buf += tmp
64+
65+
self._child_self._lcd.lcd_write(color_buf, x_s, y_s, x_e, y_e)
66+
67+
def ColorFill(self, x_s, y_s, x_e, y_e, color_buff):
68+
self._child_self._lcd.lcd_write(color_buff, x_s, y_s, x_e, y_e)
69+
70+
def DrawLine(self, x0, y0, x1, y1, color):
71+
'''
72+
画线
73+
'''
74+
steep = abs(y1 - y0) > abs(x1 - x0)
75+
if steep:
76+
x0, y0 = y0, x0
77+
x1, y1 = y1, x1
78+
if x0 > x1:
79+
x0, x1 = x1, x0
80+
y0, y1 = y1, y0
81+
dx = x1 - x0
82+
dy = abs(y1 - y0)
83+
err = dx // 2
84+
if y0 < y1:
85+
ystep = 1
86+
else:
87+
ystep = -1
88+
while x0 <= x1:
89+
if steep:
90+
self.DrawPoint(y0, x0, color)
91+
else:
92+
self.DrawPoint(x0, y0, color)
93+
err -= dy
94+
if err < 0:
95+
y0 += ystep
96+
err += dx
97+
x0 += 1
98+
99+
def DrawRectangle(self, x0, y0, x1, y1, color):
100+
'''
101+
画矩形
102+
'''
103+
self.DrawLine(x0,y0,x1,y0,color)
104+
self.DrawLine(x0,y0,x0,y1,color)
105+
self.DrawLine(x0,y1,x1,y1,color)
106+
self.DrawLine(x1,y0,x1,y1,color)
107+
108+
def DrawCircle(self, x0, y0, r, color):
109+
'''
110+
画圆
111+
'''
112+
a = 0
113+
b = r
114+
di = 3 - (r << 1)
115+
116+
while a <= b:
117+
self.DrawPoint(x0+a,y0-b,color)
118+
self.DrawPoint(x0+b,y0-a,color)
119+
self.DrawPoint(x0+b,y0+a,color)
120+
self.DrawPoint(x0+a,y0+b,color)
121+
self.DrawPoint(x0-a,y0+b,color)
122+
self.DrawPoint(x0-b,y0+a,color)
123+
self.DrawPoint(x0-a,y0-b,color)
124+
self.DrawPoint(x0-b,y0-a,color)
125+
a += 1
126+
if(di < 0):
127+
di += 4*a+6
128+
else:
129+
di += 10+4*(a-b)
130+
b -= 1
131+
132+
def ShowChar(self, x, y, xsize, ysize, ch_buf, fc, bc):
133+
'''
134+
单个字符显示,包括汉字和ASCII
135+
:param x:x轴坐标
136+
:param y:y轴坐标
137+
:param xsize:字体宽度
138+
:param ysize:字体高度
139+
:param ch_buf:存放汉字字模的元组或者列表
140+
:param fc:字体颜色,RGB565
141+
:param bc:背景颜色,RGB565
142+
'''
143+
rgb_buf = []
144+
t1 = xsize // 8
145+
t2 = xsize % 8
146+
if t2 != 0:
147+
xsize = (t1 + 1) * 8
148+
for i in range(0, len(ch_buf)):
149+
for j in range(0, 8):
150+
if (ch_buf[i] << j) & 0x80 == 0x00:
151+
rgb_buf.append(bc & 0xff)
152+
rgb_buf.append(bc >> 8)
153+
else:
154+
rgb_buf.append(fc & 0xff)
155+
rgb_buf.append(fc >> 8)
156+
self._child_self._lcd.lcd_write(bytearray(rgb_buf), x, y, x + xsize - 1, y + ysize - 1)
157+
158+
def ShowAscii(self, x, y, xsize, ysize, ch, fc, bc):
159+
'''
160+
ASCII字符显示,目前支持8x16、16x24的字体大小
161+
:param x:x轴显示起点
162+
:param y:y轴显示起点
163+
:param xsize:字体宽度
164+
:param ysize:字体高度
165+
:param ch:待显示的ASCII字符
166+
:param fc:字体颜色,RGB565
167+
:param bc:背景颜色,RGB565
168+
'''
169+
ascii_dict = {}
170+
if xsize == 8 and ysize == 16:
171+
ascii_dict = LCDPublic.ascii_8x16_dict
172+
elif xsize == 16 and ysize == 24:
173+
ascii_dict = LCDPublic.ascii_16x24_dict
174+
175+
for key in ascii_dict:
176+
if ch == key:
177+
self.ShowChar(x, y, xsize, ysize, ascii_dict[key], fc, bc)
178+
179+
180+
def ShowAsciiStr(self, x, y, xsize, ysize, str_ascii, fc, bc):
181+
'''
182+
ASCII字符串显示
183+
:param x:x轴显示起点
184+
:param y:y轴显示起点
185+
:param xsize:字体宽度
186+
:param ysize:字体高度
187+
:param str_ascii:待显示的ASCII字符串
188+
:param fc:字体颜色,RGB565
189+
:param bc:背景颜色,RGB565
190+
'''
191+
xs = x
192+
ys = y
193+
if (len(str_ascii) * xsize + x) > self._child_self._lcd_w:
194+
raise Exception('Display out of range')
195+
for ch in str_ascii:
196+
self.ShowAscii(xs, ys, xsize, ysize, ch, fc, bc)
197+
xs += xsize
198+
199+
def ShowJpg(self,name, start_x, start_y):
200+
'''
201+
显示图片
202+
:param name: 图片名
203+
:param start_x: start_x
204+
:param start_y: start_
205+
'''
206+
self._child_self._lcd.lcd_show_jpg(name, start_x, start_y)
207+
208+
def lcd_show_chinese(self, x, y, xsize, ysize, ch, fc, bc):
209+
'''
210+
汉字显示,目前支持16x16、16x24、24x24的字体大小
211+
:param x:x轴显示起点
212+
:param y:y轴显示起点
213+
:param xsize:字体宽度
214+
:param ysize:字体高度
215+
:param ch:待显示的汉字
216+
:param fc:字体颜色,RGB565
217+
:param bc:背景颜色,RGB565
218+
'''
219+
hanzi_dict = {}
220+
if xsize == 16 and ysize == 16:
221+
hanzi_dict = LCDPublic.hanzi_16x16_dict
222+
elif xsize == 16 and ysize == 24:
223+
hanzi_dict = LCDPublic.hanzi_16x24_dict
224+
elif xsize == 24 and ysize == 24:
225+
hanzi_dict = LCDPublic.hanzi_24x24_dict
226+
227+
for key in hanzi_dict:
228+
if ch == key:
229+
self.ShowChar(x, y, xsize, ysize, hanzi_dict[key], fc, bc)
230+
231+
def lcd_show_chinese_str(self, x, y, xsize, ysize, str_ch, fc, bc):
232+
'''
233+
汉字字符串显示
234+
:param x:x轴显示起点
235+
:param y:y轴显示起点
236+
:param xsize:字体宽度
237+
:param ysize:字体高度
238+
:param str_ch:待显示的汉字字符串
239+
:param fc:字体颜色,RGB565
240+
:param bc:背景颜色,RGB565
241+
'''
242+
xs = x
243+
ys = y
244+
# print('chstrlen={}, w={}'.format(len(str), self.lcd_w))
245+
if (len(str_ch) / 3 * xsize + x) > self._child_self._lcd_w:
246+
raise Exception('Display out of range')
247+
for i in range(0, len(str_ch), 3):
248+
index = i + 3
249+
ch = str_ch[i:index]
250+
self.lcd_show_chinese(xs, ys, xsize, ysize, ch, fc, bc)
251+
xs += xsize
252+
253+
def lcd_show_image(self, image_data, x, y, width, heigth):
254+
'''
255+
bytearray图片显示,如果图片宽高小于80x80,可直接该函数一次性写入并显示
256+
:param image_data:存放待显示图片的RGB数据
257+
:param x:起点x
258+
:param y:起点y
259+
:param width:图片宽度
260+
:param heigth:图片高度
261+
'''
262+
self._child_self._lcd.lcd_write(bytearray(image_data), x, y, x + width - 1, y + heigth - 1)
263+
264+
def lcd_show_image_file(self, path, x, y, width, heigth, h):
265+
'''
266+
图片显示,如果图片宽高大于80x80,用该函数来分段写入显示,分段写入原理如下:
267+
以要显示图片的宽度为固定值,将待显示的图片分成若干宽高为 width * h 大小的图片,最后一块高度不足h的按实际高度计算,
268+
h为分割后每个图片的高度,可由用户通过参数 h 指定,h的值应该满足关系: width * h * 2 < 4096
269+
:param path:存放图片数据的txt文件路径,包含文件名,如 '/usr/image.txt.py'
270+
:param x:起点x
271+
:param y:起点y
272+
:param width:图片宽度
273+
:param heigth:图片高度
274+
:param h:分割后每个图片的高度
275+
'''
276+
image_data = []
277+
read_n = 0 # 已经读取的字节数
278+
byte_n = 0 # 字节数
279+
xs = x
280+
ys = y
281+
h_step = h # 按高度h_step个像素点作为步长
282+
h1 = heigth // h_step # 当前图片按h_step大小分割,可以得到几个 width * h_step 大小的图片
283+
h2 = heigth % h_step # 最后剩下的一块 大小不足 width * h_step 的图片的实际高度
284+
with open(path, "r", encoding='utf-8') as fd:
285+
end = ''
286+
while not end:
287+
line = fd.readline()
288+
if line == '':
289+
end = 1
290+
else:
291+
curline = line.strip('\r\n').strip(',').split(',')
292+
for i in curline:
293+
byte_n += 1
294+
read_n += 1
295+
image_data.append(int(i))
296+
if h1 > 0 and byte_n == width * h_step * 2:
297+
self.lcd_show_image(image_data, xs, ys, width, h_step)
298+
image_data = []
299+
ys = ys + h_step
300+
h1 -= 1
301+
byte_n = 0
302+
# print('image_data len = {}'.format(len(image_data)))
303+
elif h1 == 0 and read_n == width * heigth * 2:
304+
if h2 != 0:
305+
self.lcd_show_image(image_data, xs, ys, width, h2)
306+
307+
@staticmethod
308+
def get_rgb565_color(r, g, b):
309+
'''
310+
将24位色转换位16位色
311+
如红色的24位色为0xFF0000,则r=0xFF,g=0x00,b=0x00,
312+
将r、g、b的值传入下面函数即可得到16位相同颜色数据
313+
'''
314+
return ((r << 8) & 0xF800) | ((g << 3) & 0x07E0) | ((b >> 3) & 0x001F)
315+
316+
317+
318+
319+
320+

0 commit comments

Comments
 (0)