day28-开发板触屏操作(2022.2.25)

简介: day28-开发板触屏操作(2022.2.25)

笔记:


书本《4.4触控屏应用接口》,了解开发板的触摸屏操作。


蜂鸣器、LCD显示屏


——》信息输出设备


触控屏:(一切皆文件)


——》信息输入设备(检测设备)



——》测试触摸屏:cat /dev/input/event0
      如果出现乱码,出现了原始数据,说明正常,


打开open、读取read、关闭close


1.触摸屏原始数据解析


输入子系统头文件:


/usr/include/linux/input.h


输入子系统编码文件:


/usr/include/linux/input-event-codes.h


输入子系统信息结构体:


struct input_event {
    struct timeval time;  // 事件发生时间戳(一般不使用)
    __u16 type;   // 事件类型
    __u16 code;   // 事件编码
    __s32 value;    // 事件数值
};


Type:


#define EV_SYN 0x00 分割标志(一类事件结束后会产生)


#define EV_KEY 0x01 按键事件(触摸屏点击事件)


#define EV_ABS 0x03 绝对位移(触摸屏坐标事件)


Code:


#define BTN_TOUCH 0x14a 触摸屏点击编码


#define ABS_X 0x00 触摸屏X轴编码


#define ABS_Y 0x01 触摸屏Y轴编码


备注:


1.黑色底板屏幕,触摸屏坐标范围是(0~1024, 0~600)



代码:


1.demo1_触摸屏输入.c


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>  // 输入子系统头文件
int main()
{
  // 1.打开
  int ts_fd = open("/dev/input/event0", O_RDONLY);
  if(ts_fd == -1)
  {
    perror("open ts failed");
    return -1;
  }
  // 2.读取(产生阻塞,等待用户点击)
  struct input_event ts_buf;
  while(1)
  {
    read(ts_fd, &ts_buf, sizeof(ts_buf));
    printf("type:0x%x code:0x%x value:%d\n", ts_buf.type, ts_buf.code, ts_buf.value);
  }
  // 3.关闭
  close(ts_fd);
  return 0;
}


2.demo2_坐标打印.c


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>  // 输入子系统头文件
int ts_fd;  //  触摸屏文件描述符全局变量
// 获取当前点击坐标
void get_xy(int *x, int *y);
int main()
{
  // 1.打开触摸屏文件
  ts_fd = open("/dev/input/event0", O_RDONLY);
  if(ts_fd == -1)
  {
    perror("open ts failed");
    return -1;
  }
  // 2.读取坐标(产生阻塞,等待用户点击)
  int pos_x, pos_y;
  while(1)
  {
    // 黑色底板屏幕,触摸屏坐标范围是(0~1024,  0~600),可通过计算进行缩小
    get_xy(&pos_x, &pos_y);
    printf("(%d, %d)\n", pos_x, pos_y);
  }
  // 3.关闭触摸屏
  close(ts_fd);
  return 0;
}
// 获取当前点击坐标
void get_xy(int *x, int *y)
{
  int x_ready=0, y_ready=0;
  struct input_event ts_buf;
  while(1)
  {
    read(ts_fd, &ts_buf, sizeof(ts_buf));
    // printf("type:0x%x code:0x%x value:%d\n", ts_buf.type, ts_buf.code, ts_buf.value);
    // if(ts_buf.type==0x3 && ts_buf.code==0x0)
    if(ts_buf.type==EV_ABS && ts_buf.code==ABS_X)
    {
      *x = ts_buf.value;
      x_ready = 1;
      y_ready = 0;  // 确保x坐标获取在前
    }
    else if(ts_buf.type==EV_ABS && ts_buf.code==ABS_Y)
    {
      *y = ts_buf.value;
      y_ready = 1;
    }
    if(x_ready==1 && y_ready==1)
      break;
  }
}


项目1


head.h


#ifndef __HEAD_H
#define __HEAD_H
// 头文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h>  // 输入子系统头文件
// 打开LCD设备并初始化显存
extern int open_lcd(void);
// 关闭LCD设备
extern void close_lcd(void);
// 显示色块
extern void show_color(int x_start, int y_start, int w, int h, int color);
// 打开触摸屏文件
extern int open_ts(void);
// 关闭触摸屏
extern void close_ts(void);
// 获取当前点击坐标
extern void get_xy(int *x, int *y);
#endif


lcd.c


