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

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 显示效果

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 初阶数据结构之栈和队列
  • huawei 路由 RIP 协议中三种定时器的工作原理
  • 快手可灵视频生成大模型全方位测评
  • CrowdStrike更新致850万Windows设备宕机,微软紧急救火!
  • JAVA学习笔记
  • QT--进程
  • qt初入门9:qt记录日志的方式,日志库了解练习(qInstallMessageHandler,qslog, log4qt)
  • 【Python】文本对齐方式
  • 大模型技术:发展历程、经典模型、微调与应用[更新中...]
  • Kafka之存储设计
  • 2024最新手机软件APP下载排行网站源码 软件下载站PHP源码
  • 每日一题~960 div2 A+B+C(简单奇偶博弈,构造,观察性质算贡献)
  • robotframework语法易错点总结(更新中...)
  • 代码审计 | .NET SqlSugar框架注入漏洞
  • Java 哈希表
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • angular2开源库收集
  • express + mock 让前后台并行开发
  • JavaScript 奇技淫巧
  • Javascript 原型链
  • JavaScript学习总结——原型
  • Js基础——数据类型之Null和Undefined
  • PaddlePaddle-GitHub的正确打开姿势
  • SpingCloudBus整合RabbitMQ
  • Terraform入门 - 3. 变更基础设施
  • 百度地图API标注+时间轴组件
  • 翻译--Thinking in React
  • 缓存与缓冲
  • 力扣(LeetCode)965
  • 聊聊directory traversal attack
  • 配置 PM2 实现代码自动发布
  • 浅谈Golang中select的用法
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • MPAndroidChart 教程:Y轴 YAxis
  • Spring第一个helloWorld
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • (6)STL算法之转换
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (day6) 319. 灯泡开关
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (web自动化测试+python)1
  • (阿里云万网)-域名注册购买实名流程
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (笔试题)合法字符串
  • (第一天)包装对象、作用域、创建对象
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (含笔试题)深度解析数据在内存中的存储
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (南京观海微电子)——示波器使用介绍