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

用C++写了基于gec6818开发板上LCD操作的一个类--附带注释(详细)

 

目录

一、效果演示

 二、代码

三、开发板的介绍


这是我制作了象棋游戏这个项目后,自己花了几个小时重新写的一个类,仅供参考。

一、效果演示

1.清屏

 

2.等待获取坐标

3.指定位置映射了一个棋子 

 

4.抠取原底图并指定位置让它覆盖棋子,实现复原效果

 

5.进度条是动态的,这里以图片代替 

 二、代码

1.Lcd.cpp

#include "Lcd.h"


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 数据的初始化                                   *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        无                                            *
*******************************************************/
Lcd::Lcd(void)
{
    //变量初始化
    w = 0;
    h = 0;
    pix = 0; 
    fd = 0; 
    touch_screen_fd = 0;
    one_x = 0;
    one_y = 0;
    tow_x = 0;
    tow_y = 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 打开lcd屏幕                                    *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::open_lcd(void)
{
    //打开lcd设备
    this->fd = open("/dev/fb0", O_RDWR);
    if (this->fd < 0)
    {
        return -1;
    }
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 关闭lcd屏幕                                    *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::close_lcd(void)
{
    //关闭lcd设备
    int fd_close = close(this->fd);
    if (fd_close < 0)
    {
        return -1;
    }
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 申请lcd屏幕映射                                *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::apply_for(void)
{
    //获取lcd参数
    struct fb_var_screeninfo vinfo;
    int ret = ioctl(this->fd, FBIOGET_VSCREENINFO, &vinfo);
    w = vinfo.xres;
    h = vinfo.yres;
    pix = vinfo.bits_per_pixel / 8;

    //映射
    int ssize = w * h * pix;
    mptr = (unsigned int*)mmap(NULL, ssize, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0);
    if (mptr == MAP_FAILED)
    {
        return -1;
    }
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 销毁lcd屏幕映射                                *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        无                                            *
*******************************************************/
void Lcd::destruction_apply_for(void)
{
    if (mptr != MAP_FAILED)
    {
        int ssize = w * h * pix;
        munmap(mptr, ssize);
    }
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 清屏                                           *
*------------------------------------------------------*
* 参  数:                                              *
*        color  要显示的颜色                           *
* 返回值:                                              *
*        无                                            *
*******************************************************/
void Lcd::clear(unsigned int color) 
{
    for (int i = 0; i < w * h; i++)
    {
        mptr[i] = color;
    }
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 在lcd上显示800*480的图片                       *
*------------------------------------------------------*
* 参  数:                                              *
*        pathname   图片的存放路径                     *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::show_bmp(const char* pathname)
{
    int width, high; //图片亮度与高度
    int i, j, x, y;
    // 读取BMP格式头,获取图片信息
    struct bitmap_header header;
    struct bitmap_info info;
    struct rgb_quad quad;

    //打开图片,获取图片描述符
    int bmp_fd = open(pathname, O_RDONLY);
    if (bmp_fd == -1)
    {
        return -1;
    }
    // 第一、二个结构体是必有信息
    read(bmp_fd, &header, sizeof(header));
    read(bmp_fd, &info, sizeof(info));

    //获取打开图片的大小
    width = info.width;
    high = info.height;

    if (width > 800 || high > 480)
    {
        close(bmp_fd);
        return -1;
    }

    //变长数组
    unsigned char bmpbuff[width * high * 3];
    unsigned int buff[width * high];
    unsigned int tmpbuff[width * high];

    read(bmp_fd, bmpbuff, sizeof(bmpbuff));

    //图片像素点移动
    for (i = 0; i < width * high; i++)
    {
        buff[i] = bmpbuff[3 * i + 0] | bmpbuff[3 * i + 1] << 8 | bmpbuff[3 * i + 2] << 16;
    }

    //图片像素点倒置
    for (y = 0; y < high; y++)
    {
        for (x = 0; x < width; x++)
        {
            tmpbuff[(high - 1 - y) * width + x] = buff[y * width + x];
        }
    }

    //图片像素显示
    for (y = 0; y < high; y++)
    {
        for (x = 0; x < width; x++)
        {
            //遇到白色就跳过,不绘画,可将0xffffff修改成不需要的颜色
            /*if (tmpbuff[y * width + x] == 0x00ffffff)
            {
                continue;
            }*/
            *(mptr + (y* 800) + x) = tmpbuff[y * width + x];

        }
    }

    //关闭LCD文件
    close(bmp_fd);
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 在lcd上显示指定起点位置的图片                  *
*------------------------------------------------------*
* 参  数:                                              *
*        pathname   图片的存放路径                     *
*        start_x    绘画起点的x轴                      *
*        start_y    绘画起点的y轴                      *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::specified_show_bmp(const char* pathname, int start_x, int start_y)
{
    int width, high; //图片亮度与高度
    int i, j, x, y;
    // 读取BMP格式头,获取图片信息
    struct bitmap_header header;
    struct bitmap_info info;
    struct rgb_quad quad;

    //打开图片,获取图片描述符
    int bmp_fd = open(pathname, O_RDONLY);
    if (bmp_fd == -1)
    {
        return -1;
    }
    // 第一、二个结构体是必有信息
    read(bmp_fd, &header, sizeof(header));
    read(bmp_fd, &info, sizeof(info));

    //获取打开图片的大小
    width = info.width;
    high = info.height;

    if (start_x + width > 800 || start_y + high > 480)
    {
        close(bmp_fd);
        return -1;
    }

    //变长数组
    unsigned char bmpbuff[width * high * 3];
    unsigned int buff[width * high];
    unsigned int tmpbuff[width * high];

    read(bmp_fd, bmpbuff, sizeof(bmpbuff));

    //图片像素点移动
    for (i = 0; i < width * high; i++)
    {
        buff[i] = bmpbuff[3 * i + 0] | bmpbuff[3 * i + 1] << 8 | bmpbuff[3 * i + 2] << 16;
    }

    //图片像素点倒置
    for (y = 0; y < high; y++)
    {
        for (x = 0; x < width; x++)
        {
            tmpbuff[(high - 1 - y) * width + x] = buff[y * width + x];
        }
    }

    //图片像素显示
    for (y = 0; y < high; y++)
    {
        for (x = 0; x < width; x++)
        {
            //遇到白色就跳过,不绘画,可将0xffffff修改成不需要的颜色
            /*if (tmpbuff[y * width + x] == 0x00ffffff)
            {
                continue;
            }*/
            *(mptr + ((start_y + y) * 800)+ start_x + x) = tmpbuff[y * width + x];

        }
    }

    //关闭LCD文件
    close(bmp_fd);
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 扣取指定区域像素并在lcd上指定起点显示          *
*------------------------------------------------------*
* 参  数:                                              *
*        pathname   图片的存放路径                     *
*        hui_x      指定扣取起点的x轴                  *
*        hui_y      指定扣取起点的y轴                  *
*        hui_w      扣取的宽度                         *
*        hui_h      扣取的高度                         *
*        start_x    绘画起点的x轴                      *
*        start_y    绘画起点的y轴                      *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::specified_cutout_show_bmp(const char* pathname,int hui_x,int hui_y, int hui_w,int hui_h,int start_x,int start_y)
{
    int width, high; //图片亮度与高度
    int i, j, x, y;

    // 读取BMP格式头,获取图片信息
    struct bitmap_header header;
    struct bitmap_info info;
    struct rgb_quad quad;

    //打开图片,获取图片描述符
    int bmp_fd = open(pathname, O_RDONLY);
    if (bmp_fd == -1)
    {
        return -1;
    }
    // 第一、二个结构体是必有信息
    read(bmp_fd, &header, sizeof(header));
    read(bmp_fd, &info, sizeof(info));

    //获取打开图片的大小
    width = info.width;
    high = info.height;

    if (width > 800 || high > 480)
    {
        close(bmp_fd);
        return -1;
    }

    //变长数组
    unsigned char bmpbuff[width * high * 3];
    unsigned int buff[width * high];
    unsigned int tmpbuff[width * high];

    read(bmp_fd, bmpbuff, sizeof(bmpbuff));

    //图片像素点移动
    for (i = 0; i < width * high; i++)
    {
        buff[i] = bmpbuff[3 * i + 0] | bmpbuff[3 * i + 1] << 8 | bmpbuff[3 * i + 2] << 16;
    }

    //图片像素点倒置
    for (y = 0; y < high; y++)
    {
        for (x = 0; x < width; x++)
        {
            tmpbuff[(high - 1 - y) * width + x] = buff[y * width + x];
        }
    }

    //图片像素显示
    for (y = 0; y < hui_h; y++)
    {
        for (x =  0; x < hui_w; x++)
        {
            //遇到白色就跳过,不绘画,可将0xffffff修改成不需要的颜色
            /*if (tmpbuff[(hui_y + y) * 800 + hui_x + x] == 0x00ffffff)
            {
                continue;
            }*/
            *(mptr +  (start_y+ y) * 800 + start_x+ x) = tmpbuff[(hui_y + y) * 800 + hui_x + x];

        }
    }

    //关闭LCD文件
    close(bmp_fd);
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 打开触摸屏并获取点击和松开的坐标               *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::open_touch_screen(void)
{
    //定义一个结构体变量
    struct input_event ts;

    //打开触摸屏
    touch_screen_fd = open("/dev/input/event0", O_RDWR);
    if (touch_screen_fd < 0)
    {
        return -1;
    }
    
    //清空
    memset(&ts, 0, sizeof(struct input_event));

    while (1)
    {
        //读取触摸屏
        read(touch_screen_fd, &ts, sizeof(struct input_event));

        //决断是否为相对坐标类型
        if (ts.type == EV_ABS && ts.code == ABS_X)
        {
            tow_x = ts.value;
        }
        //决断是否为相对坐标类型
        if (ts.type == EV_ABS && ts.code == ABS_Y)
        {
            tow_y = ts.value;
        }
        //表示手指按下
        if (ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == 1)
        {
            //记录起点坐标
            one_x = tow_x;
            one_y = tow_y;
        }

        //表示手指松开
        if (ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == 0)
        {
            //坐标换算  起点坐标
            one_x = one_x * (800.0 / 1024.0);
            one_y = one_y * (480.0 / 600.0);
            //坐标换算  结束坐标
            tow_x = tow_x * (800.0 / 1024.0);
            tow_y = tow_y * (480.0 / 600.0);

            return 0;
        }
    }
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 关闭触摸屏                                     *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        成功:0   失败:-1                              *
*******************************************************/
int Lcd::close_touch_screen(void)
{
    int close_touch_screen_fd = close(touch_screen_fd);
    if (close_touch_screen_fd < 0)
    {
        return -1;
    }
    return 0;
}


/*******************************************************
*                       函数介绍                       *
*------------------------------------------------------*
* 功能: 进度条                                         *
*------------------------------------------------------*
* 参  数:                                              *
*        无                                            *
* 返回值:                                              *
*        无                                            *
*******************************************************/
void Lcd::progress_bar(void)
{
    int x, y;
    for (y = 450; y < 465; y++)
    {
        for (x = 50; x < 750; x++)
        {
            mptr[y * 800 + x] = 0x007f7f7f;
        }
    }

    for (x = 50; x < 750; x++)
    {
        for (y = 450; y < 465; y++)
        {
            mptr[y * 800 + x] = 0x003300FF;
        }
        usleep(300);
    }
}

2.Lcd.h

#pragma once

#include <cstring>
#include <iostream>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/input.h>

using namespace std;

// BMP格式头规范
struct bitmap_header
{
	int16_t type;
	int32_t size; // 图像文件大小
	int16_t reserved1;
	int16_t reserved2;
	int32_t offbits; // bmp图像数据偏移量
}__attribute__((packed));

struct bitmap_info
{
	int32_t size;   // 本结构大小	
	int32_t width;  // 图像宽
	int32_t height; // 图像高
	int16_t planes;

	int16_t bit_count; // 色深
	int32_t compression;
	int32_t size_img; // bmp数据大小,必须是4的整数倍
	int32_t X_pel;
	int32_t Y_pel;
	int32_t clrused;
	int32_t clrImportant;
}__attribute__((packed));

struct rgb_quad
{
	int8_t blue;
	int8_t green;
	int8_t red;
	int8_t reserved;
}__attribute__((packed));

class Lcd
{
public:
	//存放触摸屏坐标
	int one_x, one_y, tow_x, tow_y;

	//数据初始
	Lcd();
	//打开lcd
	int open_lcd(void);
	//申请映射
	int apply_for(void);
	//关闭lcd
	int close_lcd(void);
	//销毁映射
	void destruction_apply_for(void);
	//清屏
	void clear(unsigned int color);
	//打开触摸屏
	int open_touch_screen(void);
	//关闭触摸屏
	int close_touch_screen(void);
	//进度条
	void progress_bar(void);
	//映射800*480图片
	int show_bmp(const char* pathname);
	//指定位置映射图片
	int specified_show_bmp(const char* pathname, int start_x, int start_y);
	//指定位置映射指定扣取的图片
	int specified_cutout_show_bmp(const char* pathname, int hui_x, int hui_y, int hui_w, int hui_h, int start_x, int start_y);
	~Lcd(){ }
private:
	//私有变量
	int fd, touch_screen_fd, h, w, pix;
	unsigned int* mptr;
};

3.main.cpp

#include "Lcd.h"

int main(void)
{
	//定义类变量
	Lcd lcd;

	//打开lcd和映射
	lcd.open_lcd();
	lcd.apply_for();
	
	//清屏
	lcd.clear(0xEB3324);
	sleep(2);

	//打开触摸屏并获取坐标
	lcd.open_touch_screen();
	cout << "按下的坐标:" << lcd.one_x << "  " << lcd.one_y << endl;
	cout << "松开的坐标:" << lcd.tow_x << "  " << lcd.tow_y << endl;

	//映射800*480图片
	lcd.show_bmp("/root/C++/photo/jiemian.bmp");
	sleep(2);

	//指定位置映射图片
	lcd.specified_show_bmp("/root/C++/photo/10.bmp", 100, 100);
	sleep(2);

	//指定位置映射指定扣取的图片
	lcd.specified_cutout_show_bmp("/root/C++/photo/jiemian.bmp", 100,100,48,48,100, 100);
	sleep(2);

	//进度条
	lcd.show_bmp("/root/C++/photo/jiazai0.bmp");
	lcd.progress_bar();

	//关闭lcd
	lcd.close_lcd();
	//销毁映射
	lcd.destruction_apply_for();
	//关闭触摸屏
	lcd.close_touch_screen();

	while (1);

	return 0;
}

三、开发板的介绍

GEC6818 开发平台,核心板采用 10 层板工艺设计,确保稳定可靠,可以批量用于平板电脑,车机,学 习机,POS 机,游戏机,行业监控等多种领域。该平台搭载三星 Cortex-A53 系列高性能八核处理器 S5P6818, 最高主频高达 1.4GHz,可应用于嵌入式 Linux 和 Android 等操作系统的驱动、应用开发。开发板留有丰富 的外设,支持千兆以太网、板载 LVDS 接口、MIPI 接口、USB 接口等。

 

GEC6818 开发平台采用的是三星 64 位八核 Cortex-A53 架构的 S5P6818 芯片,下面是芯片主要参数:

型号

S5P6818

上市时间

2014 年

工艺制程

28nm

CPU 主频

1.4G+

封装尺寸

0.65mm 引脚间距,17*17mm2

513-FCBGA 封装

CPU 架构

Cortex-A53 八核

缓存容量

32KB*4 I/D 缓存

1MB 二级缓存

DDR3 接口

单通道 32 位数据总线

高达800MHz 工作频率

多媒体解码

H.263,H.264,MPEG1,MPEG2

MEG4,VC1,VP8,Theora,AVS

RV8/9/10,MJPEG(几乎全格式)

多媒体编码

H.263,H.264

MPEG4,MJPEG

显示接口

RGB,MIPI,LVDS

最大显示分辨率

2048*1280

以太网接口

集成千兆以太网控制器

GPIO 电平

3.3V

ADC

8 路 12 bit 0~1.8V

USB 接口

1 路 HOST

1 路 HSIC

1 路 OTG

芯片 ID

支持 128BIT 唯一 ID 号

  • 常用接口说明

1.电源接口

        开发平台总电源接口为 CN1,对应的电源适配器的输出电压为直流5V。

2.调试串口 

        开发平台默认使用 UART0 作为调试串口,UART0 为标准 DB9 接口。你可以通过附带的交叉串口线和 PC 进行通讯。

3.USB-OTG接口

        该接口用于程序烧写,同步等。它还能通过 OTG 线实现 HOST 的功能。

4.以太网接口

        开发平台支持千兆有线以太网接口,板载RTL8211E

5.音频接口

         一个 3.5mm 音频输入接口(红色),一个 3.5mm 输出接口(绿色),可直接接耳机,用于音频的播放和录制。

6.LCD接口

        开发平台底板默认留有一个 40PIN 的 LCD 接口(底板背部位置),通过软排线将 RGB 相关信号连接 到 LCD 控制板上,进而控制 LCD 和显示。

 

相关文章:

  • 如何管理测试用例?测试用例有什么管理工具?YesDev
  • 【科研】如何回复审稿意见(SCI)常识及案例
  • 数据库设计大题详解
  • 数据分析案例-印度美食数据可视化分析
  • pytorch-1-4 张量的基础知识和运算
  • PDF 生成目录和页码 点击跳转(新)
  • 绕过5秒盾Cloudflare和DDoS-GUARD
  • R 贝叶斯输出分析和诊断MCMC:coda包
  • 019 Spring Boot+Vue 电影院会员管理系统(源代码+数据库+文档)
  • 论文阅读-CheckFreq:频繁、精细的DNN检查点操作。
  • uniapp的扩展组件uni-popup 弹出层自动打开
  • Qt中的QGraphicView和QGraphicScene简单使用
  • 3、spring cloud 五大组件
  • Redis_在Windows上启动多个Redis服务端
  • 项目启动端口被占用 -- Web server failed to start. Port 8082 was already in use.
  • 做运营如何蹭热点?
  • JAVA反序列化学习笔记
  • 小程序-网络数据请求
  • Vue中KeepAlive 原理与源码分析
  • 蛇形矩阵(模拟)
  • SpringMVC---->自我实现底层机制(吃透springMVC)
  • 计算机毕业设计(附源码)python医疗健康查询系统
  • 找个好用的录屏软件,怎么这么难?
  • 【Node.js】模块的加载机制
  • JavaScript大作业 基于HTML+CSS+JavaScript站酷静态页面官网7页
  • 助力汽修企业突破转型瓶颈,S2B2B商城价格管理模块实现采购交易数字化升级
  • Python作业十一:螺旋矩阵与正方形二维列表
  • 【前端】CSS(3) —— CSS的盒模型与弹性布局
  • 2022高频经典前端面试题(vue2+vue3+typescript+nodejs下篇,含答案)
  • springboot整合flink(二)
  • Oracle和MySQL查询所有的表信息和字段信息
  • Java中的File类的构造方法介绍使用、绝对路径和相对路径、File类的创建功能详细描述使用(上篇)