spi子系统实现数码管控制

  • 任务目标
    • 大致思路
    • 代码实现
      • 驱动代码
      • 测试代码

任务目标

应用层程序控制数码管显示数字

大致思路

1、定义初始化spi对象并注册
2、匹配设备树节点
3、匹配成功后,在probe函数中注册字符设备驱动
4、通过字符设备驱动对内核写入需要变换的数码管数组
5、在内核层实现write函数获取到应用层内容时对数码管进行控制
6、应用层循环发送0-9数据 依次给4个数码管,实现类似流水灯控制

代码实现

驱动代码

#include <linux/init.h>
#include<linux/spi/spi.h>//#include <linux/fs.h>//#include <linux/io.h>//#include <linux/cdev.h>//#include <linux/uaccess.h>#include <linux/module.h>struct cdev *cdev;
struct class *cls;
struct device *dev;
char  kbuf[]={0x1,0x3f};
struct spi_device *spi1=NULL;int minor=0;//次设备号从0开始
#if 1
unsigned int major = 0;//动态申请
#else
unsigned int major = 500;//静态指定设备号
#endif
//对应的是open()
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 __user *ubuf, size_t size, loff_t *loff)
{//size参数是用户期待读到的字节长度int ret;if(size>sizeof(kbuf))size=sizeof(kbuf);ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("数据从内核向用户拷贝失败\n");return -EIO;}return size;
}ssize_t mycdev_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff)
{int ret;if(size>sizeof(kbuf))size=sizeof(kbuf);ret=copy_from_user(kbuf,ubuf,size);spi_write(spi1,kbuf,sizeof(kbuf));if(ret){printk("数据从内核向用户拷贝失败\n");return -EIO;}return size;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}struct file_operations fops=
{.open=mycdev_open,.read=mycdev_read,.write=mycdev_write,.release=mycdev_close,
};int m74hc595_probe(struct spi_device *spi)
{int ret,i;dev_t devno;printk("%s:%d\n",__FILE__,__LINE__);spi_write(spi,kbuf,sizeof(kbuf));spi1=spi;//分配对象cdev=cdev_alloc();//注册对象if(cdev==NULL){printk("cdev alloc memory err\n");ret = -ENOMEM;goto ERR1;}printk("对象分配成功\n");//对象的初始化cdev_init(cdev,&fops);//设备号的申请if(major==0)//动态申请{ret=alloc_chrdev_region(&devno,minor,1,"keyirq");if(ret){printk("动态申请设备号失败\n");goto ERR2;}major = MAJOR(devno);minor = MINOR(devno);printk("动态申请设备号成功\n");}else{ret=register_chrdev_region(MKDEV(major,minor),1,"keyirq");if(ret){printk("静态申请设备号失败\n");goto ERR2;}printk("静态申请设备号成功\n");}//注册字符设备驱动ret=cdev_add(cdev,MKDEV(major,minor),1);if(ret){printk("字符设备驱动注册失败\n");goto ERR3;}printk("注册字符设备驱动成功\n");//自动创建设备节点cls = class_create(THIS_MODULE,"keyirq1");if(IS_ERR(cls)){printk("创建逻辑节点目录失败\n");ret=PTR_ERR(cls);goto ERR4;}printk("创建逻辑节点目录成功\n");//向上提交节点信息dev = device_create(cls,NULL,MKDEV(major,0),NULL,"keyirq");if(IS_ERR(dev)){printk("创建逻辑节点失败\n");ret = PTR_ERR(dev);goto ERR5;}
printk("创建逻辑节点成功\n");
return 0;
ERR5:
for(--i;i>=0;i--)
{device_destroy(cls,MKDEV(major,i));
}
class_destroy(cls);
ERR4:
cdev_del(cdev);
ERR3:
unregister_chrdev_region(MKDEV(major,minor),0);
ERR2:
kfree(cdev);
ERR1:
return ret;return 0;
}
int m74hc595_remove(struct spi_device *spi)
{printk("%s:%d\n",__FILE__,__LINE__);//1.销毁设备节点device_destroy(cls,MKDEV(major,0));class_destroy(cls);//2.注销字符设备驱动cdev_del(cdev);//3.释放设备号unregister_chrdev_region(MKDEV(major,minor),0);//4.释放动态申请的空间kfree(cdev);return 0;
}//设备树匹配表
struct of_device_id of_table[]={{.compatible="hqyj,m74hc595"},{},
};
MODULE_DEVICE_TABLE(of,of_table);
//定义SPI对象并且初始化
struct spi_driver m74hc595 ={ .probe=m74hc595_probe,.remove=m74hc595_remove,.driver={.name="m74hc595",.of_match_table=of_table,},
};module_spi_driver(m74hc595);
// module_init(mycdev_init);
//module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

