• 正文
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard ELF 1板卡-i2c与从设备通讯编程示例之i2c编写程序

2024/10/31
801
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

对于我们ELF 1板卡来说,我们前面看到的i2c-0、i2c-1总线对应着CPU的两个i2c适配器,作为主设备,而总线上挂载的设备作为从设备。如/dev/i2c-1对应的适配器作主设备,其上面挂载的光线传感器就作为从设备。

前面我们了解了i2c的通讯协议,也初步用i2c-tools尝试着读写了一个从设备寄存器。下面我们进入代码,看一下如何用代码读取光线传感器的光照值。

注意:在读取光线传感器的数据寄存器之前,需要先开启ADC电源和启动ADC测量,即在CONTROL寄存器写入0x03这个数据,CONTROL的寄存器地址为0x00,由于bh1726的寄存器地址需要加上0x80的偏移地址,所以CONTROL的地址为0x80。也就是将0x03这个数据写入到0x80中。

查看i2c总线节点

Linux内核代码文件include/linux/i2c-dev.h中针对每个i2c总线生成一个设备节点,实现了文件操作接口,用户空间可以通过i2c设备节点访问i2c适配器。适配器的编号从0开始,和适配器的设备节点的次设备号相同。

通过代码操控i2c适配器,必须包含以下头文件:

查看i2c设备节点:

 i2c设备节点是/dev/i2c-x,其中x是数字,代表i2c总线的编号。

打开设备

需要用到open()函数打开主设备i2c适配器,并获得文件描述符:

使用open()打开/dev/i2c-1总线,如果打开节点失败,会返回节点名称并输出"Can't Open i2c device"。

写寄存器

①创建消息结构体

i2c控制器和从设备之间通讯的消息,通常是储存在一个结构体中,首先,定义了一个i2c_rdwr_ioctl_data结构体,用于存储i2c通信相关的消息,我们需要规定好消息的数量,以及给这个消息申请一块空间。

②设置i2c参数

设置要写入数据的相关信息:

(一)work_queue.nmsgs被设置为1,表示只有一个消息要发送;

(二)(work_queue.msgs[0]).len被设置为2,表示要写入的数据长度;

(三)(work_queue.msgs[0]).flags被设置为0,表示写操作;

(四)(work_queue.msgs[0]).addr被设置为devaddr,表示要写入数据的设备地址。

(五)(work_queue.msgs[0]).buf通过动态内存分配了足够的空间,并将数据写入其中。首先在第一个字节位置(work_queue.msgs[0]).buf[0]写入设备地址reg,然后使用memcpy函数将要写入的数据buf拷贝到后续的字节位置。

③写入数据

调用ioctl函数执行i2c写操作,并将返回值赋给ret。如果返回值小于0,则打印错误信息。

释放动态分配的内存,因为前面有两处调用了malloc(),所以这里需要释放两次内存,包括(work_queue.msgs[0]).buf和work_queue.msgs,然后返回ret。

读寄存器

①创建消息结构体

i2c控制器和从设备之间通讯的消息,通常是储存在一个结构体中,首先,定义了一个i2c_rdwr_ioctl_data结构体,用于存储i2c通信相关的消息,我们需要规定好消息的数量,以及给这个消息申请一块空间。

②写寄存器地址

设置要写入数据的相关信息:

(一)work_queue.nmsgs被设置为1,表示只有一个消息要发送;

(二)(work_queue.msgs[0]).len被设置为1,表示要写入的数据长度;

(三)(work_queue.msgs[0]).flags被设置为0,表示写操作;

(四)(work_queue.msgs[0]).addr被设置为devaddr,表示要写入数据的设备地址。

(五)(work_queue.msgs[0]).buf通过动态内存分配了足够的空间,并将寄存器地址写入其中。

调用ioctl函数执行i2c写操作,并将返回值赋给ret。如果返回值小于0,则打印错误信息。

③读寄存器

储存的i2c通讯所需信息

设置要写入数据的相关信息:

(一)(work_queue.msgs[0]).len被设置为1,表示要写入的数据长度

(二)(work_queue.msgs[0]).flags被设置为0,表示写操作;

(三)(work_queue.msgs[0]).addr被设置为devaddr,表示要写入数据的设备地址。

调用ioctl函数执行i2c读操作,并将返回值赋给ret。如果返回值小于0,则打印错误信息。

释放动态分配的内存,因为前面有两处调用了malloc(),所以这里需要释放两次内存,包括(work_queue.msgs[0]).buf和work_queue.msgs,然后返回ret。

关闭设备

需要用到close()函数关闭主设备i2c适配器。

i2c简单读取寄存器简单代码

飞凌嵌入式

飞凌嵌入式

保定飞凌嵌入式技术有限公司,创建于2006年,是一家专注嵌入式核心控制系统研发、设计和生产的高新技术企业,是国内较早专业从事嵌入式技术的企业之一。 经过十几年的发展与积累,公司拥有业内优秀的软硬件研发团队,在北京及保定建立两大研发基地,在苏州、深圳设有华东、华南技术服务中心,并在北美、欧洲以及亚太等其他国家和地区拥有国际业务网络。公司研发的智能设备核心平台广泛应用于物联网、工控、轨道交通、医疗、电力、商业电子、智能家居、安防、机器人、环境监测等诸多领域。

保定飞凌嵌入式技术有限公司,创建于2006年,是一家专注嵌入式核心控制系统研发、设计和生产的高新技术企业,是国内较早专业从事嵌入式技术的企业之一。 经过十几年的发展与积累,公司拥有业内优秀的软硬件研发团队,在北京及保定建立两大研发基地,在苏州、深圳设有华东、华南技术服务中心,并在北美、欧洲以及亚太等其他国家和地区拥有国际业务网络。公司研发的智能设备核心平台广泛应用于物联网、工控、轨道交通、医疗、电力、商业电子、智能家居、安防、机器人、环境监测等诸多领域。收起

查看更多

相关推荐