文章目录
放假了玩点轻松的,最近为了玩电子墨水屏,搞了个电子墨水屏驱动板,用 ESP32 来驱动是很方便了,不过想试试用 CH32V003 这种入门级的芯片玩玩看,顺便也学习一下墨水屏的驱动。
这里使用的墨水屏是 1.54 英寸,通信接口是 SPI,驱动代码直接找了微雪的示例程序改写成使用 CH32V003 的库。
硬件连接
CH32V003 有一个 SPI 接口,这里与电子墨水屏通信使用四线 SPI,需要额外准备一个 DC 引脚,SPI MISO 不需要使用,这里直接悬空了。
除了标准的 SPI MOSI、CLK 需要使用指定的引脚,其他引脚都使用软件方式操作,特别是 SPI CS,这里连到了 PD3。
墨水屏其他几个引脚的连接:
- CS -> PD3
- BUSY -> PD2
- DC -> PC4
- RST -> PC3
使用 SPI 总线
SPI 驱动直接使用 CH32V003EVT 中的例程就可以了,不过需要注意的是,例程中的一些参数需要根据墨水屏的特性进行修改,主要修改有以下几个地方:
- SPI_DataSize:需要修改为 8b
- SPI_CPOL:需要修改为 Low
- SPI_CPHA:需要修改为 1Edge
- SPI_BaudRatePrescaler:需要修改为 2 或 4
其他的可以保持一致。
这里比较奇怪的就是 SPI_BaudRatePrescaler
参数,只有在 2 和 4 时墨水屏可以正常工作,再大的值墨水屏就不响应了,不知道是什么原因。
也怀疑过是不是分频大了墨水屏不能兼容,尝试修改过 CH32V003 的时钟设置,从 48MHz 换成 24MHz,仍然是 2 和 4 可以工作,比较奇怪。
启用外设时钟
测试工程的代码也是基于之前的项目改的,之前的工程也都是基于 CH32V003-GameConsole
改的,里面有一系列用于快速操作寄存器的宏,例如 PIN_high(PC4)
这样的方式来输出高电平。
但是在实际使用过程中发现有些时候不生效,需要使用官方示例的 GPIO 初始化代码先初始化一下,对比了下初始化过程,才发现需要启动外设时钟,而在 gpio.h
中也有相应的代码。
在使用 PIN_high
这样的操作之前,使用 PORTC_enable()
来启用一下对应组的引脚时钟就可以了。
这个也算是解决了之前写代码时为什么 PIN_high
不能像预期一样工作的疑惑。
字体取模
之前工程中的字体大小是 8x16 的,并且是按纵向 8 位方式取模的,在电子墨水屏上显示会有问题,方向不对。
电子墨水屏一般来说初始化时,设置的显存坐标增长方式是 X+ Y+,这就要重新给字体取模来显示。
另外因为要显示得大一点,也要重新换个字体大小,换成 16x32 像素,就在网上找到了个在线取模工具:https://www.23bei.com/tool/226.html。
不过这里还有个问题,ASCII 可见字符有 95 个,字体大小使用 16x32 的话,一个字母需要 16x32/8=64
个字节,那么 95 个字符的话,就需要 95x64=6,080
个字节,这对于 CH32V003 的 16K Flash 来说压力还是有点大的。
果然在后来写代码的时候,Flash 直接就不够用了,就把小写字母部分删除掉了,能节省个 2K 不到的空间。
绘制字符
和之前使用 12864 OLED 不同的是,1.54 寸电子墨水屏的分辨率是 200x200,如果要在内存中保留一个全量的 framebuffer 的话,是完全不现实的,因此只能即时绘制输出了
另外由于在 X 轴方向是一字节 8 像素的方式进行绘制,在没有 framebuffer 的情况下,就很难在 X 轴方进行像素级别的控制了。
不过这个问题也不大,后续在界面设计上避免就可以,本来也没准备打算显示啥复杂图片 🙈。
先有一个基本的 XBMP 绘制方法,改成适配 X 方向 8 位取模的字体:
然后按顺序显示文本的字体图片就可以了:
运行效果
感觉 16x32 的字体大小在 1.54 寸上看起来效果还可以。
0 条评论。