当前位置: 首页 > news >正文

【STM32】墨水屏驱动开发

目录

一、工程链接

二、简单介绍

三、阅读手册

参考电路

引脚定义

四、开发

cubemx配置

操作流程

代码流程

main函数测试


一、工程链接

STM32墨水屏驱动工程资源-CSDN下载

二、简单介绍

此前笔者购得一块超市货架用的电子价签,拆开后发现排线丝印写着“WFT0290CZ10”型号是GDEW029T5D。

墨水屏使用需注意:

  • 适用于更新周期从几十秒到几分钟的应用场景

  • 非常适合静态图像无需持续供电的应用

  • 超过6个月存储,每3个月刷新一次显示屏

  • 存储期间显示白色图案可防止无法消除的残影并保持最佳性能

墨水屏可以局部刷新也可以全屏刷新:局部刷新耗时短但多次局部刷新后可能有屏幕显示残留,需要全屏刷新一下。刷新完毕后根据需要进行turn off或者进入deep sleep模式。

笔者采用STM32F103CBT6单片机编写驱动,同时也参考网上的资料。

三、阅读手册

参考电路

引脚定义

DC引脚低代表命令,高代表数据。

RES引脚低则复位。

BUSY引脚低代表忙,高代表空闲。

BS1用于选择3线还是4线SPI。

笔者采用4线SPI通信方式,多一条D/C线。

在时钟的上升沿采样,且时钟空闲电平为低。

3线SPI的通信方式下,没有DC线,用SDA的第一个bit的高低电平来表征传输的是命令还是数据。

后面还有寄存器定义,就不赘述了。

四、开发

cubemx配置

开启SPI和相应的GPIO。

通过SPI来对墨水屏写入数据或者命令。

static void EPD_Write(EPD_WriteType type, uint8_t send)
{tx[0] = send;if (type == EPD_CMD){HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_RESET);}else{HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET);}HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);HAL_SPI_Transmit(&hspi1, tx, 1, 10);HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
}

操作流程

代码流程

根据操作流程,编写初始化函数。

void EPD_Init()
{HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);HAL_Delay(10);HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_RESET);HAL_Delay(10);HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);HAL_Delay(10);EPD_BoosterSoftStart();EPD_Config();EPD_Clear();EPD_Refresh();EPD_PartMode();
}

定义一个buffer存放屏幕画面信息,一个字节有8个bit,可以表示8个像素点。

uint8_t epdBuf[EPD_WIDTH][EPD_HEIGHT / 8];

想用来显示字符,图片等都需要显示像素点,因此最核心的函数是打点函数。屏幕默认刷新方向如下。

现在要横过来显示,就要对字节的每一个bit进行操作。

#if (ROTATION == 0)
/*** x 0 - 295* y 0 - 127*/
void EPD_DrawPixel(uint16_t x, uint8_t y)
{epdBuf[x][y / 8] |= (1 << (7 - y % 8)); 
}
#elif (ROTATION == 180)
void EPD_DrawPixel(uint16_t x, uint8_t y)
{x = 295 - x;y = 127 - y;epdBuf[x][y / 8] |= (1 << (7 - y % 8)); 
}
#endif

​​​​​​​把buffer填充好,调用SPI发送。

void EPD_Refresh()
{uint16_t i,j = 0;EPD_Write(EPD_CMD, 0x13);for (i = 0; i < 296; i++){for (j = 0; j < 16; j++){EPD_Write(EPD_DATA, ~epdBuf[i][j]);}}EPD_Write(EPD_CMD, 0x12);EPD_CheckBusy();
}

​​​​​​​发送后墨水屏进行处理,会处于busy状态,墨水屏将busy引脚拉低,此时就不能再对墨水屏发送任何内容。笔者这里作为演示,是同步操作,读者可按需改成异步操作。

static void EPD_CheckBusy()
{while (HAL_GPIO_ReadPin(BUSY_GPIO_Port, BUSY_Pin) == GPIO_PIN_RESET);
}

​​​​​​​有了打点函数后就可以编写画线,填充,字符,图片函数。

