【驱动篇】龙芯LS2K0300之红外驱动

news2025/1/11 11:51:11

实验目标

编写HX1838红外接收器驱动,根据接收的波形脉冲解码红外按键键值

模块连接

模块连接:VCC接Pin 2,GND接Pin1,DATA接Pin16

在这里插入图片描述

驱动代码

HX1838 GPIO初始化,申请中断,注意:GPIO48默认是给i2c0使用的,使用前记得注释掉i2c0设备树节点

#define CODE_SIZE 4
#define HX1838_IO 48
#define TIME_UNIT 140
#define GPIO_VALUE gpio_get_value(HX1838_IO)

static int __init hx1838_init(void)
{
    int ret;
    int irq = gpio_to_irq(HX1838_IO);

    printk("irq : %d\n", irq);

	gpio_request(HX1838_IO, "hx1838-gpio");

    gpio_direction_input(HX1838_IO);

    ret = request_irq(irq, irq_callback, IRQF_TRIGGER_FALLING, "hx1838-irq", NULL);

    if (ret < 0)
        goto LABEL;

    return 0;

LABEL:
    gpio_free(HX1838_IO);
    return ret;
}

中断处理函数,解码格式:地址码 + 地址码反码 + 数据码 + 数据码反码,13.5ms为前导波形信号,第56行需要注意数据取反默认是32位的(需要强制转换)

typedef unsigned char uchar;

static uchar array[CODE_SIZE];

irqreturn_t irq_callback(int irqno, void *arg)
{
    unsigned char j,k,N=0;

    udelay(15 * TIME_UNIT);

    if (GPIO_VALUE == 1)
    {
        // printk("111\n");
        return IRQ_HANDLED;
    }
    
    while (!GPIO_VALUE)  
    {
        udelay(TIME_UNIT);
    }                                       
        
    for (j=0; j < 4; j++)                                          
    {
        for (k = 0; k < 8; k++)                                
        {
            while (GPIO_VALUE)                                  
            {
                udelay(TIME_UNIT);
            }

            while (!GPIO_VALUE)                                
            {
                udelay(TIME_UNIT);
            }

            while (GPIO_VALUE)                                  
            {
                udelay(TIME_UNIT);
                N++;           
                if (N >= 30)
                {
                    // printk("222\n");
                    return IRQ_HANDLED;
                }                                              
            } 
                                                                          
            array[j] = array[j] >> 1;                            
            if(N >= 8)
            {
                array[j] = array[j] | 0x80;                     
            }  
            N = 0;
        }
    }      

    if(array[2] != (unsigned char)(~array[3]))
    {
        // printk("333\n");
        return IRQ_HANDLED;
    }

    printk("%d,%d,%d,%d\n", array[0], array[1], array[2], array[3]);

    return IRQ_HANDLED;
}

完整驱动代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/gpio.h>

#define CODE_SIZE 4
#define HX1838_IO 48
#define TIME_UNIT 140
#define GPIO_VALUE gpio_get_value(HX1838_IO)

typedef unsigned char uchar;

static uchar array[CODE_SIZE];

irqreturn_t irq_callback(int irqno, void *arg)
{
    unsigned char j,k,N=0;

    udelay(15 * TIME_UNIT);

    if (GPIO_VALUE == 1)
    {
        // printk("111\n");
        return IRQ_HANDLED;
    }
    
    while (!GPIO_VALUE)  
    {
        udelay(TIME_UNIT);
    }                                       
        
    for (j=0; j < 4; j++)                                          
    {
        for (k = 0; k < 8; k++)                                
        {
            while (GPIO_VALUE)                                  
            {
                udelay(TIME_UNIT);
            }

            while (!GPIO_VALUE)                                
            {
                udelay(TIME_UNIT);
            }

            while (GPIO_VALUE)                                  
            {
                udelay(TIME_UNIT);
                N++;           
                if (N >= 30)
                {
                    // printk("222\n");
                    return IRQ_HANDLED;
                }                                              
            } 
                                                                          
            array[j] = array[j] >> 1;                            
            if(N >= 8)
            {
                array[j] = array[j] | 0x80;                     
            }  
            N = 0;
        }
    }      

    if(array[2] != (unsigned char)(~array[3]))
    {
        // printk("333\n");
        return IRQ_HANDLED;
    }

    printk("%d,%d,%d,%d\n", array[0], array[1], array[2], array[3]);

    return IRQ_HANDLED;
}

static int __init hx1838_init(void)
{
    int ret;
    int irq = gpio_to_irq(HX1838_IO);

    printk("irq : %d\n", irq);

	gpio_request(HX1838_IO, "hx1838-gpio");

    gpio_direction_input(HX1838_IO);

    ret = request_irq(irq, irq_callback, IRQF_TRIGGER_FALLING, "hx1838-irq", NULL);

    if (ret < 0)
        goto LABEL;

    return 0;

LABEL:
    gpio_free(HX1838_IO);
    return ret;
}


