LCD 横屏切换为竖屏-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

LCD 横屏切换为竖屏

在这里插入图片描述

横屏显示如何切换为竖屏显示

LCD 屏默认横屏显示

  • 开发板配套的 LCD 屏默认都是横屏显示,如 4.3 寸、7 寸和 10.1 寸的不同分辨率的 RGB LCD 屏

固定坐标体系

  • (以 800*480
    分辨率为例)横屏模式下的固定坐标:左上角(0, 0)、左下角(0, 479)、右上角(799, 0)、右下角(799, 479)

    • LCD 屏正向放置

显存地址计算

  • 假设显存基地址为(unsigned
    char *)base

  • 显存地址的计算公式是 base + (y * width + x) * pix_bytes

    • LCD 像素点与显存对应关系示意图
  • pix_bytes 表示一个像素点使用 pix_bytes 个字节来描述

竖屏坐标转换

  • 应用程序中竖屏显示时,左下角作为起点(0, 0),相应的坐标转换为左上角(479, 0)、右下角(0, 799)、右上角(479, 799)

    • 竖屏方式坐标分布
  • 这是应用程序认为的一种坐标分布,对于LCD 硬件来说,实际物理上的起点坐标依然左上角的位置

显存地址计算调整

  • 竖屏显示时,显存地址的计算公式变为 base + ((height - 1 - x) * width + y) * pix_bytes

  • 不同的竖屏方式需要不同的计算公式

代码编写

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>#define argb8888_to_rgb565(color)   ({ \unsigned int temp = (color); \((temp & 0xF80000UL) >> 8) | \((temp & 0xFC00UL) >> 5) | \((temp & 0xF8UL) >> 3); \})static int lcd_width;                   //LCD X分辨率
static int lcd_height;                  //LCD Y分辨率
static int lcd_max_y;                   //*LCD Y坐标最大值
static int user_width;                  //*竖屏模式下X分辨率
static int user_height;                 //*竖屏模式下Y分辨率
static unsigned short *screen_base = NULL;      //映射后的显存基地址/********************************************************************* 函数名称: lcd_draw_point* 功能描述: 打点* 输入参数: x, y, color* 返 回 值: 无********************************************************************/
static void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color)
{unsigned short rgb565_color = argb8888_to_rgb565(color);//得到RGB565颜色值/* 对传入参数的校验 */if (x >= user_width)x = user_width - 1;if (y >= user_height)y = user_height - 1;/* 填充颜色 *///竖屏显示时,显存地址的计算公式变为 base + ((height - 1 - x) * width + y) * pix_bytesscreen_base[(lcd_max_y-x) * lcd_width + y] = rgb565_color;//*
}/********************************************************************* 函数名称: lcd_draw_line* 功能描述: 画线(水平或垂直线)* 输入参数: x, y, dir, length, color* 返 回 值: 无********************************************************************/
static void lcd_draw_line(unsigned int x, unsigned int y, int dir,unsigned int length, unsigned int color)
{unsigned short rgb565_color = argb8888_to_rgb565(color);//得到RGB565颜色值unsigned int end;unsigned long temp;/* 对传入参数的校验 */if (x >= user_width)x = user_width - 1;if (y >= user_height)y = user_height - 1;/* 填充颜色 */temp = (lcd_max_y-x) * lcd_width + y;//*if (dir) {  //水平线end = x + length - 1;if (end >= user_width)end = user_width - 1;for ( ; x <= end; x++, temp -= lcd_width)screen_base[temp] = rgb565_color;}else {  //垂直线end = y + length - 1;if (end >= user_height)end = user_height - 1;for ( ; y <= end; y++, temp++)screen_base[temp] = rgb565_color;}
}/********************************************************************* 函数名称: lcd_draw_rectangle* 功能描述: 画矩形* 输入参数: start_x, end_x, start_y, end_y, color* 返 回 值: 无********************************************************************/
static void lcd_draw_rectangle(unsigned int start_x, unsigned int end_x,unsigned int start_y, unsigned int end_y,unsigned int color)
{int x_len = end_x - start_x + 1;int y_len = end_y - start_y - 1;lcd_draw_line(start_x, start_y, 1, x_len, color);//上边lcd_draw_line(start_x, end_y, 1, x_len, color); //下边lcd_draw_line(start_x, start_y + 1, 0, y_len, color);//左边lcd_draw_line(end_x, start_y + 1, 0, y_len, color);//右边
}/********************************************************************* 函数名称: lcd_fill* 功能描述: 将一个矩形区域填充为参数color所指定的颜色* 输入参数: start_x, end_x, start_y, end_y, color* 返 回 值: 无********************************************************************/
static void lcd_fill(unsigned int start_x, unsigned int end_x,unsigned int start_y, unsigned int end_y,unsigned int color)
{unsigned short rgb565_color = argb8888_to_rgb565(color);//得到RGB565颜色值unsigned long temp;unsigned long step_size_count;//*记录当前步骤的大小计数int x;/* 对传入参数的校验 */if (end_x >= user_width)end_x = user_width - 1;if (end_y >= user_height)end_y = user_height - 1;/* 填充颜色 */temp = (lcd_max_y-start_x) * lcd_width + start_y;//*for ( ; start_y <= end_y; start_y++, temp++) {step_size_count = 0;//*for (x = start_x; x <= end_x; x++, step_size_count += lcd_width)//*screen_base[temp - step_size_count] = rgb565_color;//*}
}int main(int argc, char *argv[])
{struct fb_fix_screeninfo fb_fix;struct fb_var_screeninfo fb_var;unsigned int screen_size;int fd;/* 打开framebuffer设备 */if (0 > (fd = open("/dev/fb0", O_RDWR))) {perror("open error");exit(EXIT_FAILURE);}/* 获取参数信息 */ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix);screen_size = fb_fix.line_length * fb_var.yres;//*计算 framebuffer 的总大小(即屏幕缓冲区的大小)lcd_width = fb_var.xres;//*获取 LCD 宽度lcd_height = fb_var.yres;//*获取 LCD 高度lcd_max_y = lcd_height - 1;//*计算 Y 轴最大值user_width = fb_var.yres;//*竖屏下的宽度user_height = fb_var.xres;//*竖屏下的高度/* 将显示缓冲区映射到进程地址空间 */screen_base = mmap(NULL, screen_size, PROT_WRITE, MAP_SHARED, fd, 0);if (MAP_FAILED == (void *)screen_base) {perror("mmap error");close(fd);exit(EXIT_FAILURE);}/* 画正方形方块 */int w = user_height * 0.25;//*方块的宽度为1/4屏幕高度lcd_fill(0, user_width-1, 0, user_height-1, 0x0); //清屏(屏幕显示黑色)lcd_fill(0, w, 0, w, 0xFF0000); //红色方块lcd_fill(user_width-w, user_width-1, 0, w, 0xFF00);   //绿色方块lcd_fill(0, w, user_height-w, user_height-1, 0xFF);   //蓝色方块lcd_fill(user_width-w, user_width-1, user_height-w, user_height-1, 0xFFFF00);//黄色方块/* 画线: 十字交叉线 */lcd_draw_line(0, user_height * 0.5, 1, user_width, 0xFFFFFF);//白色水平线lcd_draw_line(user_width * 0.5, 0, 0, user_height, 0xFFFFFF);//白色垂直线/* 画矩形 */unsigned int s_x, s_y, e_x, e_y;s_x = 0.25 * user_width;s_y = w;e_x = user_width - s_x;e_y = user_height - s_y;for ( ; (s_x <= e_x) && (s_y <= e_y);s_x+=5, s_y+=5, e_x-=5, e_y-=5)lcd_draw_rectangle(s_x, e_x, s_y, e_y, 0xFFFFFF);/* 退出 */munmap(screen_base, screen_size);  //取消映射close(fd);  //关闭文件exit(EXIT_SUCCESS);    //退出进程
}

