完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
原理图
TM1650采用的是IIC接口。 IIC总线简介 IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的一种简单、双向、二线制、同步串行总线
tm1650的特性 TM1650 是一种带键盘扫描接口的 LED(发光二极管显示器) 驱动控制专用电路。 内部集成有 MCU输入输出控制数字接口、数据锁存器、LED 驱动、键盘扫描、辉度调节等电路。TM1650 性能稳定、质量可靠、抗干扰能力强,可适用于 24 小时长期连续工作的应用场合。 按键读写时序图 读写的键盘值对应表格如下所示: 数据命令设置 [tr]B7B6B5B4B3B2B1B0说明[/tr]
程序代码编写 添加设备树 在设备树 arch/arm64/boot/dts/rockchip/rk3399pro-toybrick-prop-linux.dts 中添加 &i2c6 { status = "okay"; //i2c-scl-rising-time-ns = <800>; //i2c-scl-falling-time-ns = <200>; i2c-scl-rising-time-ns = <140>; i2c-scl-falling-time-ns = <30>; clock-frequency=<400000>; tm1650:tm1650@24{ status = "okay"; compatible = "tm1650"; reg = <0x24>; }; }; 驱动编写 匹配设备节点 static const struct i2c_device_id i2c_id[] = { { "tm1650", 0 }, { }, /* Terminating entry */ }; static struct of_device_id i2c_match[] = { {.compatible = "tm1650" }, { }, }; MODULE_DEVICE_TABLE(i2c, i2c_id); static struct i2c_driver i2c_driver = { .driver = { .name = "tm1650", .owner = THIS_MODULE, .of_match_table = of_match_ptr(i2c_match), }, .probe = i2c_probe, .remove = i2c_remove, .id_table = i2c_id, }; 文件探索 static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; struct device_node *tm1650_node = NULL; tm1650_client = client; printk("The match successful!n"); printk("client->addr = %xn",client->addr); ret = misc_register(&gec3399_tm1650_misc); //杂项设备 if(ret < 0){ printk("misc register errorn"); goto err_register_error; } tm1650_node = of_find_compatible_node(NULL, NULL,"tm1650"); if(tm1650_node == NULL){ printk("not node of compatible is tm1650n"); ret = -ENODEV; goto err_gpio_request; } printk("tm1650 dirve install succeen"); return 0; err_gpio_request: misc_deregister(&gec3399_tm1650_misc); err_register_error: return 0; } 杂项设备 static struct miscdevice gec3399_tm1650_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "tm1650_drv", .fops = &gec3399_tm_fops, };//杂项设备初始化 文件操作集 static const struct file_operations gec3399_tm_fops = { .owner = THIS_MODULE, .read = gec3399_tm_read, }; //文件操作集结构体 键值读取接口 static ssize_t gec3399_tm_read(struct file *filp, char __user *buf, size_t len, loff_t *off) { int ret; char data_buf = 0; //printk("<0>""sizeof(data_buf) = %dnsizeof(tm() = %dn",sizeof(data_buf),sizeof(value)); msleep(250); //读取tm1650的值 ret = i2c_read_byte(tm1650_client,RDADDR,&data_buf,1); if(ret != 1){ printk("%s %d i2c read byte data errn",__FUNCTION__,__LINE__); //return -1; } //value = (data_buf[0]<<8) | (data_buf[1]<<0); //printk("<0>""value = %dn",data_buf); //按键值上报给用户空间 ret = copy_to_user(buf, &data_buf, sizeof(data_buf)); if(ret < 0){ printk("<0>""%s %d err copy tm value to usern",__FUNCTION__,__LINE__); return -EFAULT; } return ret; } IIC读取接口 static int i2c_read_byte(struct i2c_client * client, uint8_t reg, uint8_t * buf, int len) { struct i2c_msg msgs[2]; msgs[0].addr = client->addr; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = ® msgs[1].addr = client->addr; msgs[1].flags = I2C_M_RD; msgs[1].len = len; msgs[1].buf = buf; if(i2c_transfer(client->adapter, msgs, 2) != 2) return 0; return 1; } 上层应用代码 #include #include #include #include #include #include #include #include int fd_tm = 0; short tm_value = 0; int main(void) { int ret; //打开设备节点 fd_tm = open("/dev/tm1650_drv", O_RDWR); if(fd_tm < 0) { perror("open tm_drv driver"); return -1; } while(1) { //读取键盘的按键值 ret = read(fd_tm,&tm_value,1); if(ret<0) { perror("read errorn"); return -1; } //打印出按键的按键值 printf("tm_value = %xH n",tm_value); sleep(1); } close(fd_tm); return 0; } 编写Makefile文件 obj-m += tm1650_drv.o KERNELDIR:=/file/RK3399Pro/rk3399pro_git_repo/kernel PWD:=$(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules test: aarch64-linux-gnu-gcc tm1650_test.c -o tm1650_test clean: rm -rf *.o *.order .*.cmd *.ko *.mod.c *.symvers *.tmp_versions 测试步骤 编译源码 在ubuntu中输入: make 得到驱动目标文件tm1650_drv.ko 输入: make test 得到测试目标文件:tm1650_test 加载驱动 在开发板命令终端输入: insmod tm1650_drv.ko 执行测试程序 在开发板命令终端输入: chmod 777 tm1650_test ./tm1650_test 实验现象 读取到键盘的按键值 root@linaro-alip:~/test# ./tm1650_test tm_value = 44H tm_value = 45H tm_value = 46H |
||||||||
|
||||||||
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
343 浏览 0 评论
696 浏览 1 评论
602 浏览 1 评论
1833 浏览 1 评论
3083 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 08:49 , Processed in 0.458385 second(s), Total 40, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号