编写墨水屏micropython板本的驱动时,需要对墨水屏进行旋转显示,由于墨水屏本身没有旋转功能,因此需要对显存进行旋转操作。
代码如下:
def byteArrRotate(frbByteArr,scrByteArr,EPD_WIDTH,EPD_HEIGHT):
'''
frbByteArr为旋转后的虚拟屏幕显存,用frameBuff直接操作的
scrByteArr为真实屏幕显存,直接写入屏幕的
EPD_WIDTH和EPD_HEIGHT是真实屏幕显存对应的矩阵大小,虚拟屏幕的该两个值要调换
本段程序实现单色显示屏内容的90度旋转,显示屏定义如下:
---- WIDTH----
| byte0-> |
| |
| |
HEIGHT |
| |
| |
| |
-----------------
不旋转模式下,定义直接用于显示的缓存scrByteArr.显示规则是从第0字节开始,第一行第一列对应byte0的bit7-bit0,高位在前.
显示缓存scrByteArr的大小为width/8*height
如果不旋转,直接定义frameBuff,对scrByteArr进行操作即可,如:
frb_black=framebuf.FrameBuffer(scrByteArr,EPD_WIDTH,EPD_HEIGHT,framebuf.MONO_HLSB)
但要实现旋转显示,就必须定义一块虚拟的屏幕,把WIDTH和HEIGHT对调,
并定义一块显存frbByteArr,与虚拟的屏幕对应,大小为HEIGHT/8*WIDTH
然后再定义一个frameBuff,对frbByteArr进行操作,即是对虚拟屏幕进行操作
最终要将虚拟屏幕的显示内容显示到真实的屏幕上,就要用本程序,将虚拟屏幕的frbByteArr,旋转拷贝到真实屏幕的显存scrByteArr里去
(其实就是改变了两块显存的字节位索引)
再调用屏幕的整体刷新显示。
要旋转显示的话,就没必要再去定义frameBuff去操作真实屏幕的显存scrByteArr了。
'''
EPD_WIDTH_bytes=EPD_WIDTH//8
EPD_HEIGHT_bytes=EPD_HEIGHT//8
#%除法取余;//取整除,只保留整数部分
for i in range(EPD_HEIGHT):
for j in range(EPD_WIDTH_bytes):
scr_byte_addr=i*EPD_WIDTH_bytes+j
frb_byte_addr_base=j*EPD_HEIGHT+(EPD_HEIGHT_bytes-1)-i//8 #j*EPD_HEIGHT本来是j*(EPD_HEIGHT/8)*8 /8代表HEIGHT方向有多少字节,*8是WIDHTH方向1字节8位 为了提高运算速度才用j*EPD_HEIGHT写法,两种写法的意义其实不一样
for k in range(8):
#print(i,j,k)
frb_byte_addr=frb_byte_addr_base+k*EPD_HEIGHT_bytes
#scrByteArr的bit位为7-k,frbByteArr的bit位为i%8
#print("scrByteArr bit=",7-k,"frbByteArr bit=",i%8)
#print("scr_byte_addr=",scr_byte_addr,'frb_byte_addr=',frb_byte_addr)
if ((7-k) >= (i%8)):
scrByteArr[scr_byte_addr]=frbByteArr[frb_byte_addr]<<(7-k-(i%8))&(1<<(7-k))|scrByteArr[scr_byte_addr]
else:
scrByteArr[scr_byte_addr]=frbByteArr[frb_byte_addr]>>((i%8)-(7-k))&(1<<(7-k))|scrByteArr[scr_byte_addr]
#print(frb_byte_addr,scr_byte_addr)
'''
以下为测试代码
import time
start=time.time()
buf_scr=bytearray(EPD_WIDTH *EPD_HEIGHT//8)
buf_black=bytearray(EPD_WIDTH *EPD_HEIGHT//8)
byteArrRotate(buf_scr,buf_black)
print(time.time()-start)
'''
以下是ESP32驱动SES2.66寸墨水屏下实现旋转显示的测试代码。
from epaper2in66b1 import EPD
from machine import Pin,SPI
from time import sleep_ms
e=EPD(spi=SPI(1,baudrate=5000000),cs=Pin(15),dc=Pin(4),rst=Pin(2),busy=Pin(5))
e.init()
# Display resolution
EPD_WIDTH = const(152) #19*8=152
EPD_HEIGHT = const(296) #37*8=296
black = const(0)
white = const(1)
# Display orientation
ROTATE_0 = const(0)
ROTATE_90 = const(1)
ROTATE_180 = const(2)
ROTATE_270 = const(3)
import framebuf
import micropython,gc
gc.mem_free()
import spiSdcard,os,machine
SD_CS = Pin(22)#对应VSPI_CS0引脚,也可以改成其他引脚
sd_spi=SPI(2,sck=Pin(18), mosi=Pin(23),miso=Pin(19))
#GPIO18=VSPI_CLK GPIO19=VSPI_MISO GPIO23=VSPI_MOSI
#spi通道号为2
sd_spi.init()
sd = spiSdcard.SDCard(sd_spi, SD_CS)
# 初始化⽂件系统
vfs = os.VfsFat(sd)# fat挂载卡到⽬录下
os.mount(sd,"/sd")# SD/sd
import zhuanma
unicode_dict=open('/sd/font-16-16-12.Dzk','rb')
from byteArrRotate import byteArrRotate
#framebuff使用时,先要创建一块buff内存块,然后创建framebuff对象,该对象只是提供了一些操作方法,
#方便了对之前创建的buff内存块的操作,其自身不占用buff内存块,
#所以,要送给显示器的数据实际上是buff内存块,
#在framebuff没有提供的方法之外,你也可以直接操作buff内存块,更改显示内容.
#由于ESP8266内存不足,因此暂时不显示红色了.注意如果红色原来有显示东西的话,设法清除掉,否则影响红色显示效果
buf_black=bytearray(EPD_WIDTH *EPD_HEIGHT//8)#对应显示屏原生定义和方向,WIDTH和HEIGHT
frb_black=framebuf.FrameBuffer(buf_black,EPD_WIDTH,EPD_HEIGHT,framebuf.MONO_HLSB)
frb_black.fill(white)
buf_red=bytearray(EPD_WIDTH *EPD_HEIGHT//8)
frb_red=framebuf.FrameBuffer(buf_red,EPD_WIDTH,EPD_HEIGHT,framebuf.MONO_HLSB)
frb_red.fill(white)
#e.display_frame(buf_black,buf_red)#借用黑色buffer清除红色屏
for i in range(1):
sleep_ms(1000)
print(i)
buf_scr=bytearray(EPD_WIDTH *EPD_HEIGHT//8)#frameBuff操作的对象,是旋转了90度的
frb_black=framebuf.FrameBuffer(buf_black,EPD_HEIGHT,EPD_WIDTH,framebuf.MONO_HLSB)#定义frameBuff时,把WIDTH和HEIGHT调换,实现旋转
frb_black.fill(white)
zhuanma.draw_string(frb_black,0,0,white,b'床上明月光',16,16,unicode_dict)
#注意传给draw_string的是frameBuff对象,而不是直接的数组buffer,因为draw_string调用framBuff的blit方法,要求是frameBuff对象
#buf_black[36]=0
#buf_black[1]=0
#buf_black[2]=0
#buf_black[111]=129
#frb_black.text('hello',0,0,black)
byteArrRotate(buf_black,buf_scr,EPD_WIDTH,EPD_HEIGHT)
'''
print("buf_black:")
for i in range(len(buf_black)):
if buf_black[i]!=255:
print(i,buf_black[i])
print("buf_scr:")
for i in range(len(buf_scr)):
if buf_scr[i]!=255:
print(i,buf_scr[i])
'''
e.display_frame(buf_scr,buf_red)