由FrameBuffer 应用编程改写,主要是一些逻辑上的变化

LCD 显示效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3267983.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC]

文章目录 某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现某数据泄露防护(DLP)系统NoticeAjax接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内…

Vitis AI 使用 VAI_Q_PYTORCH 工具

目录 1. 简介 2. 资料汇总 3. 示例解释 3.1 快速上手示例 4. 总结 1. 简介 vai_q_pytorch 是 Vitis AI Quantizer for Pytorch 的缩写&#xff0c;主要作用是优化神经网络模型。它是 Vitis AI 平台的一部分&#xff0c;专注于神经网络的深度压缩。 vai_q_pytorch 的作用…

如何应对SQL注入攻击?

引言 在现今的网络世界中&#xff0c;安全性已成为至关重要的话题。SQL注入&#xff08;SQL Injection&#xff09;是一种常见且危险的网络攻击方式&#xff0c;攻击者通过向SQL查询中插入恶意代码来操控数据库&#xff0c;从而获取敏感信息或破坏数据。了解SQL注入的各种类型…

2024中国大学生算法设计超级联赛(2)

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;彩笔ACMer一枚。 &#x1f3c0;所属专栏&#xff1a;杭电多校集训 本文用于记录回顾总结解题思路便于加深理解。 &#x1f4e2;&#x1f4e2;&#x1f4e2;传送门 A - 鸡爪解题思…

AI在Facebook的应用:预见智能化社交的新前景

在数字化时代&#xff0c;社交媒体平台已成为我们生活的重要组成部分&#xff0c;而人工智能&#xff08;AI&#xff09;的快速发展正推动着这些平台向更智能、更个性化的方向发展。Facebook&#xff0c;作为全球最大的社交网络平台之一&#xff0c;正不断探索和应用AI技术&…

MySQL作业四

1. 创建数据库mydb15_indexstu 2. 创建表student&#xff0c;course&#xff0c;sc 2.1 创建表student 2.2 创建表course 2.3 创建表sc 3. 处理表 3.1 修改表student中年龄&#xff08;sage&#xff09;字段属性&#xff0c;数据类型由int改变为smallint 3.2 为表course中cno…

智能算法驱动的爬虫平台:解锁网络数据的无限潜力