static void __exit hx1838_exit(void)
{
    free_irq(gpio_to_irq(HX1838_IO), NULL);
    gpio_free(HX1838_IO);
}

module_init(hx1838_init);
module_exit(hx1838_exit);

MODULE_LICENSE("GPL");

Makefile文件

obj-m += irda.o 
KDIR:=/home/asensing/loongson/linux-4.19
ARCH=loongarch 
CROSS_COMPILE=loongarch64-linux-gnu-
PWD?=$(shell pwd) 
all:
	make -C $(KDIR) M=$(PWD) modules 

构建脚本

export PATH=$PATH:/home/asensing/loongson/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3-1/bin
make -j8
# loongarch64-linux-gnu-gcc test.c -o test
FILE=$PWD/$(basename $PWD).ko
scp $FILE root@192.168.137.232:/home/root

实验效果

装载驱动模块,然后在红外遥控器下按下按键,可以看到打印的红外解码数据:地址及其反码,数据及其反码

在这里插入图片描述

参考

本次代码根据51单片机程序移植:HX1838红外无线遥控模块51单片机程序 - 51单片机 (51hei.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1886830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot 中 PGSQL 判断打卡点是否经过轨迹优化代码,循环查询物理表修改生成临时表,向临时表插入数据后再做ST_DWithin判断

记录一下一个业务问题&#xff0c;流程是这样的&#xff0c;我现在有一个定时任务&#xff0c;5分钟执行一次&#xff0c;更新车辆打卡的情况。现在有20俩车&#xff0c;每辆车都分配了路线&#xff0c;每条路线都有打卡点&#xff0c;每个打卡点分配了不同的时间段&#xff0c…

【动态规划 前缀和】2478. 完美分割的方案数

本文涉及知识点 划分型dp 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode 2478. 完美分割的方案数 给你一个字符串 s &#xff0c;每个字符是数字 ‘1’ 到 ‘9’ &#xff0c;再给你两个整数 k 和 minLength 。 如…

Redis---保证主从节点一致性问题 +与数据库数据保持一致性问题

保证主从节点一致性问题 Redis的同步方式默认是异步的&#xff0c;这种异步的同步方式导致了主从之间的数据存在一定的延迟&#xff0c;因此Redis默认是弱一致性的。 解决&#xff1a; 1.使用Redisson这样的工具&#xff0c;它提供了分布式锁的实现&#xff0c;确保在分布式环…

python自动化运维--DNS处理模块dnspython

1.dnspython介绍 dnspython是Pyhton实现的一个DNS工具包&#xff0c;他几乎支持所有的记录类型&#xff0c;可以用于查询、传输并动态更新ZONE信息&#xff0c;同事支持TSIG&#xff08;事物签名&#xff09;验证消息和EDNS0&#xff08;扩展DNS&#xff09;。在系统管理方面&a…

京东云备案流程图_云主机快速ICP备案_京东云服务器备案问题解答

京东云ICP备案流程&#xff0c;备案包括网站和APP备案&#xff0c;以及备案问题解答FAQ&#xff0c;阿腾云以京东云网站域名备案流程为例&#xff0c;先填写主办单位信息&#xff0c;选择网站备案或APP备案&#xff0c;申请授权码并验证&#xff0c;填写并上传主办单位详细信息…

老挝语翻译成简体中文推荐用什么翻译工具?《老挝语翻译通》App满足你所有翻译需求!

如果你正在找一款支持把老挝语翻译成中文&#xff0c;或者把中文翻译成老挝语的翻译工具&#xff0c;不得不推荐你使用《老挝语翻译通》App&#xff0c;您的随身老挝语翻译官&#xff0c;带您轻松跨越语言障碍。 功能亮点&#xff1a; 实时翻译&#xff1a;中文与老挝语的无缝…

论文阅读【时间序列】DSformer

论文阅读【时间序列】DSformer arxive: DSformer: A Double Sampling Transformer for Multivariate Time Series Long-term Prediction github: MTST 分类&#xff1a;多变量时间序列&#xff08;Multivariate time series&#xff09; 核心观点 多变量时间序列3个维度信息 …

一款十六进制编辑器,你的瑞士军刀!!【送源码】

软件介绍 ImHex是一款功能强大的十六进制编辑器&#xff0c;专为逆向工程师、程序员以及夜间工作的用户设计。它不仅提供了基础的二进制数据编辑功能&#xff0c;还集成了一系列高级特性&#xff0c;使其成为分析和修改二进制文件的理想工具。 功能特点 专为逆向工程、编程和夜…

Appium adb 获取appActivity

方法一&#xff08;最简单有效的方法&#xff09; 通过cmd命令&#xff0c;前提是先打开手机中你要获取包名的APP adb devices -l 获取连接设备详细信息 adb shell dumpsys activity | grep mFocusedActivity 有时获取到的不是真实的Activity 方法二 adb shell monkey -p …

K6 性能测试教程:入门介绍,环境搭建和编写第一个 K6 测试脚本

K6 性能测试教程&#xff1a;入门介绍&#xff0c;环境搭建和编写第一个 K6 测试脚本 这篇文章将带您进入 K6 性能测试的世界。博文内容涵盖了 K6 性能测试的入门知识、环境搭建步骤&#xff0c;以及如何编写您的第一个测试脚本。无论您是初学者还是有经验的性能测试专业人员&…

剪映 v5.5 Pro Vip解锁版:使用指南与注意事项

摘要&#xff1a;本文介绍了剪映Pro VIP解锁版的使用方法&#xff0c;包括安装、测试和使用VIP素材的步骤&#xff0c;以及如何避免误报和保持解锁状态的建议。 正文&#xff1a; 剪映Pro是一款广受欢迎的视频编辑软件&#xff0c;提供了丰富的视频编辑功能和大量高质量的素材…

Python基础001

Python输出语句 print输出字符串 print("中国四大名著&#xff1a;","西游记|","三国演义|","红楼梦|","水浒传") print(6) print(1 1)Python输入语句 input函数 input() input("我的名字是&#xff1a;") p…

javaSE期末练习题

文章目录 前言一、程序控制1.顺序结构问题描述解题思路题解 2.选择结构2.1 题1问题描述解题思路题解 2.1 题2问题描述解题思路题解 3.循环结构3.1 阶乘的求取问题描述解题思路题解 3.2 水仙花数问题描述解题思路题解 二、数组三、类与对象1.类与对象1.1圆类问题描述解题思路题解…

【ES】--Elasticsearch的Nested类型介绍

目录 一、问题现象二、普通数组类型1、为什么普通数组类型匹配不准?三、nested类型四、nested类型查询操作1、只根据nested对象内部数组条件查询2、只根据nested对象外部条件查询3、根据nested对象内部及外部条件查询4、向nested对象数组追加新数据5、删除nested对象数组某一个…

【QT】常用控件|widget|QPushButton|RadioButton|核心属性

目录 ​编辑 概念 信号与槽机制 控件的多样性和定制性 核心属性 enabled geometry ​编辑 windowTiltle windowIcon toolTip styleSheet PushButton RadioButton 概念 QT 控件是构成图形用户界面&#xff08;GUI&#xff09;的基础组件&#xff0c;它们是实现与…

第十四届蓝桥杯省赛C++B组E题【接龙数列】题解(AC)

需求分析 题目要求最少删掉多少个数后&#xff0c;使得数列变为接龙数列。 相当于题目要求求出数组中的最长接龙子序列。 题目分析 对于一个数能不能放到接龙数列中&#xff0c;只关系到这个数的第一位和最后一位&#xff0c;所以我们可以先对数组进行预处理&#xff0c;将…

VMware创建新虚拟机教程(保姆级别)

&#x1f4e2; 续上一篇 最新超详细VMware虚拟机安装完整教程-CSDN博客 &#xff0c;本章将详细讲解VMware创建虚拟机。 一、创建新的虚拟机 点击【创建新的虚拟机】&#xff01; 点击【自定义&#xff08;高级&#xff09;】> 下一步&#xff01; > 默认下一步&#x…

[hive] posexplode生成从去年一月一号,到本月的月时间表

生成从去年一月一号&#xff0c;到本月的月时间表 posexplode用法&#xff1a; lateral view 表别名 as 序号列名,数组中的元素的名 1、生成序列 SELECT time_stamp_fist_day_of_last_year,--去年第一天的时间戳numfrom(SELECTsplit(repeat_o,,) o_array,time_stamp_fist_da…

【2024德国签证】去德国读博士需要申请什么签证?

德国留学签证面签的经过及注意事项 ✨&#xff01;希望我的经验可以帮助大家顺利通过签证&#xff0c;顺利开启德国留学之旅 。记得带上足够的现金和材料哦 &#xff01; 一、选择适合自己的签证类型 在选择签证类型时&#xff0c;一定要根据自己的实际情况来选择合适的签证种…

vmware虚拟机安装openEuler

一、openEuler简介 openEuler是一款开源操作系统。当前openEuler内核源于Linux&#xff0c;支持鲲鹏及其它多种处理器&#xff0c;能够充分释放计算芯片的潜能&#xff0c;是由全球开源贡献者构建的高效、稳定、安全的开源操作系统&#xff0c;适用于数据库、大数据、云计算、…