DAC MCP4725 i2c 驱动(linux)

2023-10-27

mcp4725是一款低功耗,高精度 单通道,拥有EEPROM的12位的dac。

由于最近项目中使用到了该芯片所以贴出来给大家参考(步进电机电机芯片半流锁定。)

本贴呢非项目中使用的平台,主要是想在linux 下实现对该器件的使用,实现一个简单的i2c dac字符驱动。

对于i2c 基本原理通信协议呢不做过多描述。

1.mcp4725 地址

mcp4725官方默认地址是一般是b'1100 (96) a0 可通过外部上拉或者下拉决定。

 

2.数据流程

 

通过前面图可以看到mcp4725 控制起来是非常简单的 第一个字节主要是器件地址(7位)+读写位(1位)。第二个字节 高4位呢是控制指令,低4位呢主要配合后面的第三个字节,是第三个字节的高4位。

那么快速模式怎么使用呢?比如需要2v 电压。

假设VDD 为电源电压5V dac的压降为0.7v 那么 我们需要2v 的的电压 Vout=2/(5-0.7)*4095=1905 ,转换为2进制可以看到

 

高4位位0111 低7位为01110001  。那么对应给设备发送 就应当为 (16进制):0x60  0x07 0x71 那么我们的数据就写好了。

本环境在MT7628 openWRT 环境下,MT7628  只有1个i2c 总线接口他的地址为0x10000900

由于linux 使用设备树,其设备树定义为:

 

下面看一下linux 驱动代码的具体实现:

#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/fs.h>

int major;
struct class *cls;
struct mcp4725_dev_t
{
	struct cdev chrdev;
	struct device *device;
	struct i2c_client *cli;
	int index;
};


int mcp4725_open(struct inode *inode,struct file *file)
{
   struct mcp4725_dev_t *pri=container_of(inode->i_cdev,struct mcp4725_dev_t,chrdev);//container_of(inode->i_cdev,struct mcp4725_dev_t,chardev);
   struct i2c_client *cli;
   file->private_data=pri;
   cli=pri->cli;
  
    printk("%s->%d\n",__func__,__LINE__);
	return 0;
}

int mcp4725_close(struct inode *inode,struct file *file)
{
    printk("%s->%d\n",__func__,__LINE__);
	return 0;
}

long mcp4725_ioctl(struct file * file, unsigned int cmd, unsigned long args)
{
	printk("%s->%d\n",__func__,__LINE__);
 	return 0;
}

int mcp_write(struct i2c_client *cli,unsigned short val)
{
	int ret=0;
	unsigned char buf[2];
	struct i2c_msg msg;
	buf[0]=(unsigned char)(val>>8);//高位4位
	buf[1]=(unsigned char)val;//低8位
	msg.addr=cli->addr;
	msg.buf=buf;
	msg.flags=0;
	//msg.
	msg.len=2;
	ret=i2c_transfer(cli->adapter,&msg,1);
	if(ret!=1)
	{
		printk("%s->%d i2c_transfer ret%d\n",__func__,__LINE__,ret);
		return -23;
	}
    printk("send %daddr:%d->%d\n",__LINE__,cli->addr,val);
	return 0;
}

int mcp4725_write(struct file *file, const char __user *usr, size_t size, loff_t *loff)
{

    int ret=0;
	unsigned short user_data;
    struct i2c_client *cli=NULL;
	struct mcp4725_dev_t *pri=file->private_data;
	cli=pri->cli;
	//char buf
	
    ret = copy_from_user(&user_data,usr,size);
	printk("addr:%d->%d\n",cli->addr,user_data);
	if(ret<0)
	{
		printk("error:%s->%d\n",__func__,__LINE__);
		return -20;
	}

    mcp_write(cli,user_data);

	printk("%s->%d\n",__func__,__LINE__);
	return 0;
}

struct file_operations fops_mcp4725={
	.open=mcp4725_open,
	.release=mcp4725_close,
	.write=mcp4725_write,
	.unlocked_ioctl=mcp4725_ioctl,
};


int mcp4725_remove(struct i2c_client *cli)
{
	/* data */
	return 0;
}

struct i2c_device_id id_table[] = {
};

