单色屏幕的旋转显示算法(micropython,frameBuf)

文章详细介绍了如何在墨水屏上实现90度旋转显示,由于硬件本身不支持旋转,需要通过软件方法对显存进行旋转操作。通过定义虚拟屏幕和显存,以及使用特定的byteArrRotate函数,将旋转后的虚拟屏幕内容拷贝到真实屏幕的显存中,从而达到旋转显示的效果。在ESP32平台上,结合framebuf库,实现了旋转显示的功能。
摘要由CSDN通过智能技术生成

编写墨水屏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)






  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值