NT35510的LCD函数详解02(洋桃电子-触摸屏开发者笔记)

news/2024/9/19 5:16:14/ 标签: 嵌入式, 触摸屏, LCD, NT35510

NT35510LCD函数详解02(洋桃电子-触摸屏开发者笔记)

矢量图形绘制函数

绘制单点函数


void LCD_Vector_Point(uint16_t x,uint16_t y){//绘制单像素点(参数:X坐标,Y坐标)LCD_Write_Cursor(x,y);//设置光标位置LCD_Write_COM(SET_GRAM);//开始写入GRAMHAL_SRAM_Write_16b(&hsram1,LCD_DAT,&ForeColor,1);//向LCD写16位数据(句柄,指令COM/数据DAT,存放寄存器,数量)
}void LCD_Vector_Point2(uint16_t x,uint16_t y,uint16_t COLOR){//绘制单像素点(参数:X坐标,Y坐标,颜色)if(LCD_ID==LCD_ID_OTM8009){//判断LCD ID OTM8009A(不同型号的指令有差异)LCD_Write_COM(SET_X);LCD_Write_DAT(x>>8);//写入LCD_Write_COM(SET_X+1);LCD_Write_DAT(x&0xFF);LCD_Write_COM(SET_X+2);LCD_Write_DAT(x>>8);LCD_Write_COM(SET_X+3);LCD_Write_DAT(x&0xFF);LCD_Write_COM(SET_Y);LCD_Write_DAT(y>>8);LCD_Write_COM(SET_Y+1);LCD_Write_DAT(y&0xFF);LCD_Write_COM(SET_Y+2);LCD_Write_DAT(y>>8);LCD_Write_COM(SET_Y+3);LCD_Write_DAT(y&0XFF);}else{//判断LCD ID NT35510/RM68120LCD_Write_COM(SET_X);LCD_Write_DAT(x>>8);//写入LCD_Write_COM(SET_X+1);LCD_Write_DAT(x&0xFF);LCD_Write_COM(SET_Y);LCD_Write_DAT(y>>8);LCD_Write_COM(SET_Y+1);LCD_Write_DAT(y&0xFF);}HAL_SRAM_Write_16b(&hsram1,LCD_COM,&SET_GRAM,1);//向LCD写16位数据(句柄,指令COM/数据DAT,存放寄存器,数量)HAL_SRAM_Write_16b(&hsram1,LCD_DAT,&COLOR,1);//向LCD写16位数据(句柄,指令COM/数据DAT,存放寄存器,数量)
}

该函数的功能是在LCD屏幕上绘制一个单像素点。函数接受两个参数,分别是像素点的X坐标和Y坐标。具体实现步骤如下:

  1. 调用LCD_Write_Cursor​函数,将光标位置设置为给定的X坐标和Y坐标。
  2. 调用LCD_Write_COM​函数,设置开始写入GRAM。
  3. 调用HAL_SRAM_Write_16b​函数,向LCD写入16位数据。该数据即为前景色ForeColor​。通过指定的句柄&hsram1​、指令类型LCD_DAT​以及存放寄存器&ForeColor​,写入1个数据。

绘制线段函数

绘制算法理解参考:Bresenham算法理解-CSDN博客

graph TD A[开始] --> B[初始化参数x1, y1, x2, y2] B --> C[计算增量delta_x = x2 - x1] B --> D[计算增量delta_y = y2 - y1] B --> E[设置初始位置uRow = x1, uCol = y1] C --> F D --> F E --> F F --> G[确定x方向增量incx] F --> H[确定y方向增量incy] G --> I{delta_x > 0?} G --> J{delta_x == 0?} G --> K[delta_x < 0] I --> L[incx = 1] J --> M[incx = 0] K --> N[incx = -1<br>delta_x = -delta_x] H --> O{delta_y > 0?} H --> P{delta_y == 0?} H --> Q[delta_y < 0] O --> R[incy = 1] P --> S[incy = 0] Q --> T[incy = -1<br>delta_y = -delta_y] L --> U M --> U N --> U R --> U S --> U T --> U U --> V[确定主增量轴distance] V --> W{delta_x > delta_y?} W -- 是 --> X[distance = delta_x] W -- 否 --> Y[distance = delta_y] X --> Z Y --> Z Z --> AA[初始化循环变量t = 0] Z --> AB[循环t从0到distance] AB --> AC[绘制点LCD_Vector_Point函数] AB --> AD[xerr += delta_x] AB --> AE[yerr += delta_y] AD --> AF{检查xerr是否大于distance} AE --> AG{检查yerr是否大于distance} AF -- 是 --> AH[xerr -= distance<br>uRow += incx] AF -- 否 --> AG AG -- 是 --> AI[yerr -= distance<br>uCol += incy] AG -- 否 --> AJ[继续循环] AH --> AJ AI --> AJ AJ --> AK{循环结束?} AK -- 是 --> AL[结束] AK -- 否 --> AB