int mcp4725_proble(struct i2c_client *cli,const struct i2c_device_id *id)
{
	int ret=0;
	struct  device_node *of_node=cli->dev.of_node;
	struct mcp4725_dev_t *mcp4725_pri=NULL;

	mcp4725_pri=kmalloc(sizeof(*mcp4725_pri),GFP_KERNEL);

    printk("addr:%d->%d\n",cli->addr,__LINE__);
	printk("%s->%d\n",__func__,__LINE__);
	memset(mcp4725_pri,0,sizeof(*mcp4725_pri));

    cli->dev.platform_data=mcp4725_pri;
	
    mcp4725_pri->cli=cli;
	

    // ret=of_property_read_u32(of_node,"index",&mcp4725_pri->index);
	// if(ret<0)
	// {
    //      printk("error:%s->%d\n",__func__,__LINE__);
	// 	return -20;
	// }
	mcp4725_pri->index=5;
	printk("%s->%d\n",__func__,__LINE__);

	cdev_init(&mcp4725_pri->chrdev,&fops_mcp4725);
	ret=cdev_add(&mcp4725_pri->chrdev,MKDEV(major,mcp4725_pri->index),1);
	if(ret<0)
	{
	    printk("error:%s->%d\n",__func__,__LINE__);
		return -21;	
	}
    
	mcp4725_pri->device=device_create(cls,NULL,MKDEV(major,mcp4725_pri->index),
	             NULL,"mcp4725xx%d",mcp4725_pri->index);
    

	if(mcp4725_pri->device==NULL)
	{
		 printk("error:%s->%d\n",__func__,__LINE__);
		return -22;	
	}
	//mcp4725_pri->device->

	printk("%s->%d\n",__func__,__LINE__);

	return 0;
}

struct of_device_id of_match_table[]={
	{.compatible="MCP4725",},
	{}
};

struct i2c_driver  i2c_mcp4725={
	.driver={
		.name="i2c_MCP4725",
		.of_match_table=of_match_table,
	},
	.id_table=id_table,
	.probe=mcp4725_proble,
	.remove=mcp4725_remove,
} ;

 int __init mcp4725_init(void)
{
    int ret=0;
	int devno;

    //alloc_chrdev_region
	ret=alloc_chrdev_region(&devno,0,255,"mcp4725 for chardev");
	if(ret<0)
	{
	    printk("%s-->%d",__func__,__LINE__);
		return -20;
	}

	major=MAJOR(devno);
	cls=class_create(THIS_MODULE,"pdev char class");
	if(!cls)
	{
	    printk("%s-->%d",__func__,__LINE__);
		return -20;
	}

   ret=i2c_add_driver(&i2c_mcp4725);
   if(ret<0)
   {
	   printk("%s-->%d",__func__,__LINE__);
	   return -20;
   }
    printk("%s-->%d",__func__,__LINE__);
	   return 0;
}
 void __exit mcp4725_exit(void)
{

    i2c_del_driver(&i2c_mcp4725);
	class_destroy(cls);
	//unregister_chrdev_region
	unregister_chrdev_region(MKDEV(major,0),255);

	printk("%s->%d",__func__,__LINE__);
	return ;
}

module_init(mcp4725_init);
module_exit(mcp4725_exit);
MODULE_LICENSE("GPL");

测试APP 为:

#include "stdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>


