【海思HI3520之QT开发】-文件操作实战(二):设备文件操作实现红外键盘

MacianYuan 2020-08-30 00:41:53 10129
  • 环境: Ubuntu 12.04-64bit
  • 硬件平台: Hi3520D_V100
  • 内核版本: linux-3.0.y
  • Qt版本: qt4.8.6
  • 编译器: arm-hisiv100nptl-linux-gcc
  • 作者: MacianYuan
  • 原文链接: https://www.ebaina.com/articles/140000004391

摘要: 介绍打开文件,读写文件的方法,以及利用操作文件完成红外键盘的实现。涉及其他操作设备文件的应用都可以借用此办法快速实现应用开发。
网上很多Qt文本打开关闭读写的例子,但是那种方法是不能即时拿到红外按键的数据的,如果需要利用QSocketNotifier即时拿到数据需要利用监听系统文件操作,将操作转换为Qt事件进入系统的消息循环队列。

第一节:加载红外解码驱动

编译SDK中 /drv/hisi-irda/ 驱动代码 生成hi_ir.ko 驱动模块,拷贝到开发板中, insmod 加载驱动模块。
在板载文件系统中dev目录下看到Hi_IR 设备文件。

第二节:C++操作红外解码设备文件
1、红外键盘解码初始化
int IrdaAnalysis::irda_init()
{
    const char *device = "/dev/Hi_IR";
    int fd = 0;
    fd = ::open(device, O_RDWR|O_NONBLOCK);
    if(fd < 0)
        return -1;
    return fd;
}
2、红外键盘编码配置 NEC with full repeat code
static hiir_dev_param static_dev_param[] =
{
    /*NEC with simple repeat code : uPD6121G*/
    {828, 972, 414, 486, 45, 67 , 135, 203, 180, 270, 32, 0, HIIR_DEFAULT_FREQ},
    //{728, 1050, 350, 550, 25, 75, 100, 250, 150, 300, 32, 0, HIIR_DEFAULT_FREQ},

    /*NEC with simple repeat code : D6121/BU5777/D1913*/
    {828, 972, 414, 486, 45, 67 , 135, 203, 207, 243, 32, 0, HIIR_DEFAULT_FREQ},

    /*NEC with simple repeat code : LC7461M-C13*/
    {828, 972, 414, 486, 45, 67 , 135, 203, 207, 243, 42, 0, HIIR_DEFAULT_FREQ},

    /*NEC with simple repeat code : AEHA*/
    {270, 405, 135, 203, 34, 51 , 101, 152, 270, 405, 48, 0, HIIR_DEFAULT_FREQ},

    /*TC9012 : TC9012F/9243*/
    {414, 486, 414, 486, 45, 67 , 135, 203, 0  , 0  , 32, 1, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : uPD6121G*/
    {828, 972, 414, 486, 45, 67 , 135, 203, 0  , 0  , 32, 2, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : LC7461M-C13*/
    {828, 972, 414, 486, 45, 67 , 135, 203, 0  , 0  , 42, 2, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : MN6024-C5D6*/
    {270, 405, 270, 405, 68, 101, 203, 304, 0  , 0  , 22, 2, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : MN6014-C6D6*/
    {279, 419, 279, 419, 70, 105, 140, 210, 0  , 0  , 24, 2, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : MATNEW*/
    {279, 419, 300, 449, 35, 52 , 105, 157, 0  , 0  , 48, 2, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : MN6030*/
    {279, 419, 279, 419, 70, 105, 210, 314, 0  , 0  , 22, 2, HIIR_DEFAULT_FREQ},

    /*NEC with full repeat code : PANASONIC*/
    {282, 422, 282, 422, 70, 106, 211, 317, 0  , 0  , 22, 2, HIIR_DEFAULT_FREQ},

    /*SONY-D7C5*/
    {192, 288, 48 , 72 , 48, 72 , 96 , 144, 0  , 0  , 12, 3, HIIR_DEFAULT_FREQ},

    /*SONY-D7C6*/
    {192, 288, 48 , 72 , 48, 72 , 96 , 144, 0  , 0  , 13, 3, HIIR_DEFAULT_FREQ},

    /*SONY-D7C8*/
    {192, 288, 48 , 72 , 48, 72 , 96 , 144, 0  , 0  , 15, 3, HIIR_DEFAULT_FREQ},

    /*SONY-D7C13*/
    {192, 288, 48 , 72 , 48, 72 , 96 , 144, 0  , 0  , 20,  3, HIIR_DEFAULT_FREQ},
};

inline void IrdaAnalysis::ir_config_fun(int filp, hiir_dev_param dev_param)
{
    int tmp[2];

    ioctl(filp, IR_IOC_SET_CODELEN, dev_param.code_len);

    ioctl(filp, IR_IOC_SET_FORMAT, dev_param.codetype);

    ioctl(filp, IR_IOC_SET_FREQ, dev_param.frequence);

    tmp[0] = dev_param.leads_min;
    tmp[1] = dev_param.leads_max;
    ioctl(filp, IR_IOC_SET_LEADS, tmp);

    tmp[0] = dev_param.leade_min;
    tmp[1] = dev_param.leade_max;
    ioctl(filp, IR_IOC_SET_LEADE, tmp);

    tmp[0] = dev_param.sleade_min;
    tmp[1] = dev_param.sleade_max;
    ioctl(filp, IR_IOC_SET_SLEADE, tmp);

    tmp[0] = dev_param.cnt0_b_min;
    tmp[1] = dev_param.cnt0_b_max;
    ioctl(filp, IR_IOC_SET_CNT0_B, tmp);

    tmp[0] = dev_param.cnt1_b_min;
    tmp[1] = dev_param.cnt1_b_max;
    ioctl(filp, IR_IOC_SET_CNT1_B, tmp);
}
3、重要!!!!

监听系统文件操作,将操作转换为Qt事件进入系统的消息循环队列。并调用预先设置的事件接受函数,处理事件

    m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
    connect (m_notifier, SIGNAL(activated(int)), this, SLOT(on_irda_read()));
第三节 数据接收和解析

1、由上面的文件监听可以on_irda_read触发槽函数,此时在on_irda_read对编码进行解析即可识别具体按键。

void IrdaAnalysis::on_irda_read()
{
      unsigned int res = 0;
      irkey_info_s rcv_irkey_info;
      //printf("random press  keys...\n");

      res = read(m_fd, &rcv_irkey_info, sizeof(rcv_irkey_info));
      if( (res > 0) && (res <= sizeof(rcv_irkey_info)) ){
          normal_report_irkey(rcv_irkey_info);
      }
      else{
          printf("Hi_IR_FUNC_TEST_007 Error. read irkey device error. res=%d.\n", res);
      }
}

2、简单列举几个按键编码解析 通过信号槽 链接到其他类中实现控制

#define MENU_KEY    0xe619ff00
#define UP_KEY      0xea15ff00
#define DOWN_KEY    0xe718ff00
#define LEFT_KEY    0xe916ff00
#define RIGHT_KEY   0xf20dff00

void IrdaAnalysis::normal_report_irkey(irkey_info_s rcv_irkey_info)
{
    //printf("RECEIVE ---> irkey_datah=0x%.8x, irkey_datal=0x%.8x\t", (int)(rcv_irkey_info.irkey_datah), (int)(rcv_irkey_info.irkey_datal));
    if(rcv_irkey_info.irkey_datal == MENU_KEY){
         printf("KEYUP...MENU_KEY");
         emit menushowSelect();

    }else if(rcv_irkey_info.irkey_datal == UP_KEY){
         printf("KEYUP...UP_KEY");
         emit stackedshowSelect(true);

    }else if(rcv_irkey_info.irkey_datal == DOWN_KEY){
         printf("KEYUP...DOWN_KEY");
         emit stackedshowSelect(false);

    }else if(rcv_irkey_info.irkey_datal == LEFT_KEY){
         emit stream_change(true);
         printf("KEYUP...LEFT_KEY");
    }else if(rcv_irkey_info.irkey_datal == RIGHT_KEY){
         emit stream_change(false);
         printf("KEYUP...RIGHT_KEY");
    }

    if(rcv_irkey_info.irkey_state_code == 1){
        printf("KEYUP...");
    }
    printf("\n");
}

使用类似红外解码类似的驱动,涉及操作设备文件对文件进行监听的应用都可以借用此方法。将操作转换为Qt事件进入系统的消息循环队列。并调用预先设置的事件接受函数,处理事件。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 86 9 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
MacianYuan
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区