• PYTHON+CH341 3线SPI驱动UC1601 LCD实现汉字显示


    前言

            参考大佬用CH341驱动OLED,链接如下:GitHub - jimjiang2/ch341dll_wrap_typical_app: A ch341dll Wrap is for using in Python 32bits windows to access I2C SPI and MDIO (by GPIO), and Demo with display PC sreen on OLED by i2c or SPI .

             本文主要实现了CH341驱动LCD显示汉字。

    一、源码

    1. import random
    2. import time
    3. import numpy as np
    4. from matplotlib import pyplot as plt
    5. import os
    6. import random
    7. import numpy as np
    8. from fractions import Fraction
    9. import pyautogui
    10. from PIL import Image
    11. import binascii
    12. import struct
    13. import codecs
    14. import binascii
    15. ## call ch341dll_wrap
    16. from ch341dll_32bits_wrap.ch341dll_wrap import *
    17. ###1. init ch341 device
    18. hd = CH341DEV(0)
    19. hd.ch341_i2c_speed(3)
    20. #hd.ch341_close()
    21. ###2. init oled ----
    22. #原驱动是1306,这里用的是UC1601,函数名没改
    23. hd.spi_oled1306_3w(0,0xe2)
    24. hd.spi_oled1306_3w(0,0x2f) #Set Power Control loading 15-24nF
    25. hd.spi_oled1306_3w(0,0xa6) # Set 0xa6正常 Display;0xa7 反显
    26. hd.spi_oled1306_3w(0,0xc4)
    27. hd.spi_oled1306_3w(0,0xa0)
    28. hd.spi_oled1306_3w(0,0x89)
    29. hd.spi_oled1306_3w(0,0xe8)
    30. hd.spi_oled1306_3w(0,0x81)
    31. hd.spi_oled1306_3w(0,0xdf) #0xaf Set Vbias : 7.99V 0xff
    32. hd.spi_oled1306_3w(0,0xf1)
    33. hd.spi_oled1306_3w(0,0x3f)
    34. hd.spi_oled1306_3w(0,0xf2)
    35. hd.spi_oled1306_3w(0,0x00)
    36. hd.spi_oled1306_3w(0,0xf3)
    37. hd.spi_oled1306_3w(0,0x3f)
    38. hd.spi_oled1306_3w(0,0x85)
    39. hd.spi_oled1306_3w(0,0xaf)
    40. ### initial done
    41. def lcd_address(page,column):
    42. column=column-1;
    43. page=page-1;
    44. din = [];
    45. b1=0xB0 + page;
    46. b2=column&0x0f;
    47. b3=((column>>4)&0x0f)+0x10;
    48. hd.spi_oled1306_3w(0,b1);
    49. hd.spi_oled1306_3w(0,b2);
    50. hd.spi_oled1306_3w(0,b3);
    51. def lcd_clr():
    52. for i in range(9):
    53. lcd_address(i+1,1);
    54. for j in range(132):
    55. hd.spi_oled1306_3w(1,0x00);
    56. def display_graphic_16x16(page,column,data):
    57. din = [];
    58. for ii in range(32):
    59. din.append(int(data[ii]))
    60. for i in range(2):
    61. lcd_address(page+i,column);
    62. for j in range(16):
    63. hd.spi_oled1306_3w(1,din[i*16+j]);
    64. def display_graphic_16x16_1(page,column,data):
    65. din = [];
    66. for ii in range(32):
    67. din.append(int(data[ii]))
    68. for i in range(2):
    69. lcd_address(page+i,column);
    70. for j in range(16):
    71. hd.spi_oled1306_3w(1,din[(1-i)*16+15-j]);
    72. arr=[0x02,0xE2,0x22,0x22,0x22,0xFE,0x22,0x22,
    73. 0x22,0xFE,0x22,0x22,0x22,0xE2,0x02,0x00,
    74. 0x00,0xFF,0x00,0x08,0x06,0x01,0x16,0x08,
    75. 0x06,0x01,0x02,0x4C,0x80,0x7F,0x00,0x00,
    76. 0x80,0x80,0x40,0x20,0x10,0x08,0x04,0xC3,
    77. 0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x00,
    78. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
    79. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    80. 0x10,0x10,0x12,0xD2,0x52,0x5F,0x52,0xF2,
    81. 0x52,0x5F,0x52,0xD2,0x12,0x10,0x10,0x00,
    82. 0x00,0x00,0x00,0x9F,0x52,0x32,0x12,0x1F,
    83. 0x12,0x32,0x52,0x9F,0x00,0x00,0x00,0x00,
    84. 0xF2,0x12,0x12,0xF2,0x02,0xF2,0x12,0x12,
    85. 0xF2,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,
    86. 0xFF,0x01,0x82,0xFF,0x00,0xFF,0x01,0x82,
    87. 0xFF,0x10,0x13,0x12,0x52,0x82,0x7E,0x00,
    88. 0x00,0xFC,0x04,0x04,0xFC,0x00,0x00,0xFC,
    89. 0x04,0x16,0x65,0x04,0x84,0xFC,0x00,0x00,
    90. 0x00,0x0F,0x04,0x04,0x0F,0x00,0x10,0x13,
    91. 0x12,0x12,0x12,0x52,0x92,0x42,0x3E,0x00,
    92. 0x00,0x22,0x26,0x1A,0x12,0x02,0x7E,0x80,
    93. 0x22,0x26,0x1A,0x12,0x02,0x7E,0x00,0x00,
    94. 0x20,0x21,0x29,0x25,0x23,0x25,0x29,0xF1,
    95. 0x29,0x25,0x23,0x25,0x29,0x21,0x20,0x00,
    96. 0x10,0x10,0xD0,0xFF,0x90,0x10,0xFC,0x04,
    97. 0x02,0xF8,0x00,0xFC,0x04,0x04,0xFC,0x00,
    98. 0x04,0x03,0x00,0xFF,0x00,0x01,0x8F,0x44,
    99. 0x32,0x0F,0x00,0xFF,0x04,0x08,0x07,0x00,
    100. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    101. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    102. 0x00,0x00,0x58,0x38,0x00,0x00,0x00,0x00,
    103. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    104. 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
    105. 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
    106. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    107. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#/*"一",8*/
    108. 0x00,0x10,0x88,0xC4,0x33,0x00,0x40,0x42,
    109. 0x42,0x42,0xC2,0x42,0x42,0x42,0x40,0x00,
    110. 0x02,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,
    111. 0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,#/*"行",9*/
    112. 0x00,0x00,0xF8,0x08,0x08,0x0C,0x0A,0x09,
    113. 0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,
    114. 0x00,0x00,0xFF,0x41,0x41,0x41,0x41,0x41,
    115. 0x41,0x41,0x41,0x41,0xFF,0x00,0x00,0x00,#/*"白",10*/
    116. 0x00,0x80,0xEE,0x8A,0xFA,0xAA,0xAE,0x14,
    117. 0x12,0xF7,0xAA,0xAA,0xF6,0x12,0x10,0x00,
    118. 0x00,0x40,0x40,0x5E,0x52,0x53,0x56,0x5A,
    119. 0x52,0x5A,0x1E,0x50,0x90,0x70,0x00,0x00,#/*"鹭",11*/
    120. 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x40,
    121. 0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,
    122. 0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,
    123. 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,#/*"上",12*/
    124. 0x40,0x44,0x54,0x54,0x54,0x54,0x54,0x7F,
    125. 0x54,0x54,0x54,0x54,0x54,0x44,0x40,0x00,
    126. 0x00,0x00,0x00,0xFF,0x15,0x15,0x15,0x15,
    127. 0x15,0x55,0x95,0x7F,0x00,0x00,0x00,0x00,#/*"青",13*/
    128. 0x40,0x40,0x42,0x42,0x42,0x42,0x42,0xFE,
    129. 0x42,0x42,0x42,0x42,0x42,0x40,0x40,0x00,
    130. 0x80,0x80,0x40,0x20,0x10,0x0C,0x03,0x00,
    131. 0x03,0x0C,0x10,0x20,0x40,0x80,0x80,0x00,#/*"天",14*/
    132. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    133. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    134. 0x00,0x00,0x18,0x24,0x24,0x18,0x00,0x00,
    135. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#/*"。",15*/
    136. 0x10,0x0C,0xC4,0x54,0x4C,0x64,0xD5,0x46,
    137. 0x44,0x44,0x4C,0x54,0xC4,0x14,0x0C,0x00,
    138. 0x00,0x00,0xFF,0x40,0x44,0x62,0x55,0x49,
    139. 0x55,0x43,0x40,0x40,0xFF,0x00,0x00,0x00,#/*"窗",0*/
    140. 0x40,0x40,0x20,0x20,0x90,0x88,0x94,0xE3,
    141. 0x84,0x88,0x90,0x20,0x20,0x40,0x40,0x00,
    142. 0x00,0x00,0x00,0xFC,0x44,0x44,0x44,0x44,
    143. 0x46,0x45,0x44,0xFC,0x00,0x00,0x00,0x00,#/*"含",1*/
    144. 0x02,0x02,0xE2,0x22,0x22,0xFE,0x22,0x22,
    145. 0x22,0xFE,0x22,0x22,0xE2,0x02,0x02,0x00,
    146. 0x00,0x00,0xFF,0x48,0x44,0x43,0x40,0x40,
    147. 0x40,0x43,0x44,0x44,0xFF,0x00,0x00,0x00,#/*"西",2*/
    148. 0x00,0xF0,0x00,0xFF,0x00,0xF0,0x40,0x20,
    149. 0x10,0x0C,0x23,0xCC,0x10,0x20,0x40,0x00,
    150. 0x00,0x1F,0x10,0x0F,0x08,0x1F,0x00,0x01,
    151. 0x09,0x11,0x21,0xD1,0x0D,0x03,0x00,0x00,#/*"岭",3*/
    152. 0x80,0x80,0x84,0x84,0x84,0x84,0x84,0xFC,
    153. 0x82,0x82,0x82,0x83,0x82,0x80,0x80,0x00,
    154. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
    155. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#/*"千",4*/
    156. 0x24,0x24,0xA4,0xFE,0x23,0x22,0x80,0x70,
    157. 0x00,0xFF,0x00,0x80,0x40,0x30,0x00,0x00,
    158. 0x08,0x06,0x01,0xFF,0x01,0x86,0x40,0x30,
    159. 0x0E,0x01,0x06,0x18,0x20,0x40,0x80,0x00,#/*"秋",5*/
    160. 0x10,0x0C,0x05,0x55,0x55,0x55,0x05,0x7F,
    161. 0x05,0x55,0x55,0x55,0x05,0x14,0x0C,0x00,
    162. 0x00,0x00,0x41,0x49,0x49,0x49,0x49,0x49,
    163. 0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,#/*"雪",6*/
    164. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    165. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    166. 0x00,0x00,0x58,0x38,0x00,0x00,0x00,0x00,
    167. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#/*",",7*/
    168. 0x00,0xF8,0x01,0x06,0x00,0x00,0x02,0x02,
    169. 0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,
    170. 0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
    171. 0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,#/*"门",8*/
    172. 0x10,0x60,0x02,0x0C,0xC0,0x00,0xF8,0x08,
    173. 0x0C,0x0B,0x08,0x08,0x08,0xF8,0x00,0x00,
    174. 0x04,0x04,0x7C,0x03,0x00,0x00,0xFF,0x41,
    175. 0x41,0x41,0x41,0x41,0x41,0xFF,0x00,0x00,#/*"泊",9*/
    176. 0x00,0x08,0x88,0x48,0x28,0x18,0x0F,0xE8,
    177. 0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,
    178. 0x00,0x20,0x11,0x09,0x05,0x41,0x81,0x7F,
    179. 0x01,0x01,0x05,0x09,0x11,0x20,0x00,0x00,#/*"东",10*/
    180. 0x00,0x00,0x80,0x9E,0x92,0x92,0x92,0x92,
    181. 0x92,0x92,0x92,0x9E,0x80,0x00,0x00,0x00,
    182. 0x84,0x84,0x44,0x44,0x24,0x14,0x0C,0x07,
    183. 0x0C,0x14,0x24,0x44,0x44,0x84,0x84,0x00,#/*"吴",11*/
    184. 0x04,0x04,0x04,0x04,0x04,0xFC,0x44,0x44,
    185. 0x44,0x44,0x44,0xC4,0x04,0x04,0x04,0x00,
    186. 0x80,0x40,0x20,0x18,0x06,0x01,0x00,0x00,
    187. 0x40,0x80,0x40,0x3F,0x00,0x00,0x00,0x00,#/*"万",12*/
    188. 0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0xFE,
    189. 0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
    190. 0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x7F,
    191. 0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00,#/*"里",13*/
    192. 0x80,0x80,0xFC,0x96,0xE5,0x84,0xFC,0x80,
    193. 0x40,0x3E,0x02,0x02,0x7E,0x40,0x40,0x00,
    194. 0x80,0x60,0x1F,0x02,0x4C,0x80,0x7F,0x00,
    195. 0xFE,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,#/*"船",14*/
    196. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    197. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    198. 0x00,0x00,0x18,0x24,0x24,0x18,0x00,0x00,
    199. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#/*"。",15*/
    200. ]
    201. lcd_clr();
    202. for k in range(4):
    203. for i in range(8):
    204. din = [];
    205. for ii in range(i*32,(i+1)*32):
    206. din.append(int(arr[ii+k*32*8]))
    207. display_graphic_16x16(1+(int)(i/8)*2+k*2, i*16%128+1,din)
    208. ### 2.
    209. def get_gb2312_bitmap(HZ):
    210. # 定义变量
    211. gbh = 0 # 汉字机器内码的高位
    212. gbl = 0 # 汉字机器内码的低位
    213. HzPt = 0 # 指向HZ字符串的指针
    214. gbbl = 0 # 根据GB2312编码计算出的点阵信息偏移量
    215. bitmaps_combined = b''
    216. # 打开文件,文件路径为 "gb2312_80.bin"
    217. fp = open("gb2312_80.bin", "rb")
    218. if fp is None: # 如果无法打开文件
    219. print("无法打开字体文件。")
    220. return 1 # 退出函数
    221. # 循环遍历HZ字符串中的每个字符
    222. HZ = HZ.encode("gb2312_80")
    223. while HzPt < len(HZ):
    224. # 将HZ字符串中的每个字符转换为GB2312编码的高位和低位
    225. gbh = HZ[HzPt]
    226. print(gbh)
    227. gbl = HZ[HzPt+1]
    228. # 打印GB2312编码的高位和低位
    229. #print("高位:0x{:02X}".format(gbh))
    230. #print("低位:0x{:02X}".format(gbl))
    231. # 根据GB2312编码计算点阵信息的偏移量
    232. if gbh >= 0xB0: # 如果高位大于等于0xB0(这是GB2312编码的起始部分)
    233. gbbl = ((gbh - 0xA7) * 94 + (gbl - 0xA1)) * 32 # 根据偏移量计算公式计算偏移量
    234. else: # 如果高位小于0xB0
    235. gbbl = ((gbh - 0xA1) * 94 + (gbl - 0xA1)) * 32 # 根据偏移量计算公式计算偏移量
    236. print("偏移量:{:06d}".format(gbbl)) # 打印偏移量
    237. # 使用计算出的偏移量在文件中定位点阵信息,并读取32个字节的点阵信息
    238. fp.seek(gbbl)
    239. bitmap = fp.read(32);
    240. bitmaps_combined=bitmaps_combined+bitmap
    241. # 将HzPt指针向前移动两个位置,准备处理下一个汉字的编码
    242. HzPt += 2
    243. # 关闭文件和释放内存(这部分在原代码中没有明确指出,我在这里添加了)
    244. fp.close()
    245. del bitmap # 释放内存
    246. return bitmaps_combined
    247. HZ ="春江潮水连海平,海上明月共潮生。滟滟随波千万里,何处春江无月明!江流宛转绕芳甸,月照花林皆似霰;空里流霜不觉飞,汀上白沙看不见。江天一色无纤尘,皎皎空中孤月轮。江畔何人初见月?江月何年初照人?人生代代无穷已,江月年年望相似。"
    248. b=get_gb2312_bitmap(HZ)
    249. hex_data = binascii.hexlify(b)
    250. hex_string = hex_data.decode('utf-8')
    251. byte_string = bytes.fromhex(hex_string)
    252. #lst = b.decode('utf-8').split(',')
    253. arr=list(byte_string);
    254. #print(byte_string)
    255. lcd_clr();
    256. #time.sleep(4);
    257. for m in range((int)(len(HZ)/32)):
    258. for k in range(4):
    259. for i in range(8):
    260. din = [];
    261. for jj in range(32):
    262. din.append(int(arr[32-jj+i*32+k*8*32+m*4*8*32]));
    263. display_graphic_16x16_1(1+(int)(i/8)*2+k*2, i*16%128+1,din)
    264. time.sleep(5);
    265. hd.ch341_close();

    二、总结

    1、CH341有IIC、SPI这些MCU常用的接口,可以和拥有这些接口标准的设备通讯。

    2、CH341通过USB和电脑通讯,可以理解为电脑的外围设备。用电脑编程向CH341发送指令,可以使CH341驱动其他原本需要单片机驱动的设备,比如LCD。

    3、电脑的性能远远高于普通的MCU。所以用这种方式可以很容易提高性能,还省了MCU。

    4、python实现了汉字->取字库字模->驱动CH341->LCD。关于驱动CH341,请参见大佬的github的源码。本文代码只是import了大佬的CH341 python封装。本源码依赖ch341dll_wrap.py。

    5、所用字库为标准GB2312-80 16*16点阵字库。

    6、源码需在电脑端执行,CH341硬件支持。

    cb7f5f18150d4699852c2e95155718b2.jpg

    演示用程序执行效果

  • 相关阅读:
    【机器学习】039_合理初始化
    算法部署经验实操:手把手教你掌握Atlas移植和算法推理
    VS Code搭配code runnner编译时提示:g++: fatal error: no input files解决方法
    Python跳动的爱心(双爱心版)
    [附源码]Python计算机毕业设计Django甜品购物网站
    近期面试128题汇总(有超详细答案)
    【Python自然语言处理】文本向量化的六种常见模型讲解(独热编码、词袋模型、词频-逆文档频率模型、N元模型、单词-向量模型、文档-向量模型)
    ARM开发初级-STM32F4寄存器-学习笔记03
    VMware Explore 2022 China,赋能中国企业加速实现云智能
    java语法基础-java面向对象编程-包的定义及使用
  • 原文地址:https://blog.csdn.net/weixin_44067125/article/details/134095894