int main(int argc,char** argv)
{
    char led1=0;
    char buf[10];
    int data;
    int fd=open("/dev/mcp4725xx5",O_WRONLY);
    if(fd<0)
    {
        printf("open error \r\n");
        return  -1;
    }
    data=atoi(argv[1]);
    unsigned short val=(short)(data)/4.7*4095;
    printf("clc:%d\r\n",val);
    write(fd,&val,sizeof(short));
    printf("exit\r\n");
    close(fd);
return 1;
}

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DAC MCP4725 i2c 驱动(linux) 的相关文章

  • 如何“grep”连续流?

    可以用吗grep在连续的流中 我的意思是有点tail f
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • bash双括号问题

    我对 bash 脚本非常陌生 在使用双括号时遇到了问题 我似乎无法让它们在 Ubuntu Server 11 10 中工作 我的下面的脚本位于 if test sh 中 bin bash if 14 14 then echo FOO fi
  • Mono 和 WebRequest 速度 - 测试

    在 mono 4 6 2 linux 中 我注意到 wget 下载文件的速度与webclient DownloadString 所以我做了一个小测试来调查 为什么 wget 明显比 C 快 根据我自己的实验 使用 wget 下载 手动读取文
  • Bash 中 $() 和 () 之间的区别

    当我打字时ls l echo file 支架的输出 这只是简单的回显 被获取并传递到外部ls l命令 就等于简单的ls l file 当我打字时ls l echo file 我们有错误 因为不能嵌套 内部外部命令 有人可以帮助我理解之间的区
  • 如何删除树莓派的相机预览

    我在我的 raspberryPi 上安装了 SimpleCv 并安装了用于使用相机板的驱动程序 uv4l 驱动程序 现在我想使用它 当我在 simpleCV shell Camera 0 getImage save foo jpg 上键入时
  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • Linux TCP服务器:在接受连接之前读取客户端的IP地址

    Related C Winsock API如何在接受连接之前获取连接客户端IP https stackoverflow com questions 716209 c winsock api how to get connecting cli
  • 将 stdout 作为命令行 util 的文件名传递?

    我正在使用一个命令行实用程序 该实用程序需要传递文件名以将输出写入 例如 foo o output txt 它唯一写入的东西stdout是一条消息 表明它运行成功 我希望能够通过管道传输写入的所有内容output txt到另一个命令行实用程
  • 如何阅读shell命令的源代码?

    我想阅读编写linux命令的实际源代码 我已经获得了一些使用它们的经验 现在我认为是时候与我的机器进行更深层次的交互了 我在这里找到了一些命令http directory fsf org wiki GNU http directory fs
  • UDP 广播发送失败:在 Linux 2.6.30 上“网络无法访问”

    我用udp广播写了一个程序 代码段如下 struct sockaddr in broadcast addr socklen t sock len sizeof broadcast addr bzero broadcast addr sock
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • Linux、ARM:为什么仅当启动时存在 I2C GPIO 扩展器时才创建 gpiochip

    在 imx6sx 硬件平台 NXP 嵌入式 ARM 上使用 Linux 3 14 52 问题是设备树中指定的 PCF8575 I2C GPIO 扩展器不会实例化为 sys class gpio 结构中的设备 除非它们在内核启动期间存在 这些
  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • 如何确保 numpy BLAS 库可用作动态加载库?

    The theano安装文档 http www deeplearning net software theano install html troubleshooting make sure you have a blas library指
  • 具有少量父设备属性的 udev 规则

    我需要复杂且通用的udev规则来确定插入任何 USB 集线器的特定端口的 USB 设备 所以 我必须结合设备树不同层的父属性 我有这个 udevadm info query all name dev ttyUSB0 attribute wa
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she

