Loading...
首页专栏详情
打赏

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

 
1人已赏
易百纳技术社区 MacianYuan 2020-12-14 10:14:50
  • 环境: 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事件进入系统的消息循环队列。并调用预先设置的事件接受函数,处理事件。

5901
9
86
评论
0个
内容存在敏感词
打赏作者
MacianYuan
您的支持将鼓励我继续创作!
金额:
¥1 ¥5 ¥10 ¥50 ¥100
支付方式:
微信支付
支付宝支付
微信支付
打赏成功!

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

易百纳技术社区
确定要删除此文章、专栏、评论吗?
确定
取消
易百纳技术社区