测试代码

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include <sys/ioctl.h>
//#include"myirq.h"
//#include<>
int main(int argc, char const *argv[])
{int fd=open("/dev/keyirq",O_RDWR);char ubuf[]={0x1,0x3f};if(fd<0){printf("打开设备文件失败\n");exit(-1);}printf("设备文件打开成功\n");//在终端输入while(1){if(ubuf[0]==0x1){ubuf[0]=0x2;}else if(ubuf[0]==0x2){ubuf[0]=0x4;}else if(ubuf[0]==0x4){ubuf[0]=0x8;}else if(ubuf[0]==0x8){ubuf[0]=0x1;}switch(ubuf[1]){case 0x3f:ubuf[1]=0x06;break;case 0x06:ubuf[1]=0x5b;break;case 0x5b:ubuf[1]=0x4f;break;case 0x4f:ubuf[1]=0x66;break;case 0x66:ubuf[1]=0x6d;break;case 0x6d:ubuf[1]=0x7d;break;case 0x7d:ubuf[1]=0x07;break;case 0x07:ubuf[1]=0x7f;break;case 0x7f:ubuf[1]=0x6f;break;case 0x6f:ubuf[1]=0x3f;break;}write(fd,&ubuf,sizeof(ubuf));for(int i=0;i<10000000;i++){}  //  sleep(1);}close(fd);return 0;
}

spi子系统实现数码管控制相关推荐

  1. SPI子系统分析之二:数据结构【转】

    转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...

  2. Linux SPI 子系统(x86平台)

    Linux SPI 子系统(x86平台) 文章目录 Linux SPI 子系统(x86平台) 前言 总述 SPI 硬件系统与软件抽象之间的关系 SPI 驱动的 Probe 和 Match 过程 SPI ...

  3. linux内核添加spi驱动,Linux内核驱动之spi子系统spi协议.docx

    Linux内核驱动之spi子系统spi协议 概况 SPI接口是摩托罗拉首先提出的全双工三线同步串行外围接口SCK,MOSI,MISO,采用主从模式(Master Slave)架构:支持多slave模式 ...

  4. mini2440 SPI驱动移植 (基于SPI子系统) (转的记录)

    原文地址:mini2440 SPI驱动移植 (基于SPI子系统) 作者:三点水兽 参考一: 按照下面帖子的方法,本人试验成功,只需按照下面步骤进行就行了. 原帖地址: http://blog.csdn ...

  5. PLC实验:LED 数码显示控制

    实验项目名称:LED 数码显示控制 一.实验控制要求 置位启动开关 K0 为 ON 时,LED 数码显示管依次循环显示 0.1.2.3-9.A.B.C- F: 二.端口分配 三.实验程序梯形图 PLC ...

  6. Linux 驱动 | SPI子系统

    SPI子系统 这些驱动的共同点: 主机端驱动和外设端驱动分离 通过一个核心层将某种总线协议进行抽象 外设端驱动通过核心层API间接调用主机驱动提供的传输函数进行收发数据 IIC.SPI等不支持热拔插的 ...

  7. 基于arduino的一位数码管控制

    基于Mixly的一位数码管控制 硬件: arduino编程板.一位数码管.220Ω电阻.杜邦线若干. 软件: Mixly图形化编程软件. 目标: 通过mixly软件对arduino编程, 实现一位数码 ...

  8. led数码显示控制plc实验_实验三 LED数码显示控制 PLC实验报告

    广州大学学生实验报告 开课学院及实验室:工程北 529 2015 年 5 月 28 日 学院 机械与电气 工程 年级. 专 业.班 姓名 学号 实验课程名称 电气控制与可编程控制器 成绩 实验项目名称 ...

  9. led数码显示控制plc实验_实验三led数码显示控制plc实验报告

    开课学院及实验室:工程北 529 2015 年 5 月 28 日 学院 机械与电气 工程 年级. 专 业.班 姓名 学号 实验课程名称 电气控制与可编程控制器 成绩 实验项目名称 实验三 LED 数码 ...

最新文章

  1. 如何用MaskBlt实现两个位图的合并,从而实现背景透明
  2. fastreport dll_报表如何连接到VistaDB嵌入式数据库?FastReport.Net轻松搞定
  3. 【算法】算法 动态规划 背包问题
  4. linux的创建线程池,Linux下通用线程池的创建与使用(上) (3)
  5. Spark Yarn-cluster与Yarn-client
  6. 【EntityFramework学习笔记】为什么要使用迁移
  7. java--DBUtils和连接池
  8. linux安装后root密码错误,linux新安装后root密码设置
  9. 提供三份程序员简历模板
  10. Day33:Swift 和 Object - C
  11. 有哪些APP小众却实用,让你相见恨晚
  12. AR5B22网卡折腾记录
  13. Android报错:Only fullscreen activities can request orientation的解决方法
  14. Shell 脚本进阶,经典用法及其案例
  15. ymlm启用root用户
  16. Latex 绘制函数图像
  17. 手把手教你升级Keil MDK的ARM编译器
  18. 我国村庄规划发展历程
  19. Error running ‘Tomcat 8.5.31’: Unable to open debugger port (127.0.0.1:52506
  20. 对研究生教育有什么看法_我对研究员特征的看法

热门文章

  1. 供应链金融服务平台系统开发-成熟、稳定、节本、增效,一站式信息交易管理平台
  2. 二类分类器构造多类分类器
  3. FMDB-FMDatabaseQueue
  4. Pixhawk原生固件PX4之常用函数解读
  5. Rabbitmq学习笔记(尚硅谷2021)
  6. abaqus切削为什么没有切屑_Abaqus切削仿真常见问题及其解决个人总结
  7. 常见开发相关变量命名词汇
  8. 系统架构设计师教程-学习-记录(1)系统架构师知识结构
  9. C语言之strcmp函数和strncmp函数
  10. 关于AQS中自旋的理解