摘要 在信息爆炸的时代&#xff0c;网络数据如同深海宝藏&#xff0c;等待着有识之士发掘其无尽价值。本文将探索智能算法驱动的爬虫平台如何成为解锁这一宝库的关键&#xff0c;不仅剖析其技术优势&#xff0c;还通过实例展示它如何助力企业与开发者高效、稳定地采集数据&…

专家访谈|王本友:分不清9.11和9.9谁大?大模型该做擅长的,而不是事事完美

作为生成式人工智能的代表&#xff0c;大模型已经进入全新的发展阶段。 红星新闻、红星资本局与OpenEval平台联合发起“巢燧杯”大模型创新发展大赛&#xff0c;已于本月正式启动。2024“巢燧杯”大模型创新发展大赛由通用大模型评测、行业大模型评测大赛、专项挑战赛、大模型…

JavaScript模拟滑动手势

双击回到顶部 左滑动 右滑动 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Gesture…

opencv使用KCF算法跟踪目标,给出目标中心位置

效果图 代码 import cv2class VideoTracker:def __init__(self, video_path: str):self.video_path video_pathself.cap cv2.VideoCapture(video_path)self.tracker cv2.legacy.TrackerKCF_create()self.initBB Noneself.tracker_initialized Falseself.selecting Fals…

河道高效治理新策略:视频AI智能监控如何助力河污防治

一、背景与现状 随着城市化进程的加快&#xff0c;河道污染问题日益严重&#xff0c;对生态环境和居民生活造成了严重影响。为了有效治理河道污染&#xff0c;提高河道管理的智能化水平&#xff0c;TSINGSEE青犀提出了一套河污治理视频智能分析及管理方案。方案依托先进的视频…

Android adb shell ps进程查找以及kill

Android adb shell ps进程查找以及kill 列出当前Android手机上运行的所有进程信息如PID等&#xff1a; adb shell ps 但是这样会列出一大堆进程信息&#xff0c;不便于定向查阅&#xff0c;可以使用关键词查找&#xff1a; adb shell "ps | grep 关键词" 关键词查…

SQLException:Operation not allowed after ResultSet closed

运行代码时出现的错误&#xff1a; 这是在运行简单的JDBC访问数据库时出现的问题&#xff0c;原因是在ResultSet方法中添加了close()关闭方法,如图&#xff1a; ResultSet 是通过 query 方法获得的&#xff0c;并且在 try-catch 块中没有显式地关闭它。这实际上是 一个常见的…

C++STL详解(一)——string类的接口详解(下)

目录 一.string的大小和容量成员函数 1.1size()和length() 1.2capacity() 1.3resize() 1.4reserve() 1.5clear()和empty() ​编辑 二.string元素的访问 2.1operator[]和at() 2.2范围for 三.string中迭代器相关函数 3.1begin()和end() 3.2rbegin()和rend() 四.string…

机械学习—零基础学习日志(高数12——反三角函数)

零基础为了学人工智能&#xff0c;真的开始复习高数 反三角函数很困难&#xff0c;但是当建立了逻辑链条&#xff0c;还是能快速理解的。这个办法就是笛卡尔坐标系。 三角函数与反三角函数的个人理解 sinx与cosx&#xff0c;tanx&#xff0c;secx&#xff0c;其实都可以放在…

react中简单的配置路由

1.安装react-router-dom npm install react-router-dom 2.新建文件 src下新建page文件夹&#xff0c;该文件夹下新建login和index文件夹用于存放登录页面和首页&#xff0c;再在对应文件夹下分别新建入口文件index.js&#xff1b; src下新建router文件用于存放路由配置文件…

加速下载,揭秘Internet Download Manager2024下载器的威力!

1. Internet Download Manager&#xff08;IDM&#xff09;是一款广受欢迎的下载管理软件&#xff0c;以其强大的下载加速功能和用户友好的界面著称。 IDM马丁正版下载如下: https://wm.makeding.com/iclk/?zoneid34275 idm最新绿色版一键安装包链接&#xff1a;抓紧保存以…

C++学习笔记——模板

学习视频 文章目录 模板的概念函数模板函数模板语法函数模板注意事项函数模板案例普通函数与函数模板的区别普通函数与函数模板的调用规则模板的局限性 类模板类模板与函数模板区别类模板中成员函数创建时机类模板对象做函数参数类模板与继承类模板成员函数类外实现类模板分文件…

JS基础知识学习笔记全

JS基础知识学习笔记全 一、引入方式 1、内部脚本 &#xff08;一般定义在body下面会改善执行速度&#xff09; <body></body><!-- 内部脚本 --><script>/* 打开页面警告框显示的内容 */alert(helloJS);</script>2、外部脚本 外部专门新建一…

Nginx系列-10 realIp模块使用

背景 Nginx对每个模块都有说明文档&#xff0c;可参考:https://nginx.org/en/docs/ 当请求被代理后&#xff0c;真实客户端相对服务器被隐藏&#xff0c;即服务端无法判断HTTP消息来源。 如上图所示&#xff0c;IP分别为100.100.100.1和100.100.100.2的两个客户端向服务器200.…