随机推荐

  • chatgpt赋能python:Python编程优化技巧

    Python编程优化技巧 为什么需要编程优化 Python是一种解释性语言 运行速度较慢 编写高效的Python程序是很有必要的 当我们需要处理大量数据 或者运行时间敏感的任务时 优化Python程序对于提高效率是至关重要的 怎样提高Pyt
  • 华为OD机试 C++ 【查字典】

    题目 题目 描述 给你一个 头 就是词的开始部分 和一个单词清单 你需要找出哪些单词是以这个 头 开始的 输出 所有以这个 头 开始的单词 每个单词一行 如果一个都没有 输出 1 输入 abc 4 a ab abc abcd 输出 abc
  • 项目结构的合理性

    以下仅为个人观点 如有好的建议请多多指教 1 有时为了项目以后修改 迭代 或者相似功能的开发 可能会对某些模块进行封装 近期所做的项目整体进行了自动化封装 个人认为封装过度其实是对后续业务并没有太多好处 反而造成项目随着时间的推移 业务发展
  • sessionStorage 问题

    问题描述 列表页点击进详情页的时候数据没加载到 查看前端代码 在跳转的时候取的列表页数据存到sessionStorage里面 function getCollarDetails index var rows coupon list tabl
  • jQuery 入门教程(21): jQuery UI 示例

    上篇介绍了使用jQuery UI基本工作过程 后面就逐个介绍jQuery UI库内置的UI组件 支持的拖放 动画效果等 如果你之前看过Yii Framework教程 PHP Yii Framework封装了jQuery UI组件 有兴趣的可
  • SqlServer 存储过程(生成订单)

    当在 SQL Server 中处理订单时 使用存储过程可以提供更高效和可维护的解决方案 存储过程是一组预编译的 SQL 语句 可以在数据库中执行 并且可以通过参数进行自定义 通过使用存储过程 可以将常见的业务逻辑封装起来 以便在需要时进行重
  • error while loading shared libraries: ../../lib/libopencv_core.so

    error while loading shared libraries lib libopencv core so 原文 http blog chinaunix net uid 27134408 id 5122776 html 最近做Op
  • SonarQube - org.sonar.process.MessageException: Unsupported JDBC driver provider: mysql

    使用docker安装最新的SonarQube 启动SonarQube报错 Exception in thread main org sonar process MessageException Unsupported JDBC driver
  • [shell编程]、()、(())、[]、[[]]的区别

    默认的变量类型是字符串 所以 str1 str2 就是一串字符串 我们想要判断它们是否相等必须使用中括号 str1 str2 1 中括号 表示条件测试 注意这里的空格很重要 要注意在 后面和 前面都必须要有空格 常用判断 d FILE 如果
  • 企业为什么要融资和上市

    这里面涉及到两个概念 即融资和上市 让我们先来理理这两者之间的逻辑辩证关系 其实根据我们的观察和调研发现 目前市场上许多人对上市这件事有着十分魔性的认知 小A觉得上市前融资轮次越多越好 小B认为上市后就是为了圈钱 小C觉得IPO的速度越快越
  • ISP之DPC(坏点校正)模块

    DPC Defective Photosites Correction即坏点校正 一 DPC的意义 图像传感器上由于自身工艺技术造成的瑕疵 如光线采集的点存在缺陷 导致在光电转换过程中某些像素值不准确 我们称之为坏点 Defect Pixe
  • 星环科技线上技术分享课“星课堂”开播,快来一探究竟

    星课堂 深度解读系列上线啦 4 9月 10期线上课带你深度了解星环科技2021全系列新品细节 关于星环科技 星环科技致力于打造 云计算 大数据 数据库 人工智能 的基础平台产品 领航基础软件新纪元 经过多年自主研发 星环科技建立了多个产品系
  • Mysql事务隔离机制

    SQL隔离机制 所谓隔离机制 指的是读与写之间的隔离 指的是在多事务并行的时候 A事务的读与B事务的写之间的隔离 也就是说B事务的写对A事务的可见性 多事务并发运行的时候 同时读写一个数据 可能会出现脏写 脏读 不可重复读 幻读几个问题 脏
  • 业务系统从阿里云物联网平台获取设备数据的3种方案——实践类

    在企业IoT业务场景中 往往需要将设备上报到IoT物联网平台的数据进行加工处理 存储到数据库中 以便供业务系统使用 物联网平台提供了3种获取数据的方式 通过阿里云POP API获取设备数据 通过HTTP 2服务端订阅取设备数据 通过规则引擎
  • iframe框架标签(内嵌窗口)iframe和a标签的联合使用

    iframe框架 内嵌窗口 标题描述 iframe标签它可以在一个html页面上 打开一个小窗口 去加载一个单独的页面 iframe和a标签的联合使用的步骤 1 在iframe标签中使用name属性定义一个名称 2 在a标签的target属
  • C++实现集群聊天服务器

    写在前面 所有代码加起来两千行 里面用到了语言 数据结构 计网 操作系统 数据库 redis等知识 可谓是麻雀虽小五脏俱全 1 项目需求 客户端新用户注册 客户端用户登录 添加好友和添加群组 好友聊天 群组聊天 离线消息 nginx配置tc
  • ie11兼容方案(ant-design-vue在ie打开,系统白屏不报错)

    问题1 整个系统白屏 但不报错 原因 1 没有做路由懒加载 不做懒加载的话 默认是全部加载在首屏 ie浏览器性能差直接卡死 2 ie无法识别一些es6 的api Babel默认只转换新的js语法 如箭头函数 而不转换新的API 比如 Ite
  • jeesite前端页面与后台业务逻辑数据交互

    Key Word jsp controller json model parameter request response result param ajax data success http 1 jsp中提交请求的方式有哪些 get p
  • 【STM32学习】——定时器输出比较功能&PWM脉宽调制&通用/高级定时器输出比较通道&舵机/直流电机简介&PWM驱动呼吸灯/舵机/直流电机代码实操

    文章目录 前言 一 输出比较简介 二 PWM波形 三 输出比较通道 1 通用定时器 2 高级定时器 三 外设简介 1 舵机 2 直流电机 四 实操案例 1 PWM驱动LED呼吸灯 2 PWM驱动舵机 3 PWM驱动直流电机 总结 声明 学习
  • DAC MCP4725 i2c 驱动(linux)

    mcp4725是一款低功耗 高精度 单通道 拥有EEPROM的12位的dac 由于最近项目中使用到了该芯片所以贴出来给大家参考 步进电机电机芯片半流锁定 本贴呢非项目中使用的平台 主要是想在linux 下实现对该器件的使用 实现一个简单的i