目录
- 如何点亮屏幕?
- 例程代码拆分
-
- DEV_Module_Init(); 模块引脚初始化
- EPD_1IN54_V2_Init(); 寄存器初始化
- EPD_1IN54_V2_Clear(); 清屏
-
- EPD_1IN54_V2_TurnOnDisplay(); 打开显示满
- 图片动态开辟空间
- void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color) 创建图片
- 显示图片
-
- void Paint_SelectImage(UBYTE *image) 选择图片
- void Paint_Clear(UWORD Color) 清除图片颜色
- void Paint_DrawBitMap(const unsigned char* image_buffer) 显示单色位图
- void EPD_1IN54_V2_Display(UBYTE *Image) 将RAM中的图像缓冲区发送到电子纸和显示器上
-
- static void EPD_1IN54_V2_SendData(UBYTE Data) 数据写入
-
- void DEV_SPI_WriteByte(UBYTE value) SPI写字节
- 在图像上绘制
-
- void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color,DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style) 画点函数
-
- void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color) 绘制像素
- void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style) 画线函数(可任意斜率)
- void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) 画矩形
- void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) 画圆形
我双休实在太累了,然后跟我的hxd上号就没更新,我最近在写墨水屏驱动,我先把 购买链接附上,然后呢我不管咋跑这家店的例程半天跑不出来,我不知道是不是这个店铺的例程有问题嗷,要没问题的小伙伴可以写个文章在评论区嗷,后面呢我领导找了个 微雪的例程让我跑我搞了两个小时也没出来,下班了领导说他加班搞搞,然后呢第二天他搞出来了还不告诉我,让我自己搞,哎,咱能力不太行嗷,墨迹了半天才出来。
对了,昨天现学了SPI,本来昨天要发的,我丢草稿箱了,emm要么晚上发要么明天再发吧。
注意:这个模块虽然是引脚是三线SPI,但实际是四线SPI,模块背面的按键得调成L,也就是四线!
如何点亮屏幕?
由于这个微雪的历程是STM32F103ZET6的,我用的是STM32F103C8T6,需要更换个启动文件
点击魔术棒,把芯片换成F103C8的
因为C6可以和C8兼容,所以我使用J-LINK也使用C6
keil v5 No Ulink2/Me Device Found 的解决方法
把这个注释去掉
编译,这时候会报一个错,堆内存不够,要想快速让屏驱动,把图片的代码注释了,就留显示四个点的。
将堆空间改成2800,除了图片基本都可以显示了。
一上电就会闪,我后面找到的话会改,效果如下图所示。
例程代码拆分
DEV_Module_Init(); 模块引脚初始化
EPD_1IN54_V2_Init(); 寄存器初始化
到SetRAMX那我现在还并不知道为啥不一样。。
EPD_1IN54_V2_Clear(); 清屏
因为屏幕是200x200,一位代表一个像素点,一个字节即可代表8个像素点
至于两个有什么区别就不知道了
EPD_1IN54_V2_TurnOnDisplay(); 打开显示满
刷新屏幕一闪一闪的就是因为这个函数,但是呢似乎没办法把一闪一闪的关掉
图片动态开辟空间
因为一个字节8个像素点,取余8,如果取余为0,则可能是200*200的
void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color) 创建图片
image : 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
Width : 图像缓存的宽度;
Height: 图像缓存的高度;
Rotate:图像的翻转的角度
Color :图像的初始颜色;
注意:旋转和
因为定义了一个全局结构体,这里是对结构体初始化
显示图片
void Paint_SelectImage(UBYTE *image) 选择图片
也就是把图片传给那个全局变量结构体
void Paint_Clear(UWORD Color) 清除图片颜色
#define WHITE 0xFF
#define BLACK 0x00
发现把这个函数注释和更改值,显示的图片都没变化。
没变化是因为图片覆盖了清除的颜色,设置白色就是全屏白色,设置黑色就是全屏黑色,如果把这个清除图片函数去掉,就会默认背景色黑色,会影响下面绘图的效果,如果背景色是黑色,绘图的也是黑色,就什么也看不见了。
void Paint_DrawBitMap(const unsigned char* image_buffer) 显示单色位图
也就是把图片写入RAM,也可以在此基础上改成清屏函数,把图片改成0x00就是黑色,0xff就是白色
void EPD_1IN54_V2_Display(UBYTE *Image) 将RAM中的图像缓冲区发送到电子纸和显示器上
static void EPD_1IN54_V2_SendData(UBYTE Data) 数据写入
void DEV_SPI_WriteByte(UBYTE value) SPI写字节
hspil 就是我们之前定义的全局结构体
value 就是我们要传输的数据
1 就是发送数据量
1000 是timeout,超时时间
在图像上绘制
下图对应上面Paint_Clear函数的注释
void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color,DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style) 画点函数
Xpoint : 点的X坐标
Ypoint : 点的Y坐标
Color : 填充颜色
Dot_Pixel : 点大小
Dot_Style : 点样式
下面这段就是判断绘制的坐标是否超出屏幕范围
画点分为两种类型
一种是DOT_FILL_AROUND ( XDir_Num < 2 * Dot_Pixel - 1 )
另一种是DOT_FILL_RIGHTUP ( XDir_Num < Dot_Pixel )
这两种类型区别也就是一个大一个小
然后就是一个个像素点写入了
void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color) 绘制像素
Xpoint : 在X点
Ypoint : 在Y点
Color : 绘制颜色
下面这部分还是判断是否超出边界
判断是否旋转,旋转也会导致x和y改变
这就判断是否对称了
再次判断是否超出边界,因为可能旋转或者对称了,画布如果不是200x200的,如果是200x100的就会超出边界,200x200的其实不需要,因为不管怎么对称怎么旋转都不会越界
不同的Scale(规模)就对应着不同的写入,在创建图片那写的是2,我试着改成了4和7,发现会变大很多,应该是对应着尺寸,因为微雪的例程不仅仅适应2寸显示屏,还有4,5,7寸显示屏
那么为什么黑色是Paint.Image[Addr] = Rdata & ~(0x80 >> (X % 8));
白色是Paint.Image[Addr] = Rdata | (0x80 >> (X % 8));?
因为白色是1黑色是0 ,所以地址或1,就可以把像素点变成白色
黑色的话就取反再与,这样就不会动其他像素,只改变我需要更改的像素点为黑色
因为一个字节对应8个像素点,也就是0x80,也就对应的二进制8位
这里还是把数据写入缓冲区RAM,还没刷新界面。到最后肯定是调用EPD_1IN54_V2_Display(UBYTE *Image)刷新界面。
void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style) 画线函数(可任意斜率)
Xstart :线段X起点
Ystart :线段Y起点
Xend : 线段X终点
Yend : 线段Y终点
Color :线段的颜色
Line_width : 行宽
Line_Style: 线的类型:实线还是虚线
这一部分是判断点是否超出边界
这一部分是让dx,dy是绝对的正数,如果拿起点作为坐标起点的话,那么终点可以在四个象限的任意一个
增量方向,1为正,-1为负
累计误差
首先这判断了是实线还是虚线,如果是实线那么Dotted_Len就没啥用了,第一个判断,写了3个实线点再写一个虚线点,换句话说就是写了三个1再写了一个0,下面的两个判断,就是保证他任何斜率都可以的关键
void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) 画矩形
上来判断还是有没有越界嗷,然后判断全写满还是只画框,也就是对画线函数组合了一下
void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) 画圆形
首先还是判断是否越界,然后是画实心圆还是空心圆