简介
本次活动买到的一块物料是来自微雪的7.5寸墨水屏,原本是想着用蓝牙来驱动屏幕的显示,但是由于蓝牙协议过于复杂,所以工程的SPI驱动都是在P2P_Server上做的。 其中硬件的SPI引脚被占用了。 随即又切换到软件SPI的方式, 但是软件SPI的方式驱动屏幕的时候会一直出现屏幕busy的情况。 所以最终没有办法了只能新建一个项目工程,并没有使用蓝牙来驱动,最终实现了屏幕的驱动显示等。
驱动的过程
1- 首先在微雪电子官网上下载STM32的驱动。
2- 新建工程,并且将对应的屏幕的驱动文件夹拷贝的项目目录。
3 - 在Main.h中定义对应的SPI的Pin
使其上述的PIN和DEV-config的对应
此时运行正确的话, 屏幕已经可以正确的被点亮了。这里需要说明一下它屏幕的刷新方法。
//Create a new image cache UBYTE *BlackImage; /* you have to edit the startup_stm32fxxx.s file and set a big enough heap size */ UWORD Imagesize = ( (EPD_7IN5_V2_WIDTH % 8 == 0) ? (EPD_7IN5_V2_WIDTH / 8) : (EPD_7IN5_V2_WIDTH / 8 + 1)) * EPD_7IN5_V2_HEIGHT; if ((BlackImage = (UBYTE*) malloc(Imagesize / 2)) == NULL) { printf("Failed to apply for black memory...\r\n"); return -1; }
所有的图像或者文字操作实际上都是操作一块内存空间, 指针。 上述的代码是向上取整计算出当前屏幕最高需要分配多大的内存空间。而受限于原本demo单片机的ram限制,所以这里的内存分配被除2了。 因此屏幕完成一整次的刷新的话需要分两次来传送数据到这块内存中。
如下代码所示
//1.Select Image // 使用创建的图像指针作为图像的缓冲区 Paint_SelectImage(BlackImage); // 清空缓冲器的数据, 使其保持初始化 Paint_Clear(WHITE); //打印文字在 10 * 10 Paint_DrawString_EN(10, 10, "XXXXXXXX", &Font24, WHITE, BLACK); //文字写入缓冲区 EPD_7IN5_V2_WritePicture(BlackImage, 0); //清空内存 Paint_Clear(WHITE); //下部分要写入的文字, 注意坐标并非相对与整个屏蔽0,0处的绝对坐标, 而是相对于上下区的相对0,0的绝对坐标 Paint_DrawString_EN(0, 0, "XXXXXX", &Font24, WHITE, BLACK); // 写入下部分 EPD_7IN5_V2_WritePicture(BlackImage, 1); printf("EPD_Display\r\n"); DEV_Delay_ms(2000);
但是由于现在的WBA55单片机性能足够,所以可以使用另一种刷新方式, 即创建图片分配内存的时候不除二。 直接使用全屏刷新的方式来将整个图片刷新到屏幕上。 如下代码所示。
//Create a new image cache UBYTE *BlackImage; /* you have to edit the startup_stm32fxxx.s file and set a big enough heap size */ UWORD Imagesize = ( (EPD_7IN5_V2_WIDTH % 8 == 0) ? (EPD_7IN5_V2_WIDTH / 8) : (EPD_7IN5_V2_WIDTH / 8 + 1)) * EPD_7IN5_V2_HEIGHT; if ((BlackImage = (UBYTE*) malloc(Imagesize)) == NULL) { printf("Failed to apply for black memory...\r\n"); return -1; } printf("Paint_NewImage\r\n"); Paint_NewImage(BlackImage, EPD_7IN5_V2_WIDTH, EPD_7IN5_V2_HEIGHT, 0, WHITE);
上述代码为创建一个完整的内存空间。
// 使用创建的图像指针作为图像的缓冲区 Paint_SelectImage(BlackImage); // 清空缓冲器的数据, 使其保持初始化 Paint_Clear(WHITE); //相对坐标0,0. 因为只有一个bank Paint_DrawString_EN(10, 10, "xxxx !", &Font24, WHITE, BLACK); Paint_DrawString_EN(300, 300, "Hello Welcome to EEPW", &Font24, WHITE, BLACK); EPD_7IN5_V2_Display(BlackImage); // 写入下部分 printf("EPD_Display\r\n"); DEV_Delay_ms(2000);
直接刷新一个整屏幕。 同时这个黑白的屏幕还支持局部刷新的方式,那么具体的话需要使用下面的API来规定一个矩形的范围,然后会将这个矩形范围的的所有内容全部清空。
void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color);
接下来我们便可以写我们的代办事项界面了。
void drawWindow(void) { printf("EPD_7IN5_V2_test Demo\r\n"); if (DEV_Module_Init() != 0) { return -1; } printf("e-Paper Init and Clear...\r\n"); EPD_7IN5_V2_Init(); EPD_7IN5_V2_Clear(); DEV_Delay_ms(500); //Create a new image cache UBYTE *BlackImage; /* you have to edit the startup_stm32fxxx.s file and set a big enough heap size */ UWORD Imagesize = ( (EPD_7IN5_V2_WIDTH % 8 == 0) ? (EPD_7IN5_V2_WIDTH / 8) : (EPD_7IN5_V2_WIDTH / 8 + 1)) * EPD_7IN5_V2_HEIGHT; if ((BlackImage = (UBYTE*) malloc(Imagesize)) == NULL) { printf("Failed to apply for black memory...\r\n"); return -1; } printf("Paint_NewImage\r\n"); Paint_NewImage(BlackImage, EPD_7IN5_V2_WIDTH, EPD_7IN5_V2_HEIGHT, 0, WHITE); Paint_SelectImage(BlackImage); // 清空缓冲器的数据, 使其保持初始化 Paint_Clear(WHITE); Paint_DrawRectangle(4, 4, 800 - 4, 480 - 4, BLACK, DOT_PIXEL_4X4, DRAW_FILL_EMPTY); Paint_DrawString_EN(250, 20, "TodoList for 16/1/2024", &Font24, WHITE, BLACK); Paint_DrawPoint(220, 60, BLACK, DOT_PIXEL_8X8, DOT_FILL_AROUND); Paint_DrawLine(228, 60, 658, 60, BLACK, DOT_PIXEL_4X4, LINE_STYLE_SOLID); Paint_DrawPoint(655, 60, BLACK, DOT_PIXEL_8X8, DOT_FILL_AROUND); Paint_DrawRectangle(120, 100, 140, 120, BLACK, DOT_PIXEL_4X4, DRAW_FILL_FULL); Paint_DrawString_EN(160, 105, "Hello eepw !", &Font16, WHITE, BLACK); Paint_DrawRectangle(120, 150, 140, 170, BLACK, DOT_PIXEL_4X4, DRAW_FILL_EMPTY); Paint_DrawString_EN(160, 155, "To finish blog submission", &Font16, WHITE, BLACK); Paint_DrawRectangle(120, 200, 140, 220, BLACK, DOT_PIXEL_4X4, DRAW_FILL_EMPTY); Paint_DrawString_EN(160, 205, "Watch tutorial", &Font16, WHITE, BLACK); Paint_DrawRectangle(120, 250, 140, 270, BLACK, DOT_PIXEL_4X4, DRAW_FILL_EMPTY); Paint_DrawString_EN(160, 255, "Go to shopping", &Font16, WHITE, BLACK); Paint_DrawRectangle(120, 300, 140, 320, BLACK, DOT_PIXEL_4X4, DRAW_FILL_EMPTY); Paint_DrawString_EN(160, 305, "Play badminton", &Font16, WHITE, BLACK); Paint_DrawRectangle(120, 350, 140, 370, BLACK, DOT_PIXEL_4X4, DRAW_FILL_EMPTY); Paint_DrawString_EN(160, 355, "Current humidity is: 70 %", &Font16, WHITE, BLACK); EPD_7IN5_V2_Display(BlackImage); EPD_7IN5_V2_Sleep(); free(BlackImage); BlackImage = NULL; // close 5V printf("close 5V, Module enters 0 power consumption ...\r\n"); DEV_Module_Exit(); // Paint_ClearWindows(0, 0, 800, 200, WHITE); // Paint_DrawString_EN(350, 50, "TodoList for 16/1/2024", &Font24, WHITE, BLACK); // EPD_7IN5_V2_Display(BlackImage); // HAL_Delay(5000); // Paint_ClearWindows(0, 0, 800, 200, WHITE); // Paint_DrawString_EN(350, 50, "TodoList for 17/1/2024", &Font24, WHITE, BLACK); // EPD_7IN5_V2_Display(BlackImage); // HAL_Delay(5000); DEV_Delay_ms(2000); }
效果如下所示
工程文件