变量介绍:

uint16_t t;
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
int incx, incy, uRow, uCol;
  • t​:循环计数器。
  • xerr​和yerr​:用于累加误差,避免浮点数运算。
  • delta_x​和delta_y​:表示终点与起点在x和y方向上的距离(增量)。
  • distance​:主增量轴的距离,用于循环次数。
  • incx​和incy​:步长,根据直线方向确定是增加还是减少。
  • uRow​和uCol​:当前绘制点的坐标。

思路介绍:

想象一下,你在一张大纸上画一条直线,从一点(我们称之为起点)画到另一点(我们称之为终点)。现在,这张纸非常特别,它是由很多很多小方块组成的,每个小方块我们称之为“像素”。我们的任务就是用彩色笔在这些像素上画线,确保我们的直线只穿过这些小方块的中心,而不碰到方块的边缘。

  1. 第一步:确定起点和终点

    首先,我们需要知道起点(x1, y1)​和终点(x2, y2)​的坐标。这就像是告诉你从纸上的哪个角落开始画,以及在哪里停止。

  2. 第二步:看看我们要走多远

    接下来,我们计算从起点到终点在左右(x方向)和上下(y方向)上各要走多远。这就像是量一下从开始到结束需要走多长的路。代码中用delta_x​来表示左右的距离,用delta_y​来表示上下的距离。

  3. 第三步:决定我们朝哪个方向走

    我们知道了要去哪里,现在要决定怎么走。如果终点在起点的右边,我们就向右走;如果在左边,我们就向左走。同样的,如果终点在起点的上面,我们就向上走;如果在下面,我们就向下走。代码中用incx​和incy​来表示我们走的方向。

    if (delta_x > 0)incx = 1; // 如果终点x大于起点x,我们向右移动
    else if (delta_x == 0)incx = 0; // 如果x没有变化,说明是垂直线,不动x
    else
    {incx = -1; // 如果终点x小于起点x,我们向左移动delta_x = -delta_x; // 把delta_x转换成正数,方便后面的计算
    }
    if (delta_y > 0)incy = 1; // 如果终点y大于起点y,我们向下移动
    else if (delta_y == 0)incy = 0; // 如果y没有变化,说明是水平线,不动y
    else
    {incy = -1; // 如果终点y小于起点y,我们向上移动delta_y = -delta_y; // 把delta_y转换成正数
    }
    
  4. 第四步:选择主要的画线方向

    我们决定是主要沿着x方向(左右)画线,还是沿着y方向(上下)画线。这取决于左右距离和上下距离哪个更长。这个距离我们称之为 distance​。

    if (delta_x > delta_y)distance = delta_x; // 如果x方向的距离更远,我们就以x为基准
    elsedistance = delta_y; // 否则以y为基准
    
  5. 第五步:开始画线

    现在,我们开始画线。我们从起点开始,一小步一小步地移动。每一步,我们都检查一下:“我现在是不是应该转向,开始画下一部分线了?”这个“转向”的决定是基于我们左右和上下的移动距离。

  6. 第六步:决定下一步怎么走

    我们用两个“尺子”(变量xerr​和yerr​)来帮助我们决定下一步怎么走。如果“左右尺子”告诉我们走得太远了,我们就需要向上或向下移动一点。如果“上下尺子”告诉我们走得太远了,我们就需要向左或向右移动一点。

    在循环的每一次迭代中,我们都会先尝试在 x 方向上移动。如果 x 方向的误差 xerr​ 变得比 distance​ 大,说明我们应该转向 y 方向了。这时我们更新 x 方向的位置 uRow​,然后调整 xerr​。如果 yerr​ 也变得比 distance​ 大,我们做同样的操作更新 y 方向的位置 uCol​。

    这个过程会一直重复,直到我们完成整个 distance​ 的移动,或者画完直线。

    for (t = 0; t <= distance + 1; t++)
    {// 画点函数,这里画在LCDLCD_Vector_Point(uRow, uCol);// 更新x方向的误差值xerr += delta_x;if (xerr > distance){xerr -= distance; // 调整误差值uRow += incx;    // 根据方向增加或减少x坐标}// 更新y方向的误差值yerr += delta_y;if (yerr > distance){yerr -= distance; // 调整误差值uCol += incy;    // 根据方向增加或减少y坐标}
    }
    
  7. 第七步:重复步骤五和六

    我们重复第五步和第六步,直到我们的线从起点画到了终点。

  8. 第八步:完成画作

    当我们到达终点时,我们就完成了整条直线的绘制。

