驱动层
spi.c
#include<linux/module.h>
#include<linux/init.h>
#include<linux/spi/spi.h>
int major;
struct class *cls;
struct device *dev;
struct spi_device *spi1;
char buf[2] = {0};
int m74hc595_open(struct inode *inode, struct file *file)
{
return 0;
}
ssize_t m74hc595_write (struct file *file, const char __user *buff, size_t size, loff_t *offset)
{
copy_from_user(buf,buff,size);
// printk("buf[0] = %d\n",buf[0]);
// printk("buf[1] = %d\n",buf[1]);
spi_write(spi1,buf,sizeof(buf));
return 0;
}
int m74hc595_close(struct inode *inode, struct file *file)
{
return 0;
}
struct file_operations fops={
.open=m74hc595_open,
.write=m74hc595_write,
.release=m74hc595_close,
};
int m74hc595_probe(struct spi_device *spi)
{
spi1 = spi;
/*
//让右边第一个数码管显示数字5
char buf[] = {0x8,0x6d};
spi_write(spi,buf,sizeof(buf));
*/
/*********字符设备驱动注册*begin**********/
//字符设备驱动注册
major = register_chrdev(major,"m74hc595_1",&fops);
if(major<0)
{
printk("字符设备驱动注册失败\n");
return major;
}
printk("字符设备驱动注册成功\n");
//向上提交目录
cls = class_create(THIS_MODULE,"m74hc595_1");
if(IS_ERR(cls))
{
printk("向上提交目录失败\n");
return PTR_ERR(cls);
}
printk("向上提交目录成功\n");
//自动创建设备节点
dev = device_create(cls,NULL, MKDEV(major,0),\
NULL, "m74hc595_1");
if(IS_ERR(dev))
{
printk("向上提交设备节点失败\n");
return PTR_ERR(dev);
}
printk("向上提交设备节点成功\n");
/*********字符设备驱动注册*end**********/
printk("%s:%d\n",__FILE__,__LINE__);
return 0;
}
int m74hc595_remove(struct spi_device *spi)
{
device_destroy(cls,MKDEV(major,0));
class_destroy(cls);
unregister_chrdev(major,"m74hc595_1");
printk("%s:%d\n",__FILE__,__LINE__);
return 0;
}
const struct of_device_id oftable[] =
{
{.compatible = "hqyj,m74hc595"},
{}
};
struct spi_driver m74hc595_driver =
{
.probe = m74hc595_probe,
.remove = m74hc595_remove,
.driver = {
.name = "m74hc595",
.of_match_table = oftable,
}
};
module_spi_driver(m74hc595_driver);
MODULE_LICENSE("GPL");
应用层
spi_app.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
//0 1 2 3 4 5 6 7 8 9
int num[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
// 1 2 3 4
int sec[4] = {0x01,0x02,0x04,0x08};
char writebuf[2] = {0};
int main(int argc, char const *argv[])
{
int tem,hum;
float tem1,hum1;
int fd = open("/dev/m74hc595_1",O_RDWR);
if (fd < 0)
{
printf("设备文件打开失败\n");
exit(-1);
}
char num1[10];
printf("请输入一个四位数:");
fscanf(stdin, "%s", num1);
while (getchar()!=10);
while (1)
{
for (int i = 0; i < 4; i++)
{
switch(num1[i])
{
case '0':
{
writebuf[0] = sec[i];
writebuf[1] = num[0];
}
break;
case '1':
{
writebuf[0] = sec[i];
writebuf[1] = num[1];
}
break;
case '2':
{
writebuf[0] = sec[i];
writebuf[1] = num[2];
}
break;
case '3':
{
writebuf[0] = sec[i];
writebuf[1] = num[3];
}
break;
case '4':
{
writebuf[0] = sec[i];
writebuf[1] = num[4];
}
break;
case '5':
{
writebuf[0] = sec[i];
writebuf[1] = num[5];
}
break;
case '6':
{
writebuf[0] = sec[i];
writebuf[1] = num[6];
}
break;
case '7':
{
writebuf[0] = sec[i];
writebuf[1] = num[7];
}
break;
case '8':
{
writebuf[0] = sec[i];
writebuf[1] = num[8];
}
break;
case '9':
{
writebuf[0] = sec[i];
writebuf[1] = num[9];
}
break;
default:
break;
}
write(fd,writebuf,sizeof(writebuf));
}
}
return 0;
}
设备树
&spi4{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi4_pins_b>;
pinctrl-1 = <&spi4_sleep_pins_b>;
cs-gpios = <&gpioe 11 0>;
status = "okay";
//参照documentation spi-st-ssc.txt文档
m74hc595@0{
compatible = "hqyj,m74hc595";
reg = <0>;
spi-max-frequency = <10000000>; //总线速率设置为10Mhz
//spi总线最大速率59Mhz
};
};