arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭

这篇具有很好参考价值的文章主要介绍了arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

中断控制led灯亮灭
驱动文件源码
led-key.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
#include<linux/of_irq.h>
#include<linux/interrupt.h>
struct device_node *led_dev;
struct device_node *key_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
unsigned int irqno_1;
unsigned int irqno_2;
unsigned int irqno_3;
irqreturn_t myirq_handler(int irq, void *dev){
    printk("irq=%d\n",irq);
    switch (irq)
    {
    case 71:
        gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));
        break;
    case 72:
        gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));
        break;
    case 73:
        gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));
        break;
    } 
    return IRQ_HANDLED;
}
static int __init mycdev_init(void){ 
    int ret;
    led_dev = of_find_node_by_path("/leds");
    if(led_dev == NULL)
    {
        printk("解析led灯设备树节点失败\n");
        return -EFAULT;
    }
    printk("解析led灯设备树成功\n");
    key_dev = of_find_node_by_path("/myirq");
    if(key_dev == NULL)
    {
        printk("解析中断设备树节点失败\n");
        return -EFAULT;
    }
    printk("解析中断设备树成功\n");
    gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpiono_led_1))
    {
        printk("获取GPIO号失败\n");
        return -PTR_ERR(gpiono_led_1);
    }
     gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpiono_led_2))
    {
        printk("获取GPIO号失败\n");
        return -PTR_ERR(gpiono_led_2);
    }
     gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpiono_led_3))
    {
        printk("获取GPIO号失败\n");
        return -PTR_ERR(gpiono_led_3);
    }
    printk("申请GPIO编号成功\n");
    irqno_1 = irq_of_parse_and_map(key_dev,0);
    if(!irqno_1){
        printk("解析中断号失败\n");
        return -ENXIO;
    }
    printk("解析软中断号成功 irqno=%d\n",irqno_1);
    irqno_2 = irq_of_parse_and_map(key_dev,1);
    if(!irqno_2){
        printk("解析中断号失败\n");
        return -ENXIO;
    }
    printk("解析软中断号成功 irqno=%d\n",irqno_2);
    irqno_3 = irq_of_parse_and_map(key_dev,2);
    if(!irqno_3){
        printk("解析中断号失败\n");
        return -ENXIO;
    }
    printk("解析软中断号成功 irqno=%d\n",irqno_3);
    //注册中断
    ret = request_irq(irqno_1,myirq_handler,IRQF_TRIGGER_FALLING,"key1",NULL);
    if(ret){
        printk("注册中断1失败\n");
        return ret;
    }
    //注册中断
    ret = request_irq(irqno_2,myirq_handler,IRQF_TRIGGER_FALLING,"key2",NULL);
    if(ret){
        printk("注册中断2失败\n");
        return ret;
    }
    //注册中断
    ret = request_irq(irqno_3,myirq_handler,IRQF_TRIGGER_FALLING,"key3",NULL);
    if(ret){
        printk("注册中断3失败\n");
        return ret;
    }
    printk("注册中断成功\n");
    return 0;
}
static void __exit mycdev_exit(void){
    free_irq(irqno_1,NULL);
    free_irq(irqno_2,NULL);
    free_irq(irqno_3,NULL);
    gpiod_set_value(gpiono_led_1,0);
    gpiod_put(gpiono_led_1);
    gpiod_set_value(gpiono_led_2,0);
    gpiod_put(gpiono_led_2);
    gpiod_set_value(gpiono_led_3,0);
    gpiod_put(gpiono_led_3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

字符设备指令控制led灯亮灭
驱动文件
led-cmd.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include<linux/fs.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
struct device_node *led_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
struct class *cls;
struct device *dev;
char kbuf[128]={0};
unsigned int major;//定义一个变量保存主设备号
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{
     printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{
     printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
     long ret;
     ret=copy_from_user(kbuf,ubuf,size);
     switch (kbuf[0])
    {
    case '1':
        gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));
        break;
    case '2':
        gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));
        break;
    case '3':
        gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));
        break;
    } 
    return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
     printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}