绘制圆形

Bresenham 画圆算法原理-CSDN博客

【计算机图形学】中点画圆算法和Bresenham画圆算法_用中点法和bresenham法完成以下内容。 整圆的生成 算法思想-CSDN博客


void LCD_Vector_Circle(uint16_t x0, uint16_t y0, uint8_t r)
{ // 绘制矢量正圆形(参数:圆心X坐标,圆心Y坐标,半径)int a, b, di;if (x0 > r && y0 > r && x0 < (LCD_Height - r) && y0 < (LCD_Width - r)){ // 判断坐标+半径后不要超出绘制区域a = 0;b = r;di = 3 - (r << 1); // 判断下个点位置的标志while (a <= b){									  // 使用Bresenham直线算法LCD_Vector_Point(x0 + a, y0 - b); //LCD_Vector_Point(x0 + b, y0 - a); //LCD_Vector_Point(x0 + b, y0 + a); //LCD_Vector_Point(x0 + a, y0 + b); //LCD_Vector_Point(x0 - a, y0 + b); //LCD_Vector_Point(x0 - b, y0 + a); //LCD_Vector_Point(x0 - a, y0 - b); //LCD_Vector_Point(x0 - b, y0 - a); //a++;if (di < 0)di += 4 * a + 6;else{di += 10 + 4 * (a - b);b--;}}}
}

这里不详讲了,我也不是很懂。

绘制空心矩形

void LCD_Vector_Rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{									 // 绘制矢量空心矩形(参数:左上角X,左上角Y,右下角X,右下角Y坐标)LCD_Vector_Line(x1, y1, x2, y1); // 调用绘制线段函数LCD_Vector_Line(x1, y1, x1, y2);LCD_Vector_Line(x1, y2, x2, y2);LCD_Vector_Line(x2, y1, x2, y2);
}

该函数用于在LCD屏幕上绘制一个矢量空心矩形。

  • 输入参数:

    • x1​、y1​:矩形左上角的坐标
    • x2​、y2​:矩形右下角的坐标
  • 函数内部逻辑:

    • 调用LCD_Vector_Line​函数绘制四条线段,构成矩形的四个边:

      1. 从(x1​, y1​)到(x2​, y1​)的上边
      2. 从(x1​, y1​)到(x1​, y2​)的左边
      3. 从(x1​, y2​)到(x2​, y2​)的下边
      4. 从(x2​, y1​)到(x2​, y2​)的右边

通过这四条线段的绘制,最终在LCD屏幕上呈现出一个空心矩形。

绘制实心矩形

void LCD_Vector_Rectangle_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t COLOR)
{ // 绘制矢量实心矩形(参数:左上角X,左上角Y,右下角X,右下角Y坐标,颜色)uint16_t i, j, xlen = 0;xlen = ex - sx + 1;for (i = sy; i <= ey; i++){LCD_Write_Cursor(sx, i);							 // 设置光标位置LCD_Write_COM(SET_GRAM);							 // 开始写入GRAMfor (j = 0; j < xlen; j++)							 // 显示颜色HAL_SRAM_Write_16b(&hsram1, LCD_DAT, &COLOR, 1); // 向LCD写16位数据(句柄,指令COM/数据DAT,存放寄存器,数量)}
}