/*** x 0 - 295* y 0 - 127*/
void EPD_DrawChar(uint16_t x, uint16_t y, char ch, GUI_CHARINFO_EXT* info)
{ch -= START_CHAR;uint16_t xbyts = ((info + ch)->XSize % 8 == 0) ? (info + ch)->XSize / 8 : (info + ch)->XSize / 8 + 1;for (uint16_t k = 0; k < (info + ch)->YSize; k++){for (uint16_t i = 0; i < xbyts; i++){for (uint16_t j = 0; j < 8; j++){if (((info + ch)->pData[i + k * xbyts] >> j) & 0x01 == 1){EPD_DrawPixel(x + 8 * i + 7 - j, y + (info + ch)->YSize - 1 - k);}}}}
}void EPD_DrawPic(uint16_t x, uint16_t y, GUI_BITMAP* bitmap)
{for (uint16_t k = 0; k < bitmap->YSize; k++){for (uint16_t i = 0; i < bitmap->BytesPerLine; i++){for (uint16_t j = 0; j < 8; j++){if ((bitmap->pData[i + k * bitmap->BytesPerLine] >> j) & 0x01 == 1){EPD_DrawPixel(x + 8 * i + 7 - j, y + bitmap->YSize - 1 - k);}}}}
}void EPD_DrawStr(uint16_t x, uint16_t y, char* str, GUI_CHARINFO_EXT* info)
{uint16_t i = 0;while (*(str + i + 1)){EPD_DrawChar(x, y, *(str + i), info);x += ((info + *(str + i) - START_CHAR)->XDist + (info + *(str + i + 1) - START_CHAR)->XPos);i++;}EPD_DrawChar(x, y, *(str + i), info);
}void EPD_DrawHLine(uint16_t xs, uint16_t xe, uint16_t y)
{for (uint16_t i = xs; i < xe; i++){EPD_DrawPixel(i, y);}
}void EPD_DrawVLine(uint16_t x, uint16_t ys, uint16_t ye)
{for (uint16_t i = ys; i < ye; i++){EPD_DrawPixel(x, i);}
}void EPD_DrawRect(uint16_t xs, uint16_t xe, uint16_t ys, uint16_t ye)
{for (uint16_t i = ys; i < ye; i++){EPD_DrawHLine(xs, xe, i);}
}

字符和图片的取模是使用segger的工具,如果安装了HAL固件包,一般在这个路径。

中文字符是由笔者自制的上位机生成。

main函数测试​​​​​​​

/*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_SPI1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */EPD_Init();for (uint8_t i = 0; i < 10; i++){EPD_DrawChar(170 + 12 * i, 110, '0'+ i, GUI_FontMicrosoftYaHeiUI24_CharInfo);}EPD_DrawStr(170, 20, "hello world", GUI_FontMicrosoftYaHeiUI24_CharInfo);sprintf(str, "0123456789");EPD_DrawStr(170, 0, str, GUI_FontMicrosoftYaHeiUI24_CharInfo);sprintf(str, "3.14");EPD_DrawStr(170, 40, str, GUI_FontMicrosoftYaHeiUI24_CharInfo);for (uint8_t i = 0; i < 4; i++){EPD_DrawChar(170 + 24 * i, 60, i + ' ', GUI_FontMicrosoftYaHeiUI22_CharInfo);}EPD_DrawRect(170, 190, 85, 105);EPD_DrawRect(210, 230, 85, 105);EPD_DrawRect(250, 270, 85, 105);EPD_DrawChar(110, 0, '1' - '-' + ' ', GUI_FontMicrosoftYaHeiUI200_CharInfo);EPD_DrawPic(0, 0, &bmapple_logo_2d_bmp_graphics_graphics_88386);EPD_Refresh();HAL_Delay(2000);EPD_FullMode();EPD_Clear();EPD_Refresh();EPD_PartMode();for (uint8_t i = 0; i < 10; i++){EPD_BufReset();EPD_DrawChar(110, 0, i + '0' - '-' + ' ', GUI_FontMicrosoftYaHeiUI200_CharInfo);EPD_Refresh();HAL_Delay(1000);}/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
http://www.dtcms.com/a/449137.html

相关文章:

  • Java 大视界 -- 基于 Java 的大数据实时流处理在工业物联网设备故障预测与智能运维中的应用
  • 【MySQL】SQL的分类
  • Flutter GridView 使用指南
  • day86——有效的字母异位词(LeetCode-242)
  • 企业的网站建设费用重庆seo什么意思
  • 网站搭建介绍网站建设的原因
  • 怎么建免费网站建设公司网站新闻宣传管理制度
  • Deep Code Research:当 Deep Research 遇上 ABCoder
  • JavaEE初阶——中秋特辑:网络编程送祝福从 Socket 基础到 TCP/UDP 实战
  • 多模卫星导航定位与应用-原理与实践(RTKLib)3
  • 数字婵娟:一部关于中秋节的计算主义宣言
  • ED2K技术
  • 【数据结构】顺序表0基础知识讲解 + 实战演练
  • GPU即服务:Linux与云原生如何联手开启AI算力“自来水“时代
  • 【数据结构】算法复杂度
  • 校园网门户网站建设招聘网站如何做
  • 深度学习(十六):数据归一化处理
  • 力扣70.爬楼梯
  • 【深度学习计算机视觉】10:转置卷积
  • 电子商务网站策划素材网站 模板
  • Coze源码分析-资源库-编辑知识库-后端源码-安全/错误处理机制
  • 【无标题】标签单击事件
  • GAMES101:现代计算机图形学入门(Chapter5 光栅化1(三角形遍历))迅猛式学习笔记(附Homework 0)
  • 【Linux操作系统】进程概念
  • 【Linux】Linux进程信号(上)
  • 海思SS528/22AP30开发笔记之环境搭建和SDK编译
  • 算法二分法详解
  • 信号 | 基本描述 / 分类 / 运算
  • 【环境配置 升级gcc】RK3588 Ubuntu20.04 gcc9升级为gcc10
  • 资产信息收集与指纹识别:HTTPX联动工具实战指南