void all_led_init(void){
    int ret;
    led_dev = of_find_node_by_path("/leds");
    if(led_dev == NULL)
    {
        printk("解析led灯设备树节点失败\n");
        //return -EFAULT;
    }
    gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpiono_led_1))
    {
        printk("获取GPIO号失败\n");
        //return -PTR_ERR(gpiono_led_1);
    }
     gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpiono_led_2))
    {
        printk("获取GPIO号失败\n");
        //return -PTR_ERR(gpiono_led_2);
    }
     gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);
    if(IS_ERR(gpiono_led_3))
    {
        printk("获取GPIO号失败\n");
       // return -PTR_ERR(gpiono_led_3);
    }
    printk("申请GPIO编号成功\n");
}
//定义一个操作方法结构体变量并且初始化
struct file_operations fops={
    .open=mycdev_open,
    .release=mycdev_close,
    .read=mycdev_read,
    .write=mycdev_write,
};
static int __init mycdev_init(void){ 
    //注册字符设备驱动
    major=register_chrdev(0,"mychrdev",&fops);
    if(major<0)
    {
        printk("注册字符设备驱动失败\n");
        return major;
    }
    printk("注册字符设备驱动成功major=%d\n",major);
    // 向上提交目录
    cls = class_create(THIS_MODULE, "mycdev");
    if (IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return -PTR_ERR(cls);
    }
    printk("向上提交目录信息成功\n");
    // 向上提交设备节点信息
    dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");
    if (IS_ERR(dev))
    {
        printk("向上提交设备节点信息失败\n");
        return -PTR_ERR(dev);
    }
    
    printk("向上提交设备节点成功\n");
    all_led_init();
    return 0;
}
static void __exit mycdev_exit(void){
    gpiod_set_value(gpiono_led_1,0);
    gpiod_put(gpiono_led_1);
    gpiod_set_value(gpiono_led_2,0);
    gpiod_put(gpiono_led_2);
    gpiod_set_value(gpiono_led_3,0);
    gpiod_put(gpiono_led_3);
     //注销字符设备驱动
        //销毁节点信息
    device_destroy(cls,MKDEV(major,0));
    //销毁目录信息
    class_destroy(cls);
    unregister_chrdev(major,"mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

应用文件
led.c文章来源地址https://www.toymoban.com/news/detail-627809.html

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int fd = open("/dev/mycdev", O_RDWR);
    if (fd < 0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    while (1)
    {
        printf("请输入控制命令:1(led1关灯/开灯)2(led2关灯/开灯)3(led3关灯/开灯)>");
        fgets(buf, sizeof(buf), stdin); // 从终端输入数据到buf
        buf[strlen(buf) - 1] = '\0';    // 将buf末尾的'\n'切换为'\0'
        write(fd, buf, sizeof(buf));    
    }
    close(fd);
    return 0;
}

到了这里,关于arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【stm32----按键中断实验,按键控制LED灯】

    1、按下KEY1,LED1亮,再次按下KEY1,LED1灭; 2、按下KEY2,LED2亮,再次按下KEY2,LED2灭; 3、按下KEY3,LED3亮,再次按下KEY3,LED3灭; 一、头文件 1、gpio.h 2、key.h 二、初始化函数及功能函数 1、gpio.c 2、key.c 三、中断处理函数 do_irq.c 四、主函数 main.c 依次按下key3、key2、key1、key2

    2024年02月04日
    浏览(43)
  • STM32——05-按键、时钟控制、中断复位 点亮LED灯

    如何点亮一颗LED灯   编程实现点灯 常用的 GPIO HAL 库函数: void HAL_GPIO_Init ( GPIO_TypeDef * GPIOx , GPIO_InitTypeDef * GPIO_Init ); void HAL_GPIO_WritePin ( GPIO_TypeDef * GPIOx , uint16_t GPIO_Pin , GPIO_PinState PinState ); void HAL_GPIO_TogglePin ( GPIO_TypeDef * GPIOx , uint16_t GPIO_Pin );  结构体  GPIO_InitTypeDef  定义:

    2024年02月08日
    浏览(39)
  • STM32+摁键与定时器实现Led灯控制(中断)

    中断作为单片机开发必须掌握的内容,它能够在不搭载操作系统的情况下让我们体验多任务处理的快感,保证了高优先级任务的实时性,同时系统中断也能够提供给用户在核心发生错误之后进行处理的机会。STM32F103系列单片机中断非常强大,每个外设都可以产生中断,F103 在

    2024年02月04日
    浏览(52)
  • STM32——ADC读取光敏传感器控制LED灯,看门狗中断

    一、编写读取AD值的函数,之后判断AD值,进行相应操作,比如点灯。 二、用ADC读取光敏传感器AO口输出,并配置ADC通道看门狗监控这条通道,当光线太暗时打开LED灯。 之后会再介绍可编程RGB灯带WS2812B。 光敏传感器有两个输出口,一个是DO(Digital Output),一个是AO(Analog O

    2023年04月18日
    浏览(37)
  • stm32单片机开关控制LED灯(中断方式)(proteus电路图)

      补充一点:拼多多上面LED额定电流20mA,额定电压2V,额定电阻100欧姆,后边这个是STM32 如果只是用面包板做实验,输入输出都不是很多,就直接用灌电流的方式把LED直接接到STM32了,即使是设计产品,如果能够直接接,那么肯定也是不会浪费钱去买额外的原件的,所以只有

    2024年02月11日
    浏览(34)
  • STM32G030C8T6:使用按键控制LED亮灭(外部中断)

    本专栏记录STM32开发各个功能的详细过程,方便自己后续查看,当然也供正在入门STM32单片机的兄弟们参考; 本小节的目标是,系统主频64 MHZ,采用高速外部晶振,通过KEY1 按键的PA0 引脚配置成中断输入引脚,PB9引脚配置成输出,每次按键,PA0 引脚就会进入一次外部中断,每进

    2024年02月05日
    浏览(35)
  • 基于STM32CubeMX与keil采用按键外部中断方式控制LED与蜂鸣器

    这篇文章详细记录外部中断方式控制LED的亮灭以及蜂鸣器的开关;本文从原理图开始到最后实现功能,内容详细。 本栏目的所有都是基于STM32F407ZET6芯片,博主采用的是普中的天马F407开发板。 实现功能:LED0与LED1默认熄灭,蜂鸣器默认关闭。按下按键KEY0,控LED0亮灭;按下按

    2024年02月16日
    浏览(42)
  • STM32_ADC————ADC+DMA多路数据传输,看门狗中断,传感器控制LED

    一:介绍ADC与DMA的基本情况与初始化 二:利用ADC+DMA+看门狗中断+传感器控制LED灯代码 三:总结实验过程中碰到的错误与问题 通过DMA转运ADC的数据,设置ADC的中断看门狗阈值,当光敏传感器的ADC采样值在看门狗高低阈值中间,不触发中断,如果超过看门狗的高低阈值就会触发

    2024年02月04日
    浏览(41)
  • arm学习stm32串口指令点亮led灯

    main.c uart-led.h uart-led.c

    2024年02月12日
    浏览(35)
  • STM32 按键控制的灯亮或灭

    目录 1.STM32CubeMX的配置 2.轮询模式下的控制(代码) 3.上电烧录摁下复位键,摁下按键1 ,亮红灯,摁下按键2,亮绿灯,摁下按键3,亮蓝灯 1.STM32CubeMX的配置 按原理图去设置引脚状态  GPIO输入模式读取按键状态,输出模式控制灯的状态  右键进行重命名按键分别为,KEY1,KEY

    2024年02月07日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包