该函数用于在LCD屏幕上绘制一个实心矩形。参数包括矩形左上角坐标(sx, sy)、右下角坐标(ex, ey)和矩形的颜色。函数通过计算矩形的宽度,然后使用两层循环来填充矩形区域的每个像素点。首先设置光标位置,然后写入GRAM,最后使用HAL_SRAM_Write_16b函数向LCD写入16位颜色数据,重复执行直到填充整个矩形区域。


http://www.ppmy.cn/news/1509621.html

相关文章

【卫星遥感影像】卫星遥感及图像处理平台发展_论文综述

本文将围绕卫星遥感对地观测主题,从卫星遥感数据获取能力、卫星遥感数据处理系统平台两方面,对国内外现状进行综述,在此基础上分析了卫星遥感的发展趋势。 论文引用 [1]赵忠明,高连如,陈东,等.卫星遥感及图像处理平台发展[J].中国图象图形学报,2019,24(12):2098-2110. 2. 国际…

贪心算法:活动选择问题与霍夫曼编码

引言 贪心算法是一种在每一步选择中都采取当前最优解的方法。贪心算法通常用于解决一些优化问题&#xff0c;它的主要优势在于其简单性和高效性。本文将详细介绍两个经典的贪心算法问题&#xff1a;活动选择问题和霍夫曼编码。 目录 活动选择问题霍夫曼编码 活动选择问题 …

贷齐乐hpp+php特性注入