#include "head.h"
static int *FB; // 显存首地址(内部链接类型)
static int lcd_fd;  // LCD文件描述符
// 打开LCD设备并初始化显存
int open_lcd(void)
{
  // 1.   打开冰箱门   ——》打开屏幕设备文件
  lcd_fd = open("/dev/fb0", O_RDWR);
  if(lcd_fd == -1)
  {
    perror("open lcd failed");
    return -1;
  }
    // 显存映射(int *类型表示操作对象是像素点)
  FB = mmap(  NULL,   // 填NULL表示显存地址由系统自动分配
        800*480*4,  // 整块屏幕的显存大小
        PROT_READ|PROT_WRITE,   // 显存保护权限:可读可写
        MAP_SHARED,     // 多进程共享设置
        lcd_fd,     // LCD文件描述符
        0);         // 0表示不偏移
  if(FB == MAP_FAILED)
  {
    perror("mmap failed");
    return -2;
  }
  return 0;
}
// 关闭LCD设备
void close_lcd(void)
{
  close(lcd_fd);
}
// 显示色块
void show_color(int x_start, int y_start, int w, int h, int color)
{
  int x, y;
  for(y=y_start; y<y_start+h; y++)
    for(x=x_start; x<x_start+w; x++)
      *(FB+x+800*y) = color;
}


main.c


#include "head.h"
int main()
{
  open_lcd();   // 打开并初始化LCD
  open_ts();    // 打开触摸屏
  // 全屏刷白
  show_color(0, 0, 800, 480, 0xFFFFFF);
  int pos_x, pos_y;
  while(1)
  {
    get_xy(&pos_x, &pos_y);
    printf("(%d,%d)\n", pos_x, pos_y);
    if(pos_x>=0 && pos_x<400)
      show_color(0, 0, 800, 480, 0xFFFFFF);
    else if(pos_x>=400 && pos_x<=800)
      show_color(0, 0, 800, 480, 0xFF0000);
  }
  close_ts();   // 关闭触摸屏
  close_lcd();  // 关闭LCD
  return 0;
}


ts.c


#include "head.h"
static int ts_fd; //  触摸屏文件描述符全局变量
// 打开触摸屏文件
int open_ts(void)
{
  ts_fd = open("/dev/input/event0", O_RDONLY);
  if(ts_fd == -1)
  {
    perror("open ts failed");
    return -1;
  }
  return 0;
}
// 关闭触摸屏
void close_ts(void)
{
  close(ts_fd);
}
// 获取当前点击坐标
void get_xy(int *x, int *y)
{
  int x_ready=0, y_ready=0;
  struct input_event ts_buf;
  while(1)
  {
    read(ts_fd, &ts_buf, sizeof(ts_buf));
    // printf("type:0x%x code:0x%x value:%d\n", ts_buf.type, ts_buf.code, ts_buf.value);
    // if(ts_buf.type==0x3 && ts_buf.code==0x0)
    if(ts_buf.type==EV_ABS && ts_buf.code==ABS_X)
    {
      *x = ts_buf.value;
      x_ready = 1;
      y_ready = 0;  // 确保x坐标获取在前
    }
    else if(ts_buf.type==EV_ABS && ts_buf.code==ABS_Y)
    {
      *y = ts_buf.value;
      y_ready = 1;
    }
    if(x_ready==1 && y_ready==1)
      break;
  }
}


相关文章
arduino环境基于wemos串口调试小助手控制小车前后左右烧写源码
arduino环境基于wemos串口调试小助手控制小车前后左右烧写源码
97 0
arduino环境基于wemos串口调试小助手控制小车前后左右烧写源码
|
12天前
|
Linux
GEC6818开发板触摸屏---点击屏幕获取触摸屏坐标
GEC6818开发板触摸屏---点击屏幕获取触摸屏坐标
|
8月前
STM32 触摸屏移植GUI控制控件
STM32 触摸屏移植GUI控制控件
STM32 触摸屏移植GUI控制控件
|
7月前
|
移动开发 小程序 Android开发
|
Windows
【电脑控制手机屏幕】windows11、10自带投屏功能,三步解决
想用电脑控制手机,但是下载第三方软件好麻烦,只需三步骤即可使用windows系统自带投屏插件实现投屏功能
1112 0
|
Linux
ARM6818开发板输入设备(触摸屏)操作(开发五子棋游戏)
ARM6818开发板输入设备(触摸屏)操作(开发五子棋游戏)
340 0
|
图形学
unity3d 中控制手机前后摄像头切换
闲话少说,上代码,google上搜来的代码,不过里面有bug,不能顺利切换,下面的代码是已经修改过的,经测试,可以正常运行。 using System;using UnityEngine;using System.
1286 0
|
C#
C#串口控制舵机、arduino源码 及C#源码及界面
原文 C#串口控制舵机、arduino源码 及C#源码及界面 1.舵机原理简介         控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。
2504 0