文章目录 运行过程waf第一层waf拦截第二层waf拦截 数据库查询语句注入思路注入 运行过程 foreach ($_REQUEST as $key > $value) {$_REQUEST[$key] dowith_sql($value);}$request_uri explode("?", $_SERVER[REQUEST_URI]);if (isset($request_uri[1])) {$rewr…

Java基础入门15:算法、正则表达式、异常

算法&#xff08;选择排序、冒泡排序、二分查找&#xff09; 选择排序 每轮选择当前位置&#xff0c;开始找出后面的较小值与该位置交换。 选择排序的关键&#xff1a; 确定总共需要选择几轮&#xff1a;数组的长度-1。 控制每轮从以前位置为基准&#xff0c;与后面元素选择…

pnpm-workspace.yaml 有什么作用

pnpm-workspace.yaml 是在使用 pnpm 包管理器时用于定义工作空间&#xff08;Workspace&#xff09;配置的文件。 1. 作用 1.1 定义工作空间的范围 指定哪些目录或项目属于当前的工作空间&#xff0c;使得 pnpm 能够在这些项目之间有效地共享依赖和进行管理。 1.2 配置共享…

【日常记录-Java】EasyExcel输出设定字体

Author&#xff1a;赵志乾 Date&#xff1a;2024-08-15 Declaration&#xff1a;All Right Reserved&#xff01;&#xff01;&#xff01; 1. 问题描述 使用EasyExcel默认的设定输出时&#xff0c;中文字体显得比较怪异。 2. 解决方案 本质是单元格样式的设置问题&#xff0c…

在复杂的数据库架构中,如何优化 SQL 查询以提高性能和减少资源消耗?

在优化 SQL 查询以提高性能和减少资源消耗时&#xff0c;可以考虑以下几个方面&#xff1a; 使用索引&#xff1a;为经常被查询的列创建索引&#xff0c;可以大大加快查询速度。同时&#xff0c;避免过多的索引&#xff0c;因为过多的索引会增加写入操作的开销。 编写高效的查…

Gather在全球隐私保护领域的先锋地位

随着全球数字化进程的加速&#xff0c;隐私保护已成为各国政府、企业以及个人用户的共同关注点。近年来&#xff0c;频发的数据泄露事件和隐私侵害问题&#xff0c;让用户对安全通信和隐私保护的需求愈发强烈。据 IBM Security 统计&#xff0c;2024 年全球数据泄露的平均成本为…

fastadmin 实现标签打印

项目场景如图&#xff0c;需要打印一批条形码或者二维码&#xff0c;除了市面上成熟的标签机之外&#xff0c;今天挑战一下使用普通的打印机不干胶贴纸&#xff0c;实现低成本的标签打印&#xff1b; 项目框架基于 fastadmin&#xff1a; 1、项目对应的js添加打印按钮的事件监…

位图、布隆过滤器和哈希切割

位图、布隆过滤器和哈希切割 一、位图1、概念2、示意图 二、位图的简单实现1、位图类&#xff08;1&#xff09;代码&#xff08;2&#xff09;说明 2、设置函数&#xff08;1&#xff09;代码&#xff08;2&#xff09;说明 三、应用1、题目一&#xff08;1&#xff09;题目&a…

24.8.15学习笔记(Titanic - Machine Learning from Disaster)

Titanic - Machine Learning from Disaster 导入库&#xff1a; import pandas as pd # 导入pandas库&#xff0c;用于数据处理和分析 import numpy as np # 导入numpy库&#xff0c;用于数值计算from sklearn.impute import SimpleImputer # 从sklearn.impute模块导入Sim…

【Linux网络】Linux网络初探:开启网络世界的大门

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;我们已经系统的学习了Linux的基本操作、进程、线程、文件、通信等待&#xff0c;但是在如今社会没有网络通信方式是万万不行的&#xff0c;今天我们就走进网络中&#xff0c;系统的学习一下有关Linux网…

线程资源回收和进程和线程的比较及互斥锁

资源回收 线程与进程的比较 互斥锁

复写零问题

目录 一题目&#xff1a; 二思路汇总&#xff1a; 三解答代码&#xff1a; 一题目&#xff1a; leetcode原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 二思路汇总&#xff1a; 思路&#xff1a;此题要求原数组修改故&#xff0c;放弃两个指针位于不同数…

Subscription模块

目录 数据访问SampleInfosample_stateinstance_statevalid_data 本文主要解读V1.4版本DDS标准Subscription模块的内容。 类图&#xff1a;P58 TODO 数据访问 在DataReader对象上通过以下操作使用数据&#xff1a;read, read_w_condition, take, and take_w_condition。“read…

学习日志8.14--ALC(Access Control List)访问控制列表

ACL访问控制列表是一条或者多条流量规则的集合&#xff0c;作用主要用于流量的匹配&#xff0c;还可以匹配路由。通过ACL对流量加以控制&#xff0c;通过配合使用过滤工具&#xff0c;对流量进行拦截。需要注意的是ACL只是一个个匹配工具&#xff0c;负责匹配源IP地址、目的IP地…

WEB渗透未授权访问篇-Redis

测试 redis-cli redis-cli -h 127.0.0.1 flunshall 192.168.0.110:6379>ping PONG 存在未授权访问 JS打内网 var cmd new XMLHttpRequest(); cmd.open("POST", "http://127.0.0.1:6379"); cmd.send(flushall\r\n); var c…

TikTok网络无法连接?4个方法解决它

“No network connection”&#xff01;当你信心满满下载并准备开始运营TikTok时&#xff0c;屏幕上如果提示“无互联网连接”非常难办。有很多因素可能会导致此问题&#xff0c;包括网络连接无效、应用程序故障等。接下来将为你盘点主要的原因与解决方法。 一、无网络连接的原…

Ubuntu Linux安装Go语言

Golang是Google公司在2007年开始开发的一种静态强类型、编译型语言。Go语言被设计成一门简单、高效且可靠的编程语言&#xff0c;旨在解决大规模网络服务和分布式系统开发中的复杂性问题。Go语言结合了动态语言的开发速度和C/C等编译型语言的性能与安全性&#xff0c;提供了强大…

自媒体常用的高清素材网站有哪些?自媒体必备的素材网站库分享

在这个自媒体时代&#xff0c;一个高质量的素材库对于创作者来说是必不可少的。优质的素材不仅可以提升内容的吸引力&#xff0c;还能增强专业感。对于那些寻求高清、多样及易用素材的自媒体创作者&#xff0c;以下几个素材网站值得推荐。 蛙学网 蛙学网是自媒体创作者的得力助…