来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版)

作者:韦东山

本文字数:3776,阅读时长:5分钟

我们现在来讲I2C控制器怎么写,它是I2C程序中最核心的地方,我们要先构造几个结构体,这几个结构体放在i2c_controller.h里面。

我们要发出I2c传输时,要构造出i2c_msg,把构造出的i2c_msg扔给下面的i2c_controller.c,i2c_controller.c会选择某一个i2c控制器,使用里面的master_xfer来传输数据, 所以我们需要构造出一个i2c_controller结构体。

i2c_controller.h文件

文件的内容如下所示:

#ifndef _I2C_CONTROLLER_H#define _I2C_CONTROLLER_Htypedef struct i2c_msg {unsigned int addr;  /* 7bits */int flags;  /* 0 - write, 1 - read */int len;int cnt_transferred;unsigned char *buf;}i2c_msg, *p_i2c_msg;typedef struct i2c_controller {int (*int)(void);int (*master_xfer)(i2c_msg msgs, int num);char *name;}i2c_controller, *p_i2c_controller;#endif /* _I2C_CONTROLLER_H */

解析:我们构造这两个结构体,我们要把它放在i2c_controller.c把它用起来,

i2c_controller.c文件

文件的内容如下所示:

include "i2c_controller.h"#define I2C_CONTROLLER_NUM 10/* 有一个i2c_controller数组用来存放各种不同芯片的操作结构体 */static p_i2c_controller p_i2c_controllers[I2C_CONTROLLER_NUM];static p_i2c_controller p_i2c_con_selected;void register_i2c_controller(p_i2c_controller *p){int i;for (i = 0; i < I2C_CONTROLLER_NUM; i++){if (!p_i2c_controllers[i]){p_i2c_controllers[i] = p;return;}}}

解析:register_i2c_controller函数用于把参数中的结构体指针,注册到p_i2c_controllers指针数组中。

/* 根据名字来选择某款I2C控制器 */int select_i2c_controller(char *name){int i;for (i = 0; i < I2C_CONTROLLER_NUM; i++){if (p_i2c_controllers[i] && !strcmp(name, p_i2c_controllers[i]->name)){p_i2c_con_selected = p_i2c_controllers[i];return 0;}}return -1;}

解析:select_i2c_controller函数根据参数中的名字(name) 从p_i2c_controllers指针数组中取出对应的结构体指针复制给p_i2c_con_selected结构体指针(静态全局变量)。

/* 实现 i2c_transfer 接口函数 */int i2c_transfer(i2c_msg msgs, int num){return p_i2c_con_selected->master_xfer(msgs, num);}

解析:i2c_transfer接口函数,调用选择的p_i2c_con_selected成员中master_xfer函数。

void i2c_init(void){/* 注册下面的I2C控制器 */s3c2440_i2c_con_add();/* 选择某款I2C控制器 *//* 调用它的init函数 */}

解析:s3c2440_i2c_con_add()函数,把定义的s3c2440_i2c_con结构体注册到p_i2c_controllers数组中。

s3c2440_i2c_controller.c文件

中断服务函数,当发成中断时,就会调用中断服务函数,代码如下

void i2c_interrupt_func(int irq){/* 每传输完一个数据将产生一个中断 *//* 对于每次传输, 第1个中断是"已经发出了设备地址" */}

s3c2440_i2c_con_init函数,用来初始化I2C,控制器代码如下:

void s3c2440_i2c_con_init(void){/* 设置时钟 *//* [7] : IIC-bus acknowledge enable bit, 1-enable in rx mode * [6] : 时钟源, 0: IICCLK = fPCLK /16; 1: IICCLK = fPCLK /512 * [5] : 1-enable interrupt * [4] : 读出为1时表示中断发生了, 写入0来清除并恢复I2C操作 * [3:0] : Tx clock = IICCLK/(IICCON[3:0]+1). * Tx Clock = 100khz = 50Mhz/16/(IICCON[3:0]+1) */IICCON = (0<<6) | (1<<5) | (30<<0);/* 注册中断处理函数 */register_irq(27, i2c_interrupt_func);}

解析:

1).IICCON = (0<<6) | (1<<5) | (30<<0); 设置IICCON控制寄存器。选择发送时钟,使能中断。

2).register_irq(27, i2c_interrupt_func):注册中断处理函数,当发生I2C中断的时候就会调用i2c_interrupt_func中断处理函数。

初始化完成后,就可以调用do_master_tx写I2C从机了,这个函数仅仅启动I2C传输,然后等待,直到数据在中断服务程序中传输完毕后再返回。函数代码如下:

void do_master_tx(p_i2c_msg msg){msg->cnt_transferred = 0;/* 设置寄存器启动传输 *//* 1. 配置为 master tx mode *//* 2. 把从设备地址写入IICDS */IICDS = msg->addr<<1;/* 3. IICSTAT = 0xf0 , 数据即被发送出去, 将导致中断产生 */IICSTAT = 0xf0;/* 后续的传输由中断驱动 *//* 循环等待中断处理完毕 */while (msg->cnt_transferred != msg->len);}

解析:

1).IICDS = msg->addr<<1: 把从机地址(高7位,所以需要向右移一位)写入到IICDS寄存器中。

2).IICSTAT = 0xf0:设置IICSTAT寄存器,将s3c2440设为主机发送器,并发出S信号后,紧接着就发出从机地址。后续的传输工作将在中断服务程序中完成。

do_master_rx函数的实现和do_master_tx函数类似,代码如下:

void do_master_rx(p_i2c_msg msg){msg->cnt_transferred = 0;/* 设置寄存器启动传输 *//* 1. 配置为 Master Rx mode *//* 2. 把从设备地址写入IICDS */IICDS = (msg->addr<<1)|(1<<0);/* 3. IICSTAT = 0xb0 , 从设备地址即被发送出去, 将导致中断产生 */IICSTAT = 0xb0;/* 后续的传输由中断驱动 *//* 循环等待中断处理完毕 */while (msg->cnt_transferred != msg->len);}

解析: 1).IICDS = (msg->addr<<1)|(1<<0):把从设备地址写入IICDS,前7位是从机地址,第8位表示传输方向(0表示写操作,1表示读操作)。

s3c2440传输函数,根据标志位flags,来指明是读/写(1:读 0:写)。代码如下:

int s3c2440_master_xfer(p_i2c_msg msgs, int num){int i;for (i = 0; i < num; i++){if (msgs[i]->flags == 0)/* write */do_master_tx(msgs[i]);elsedo_master_rx(msgs[i]);}}

我们定义一个i2c_controller结构体s3c2440_i2c_con。下面的代码对他进行初始化。

static i2c_controller s3c2440_i2c_con = {.name = "s3c2440",.init = s3c2440_i2c_con_init,.master_xfer = s3c2440_master_xfer,};

s3c2440_i2c_con_add函数把上面定义的s3c2440_i2c_con结构体注册到上层的i2c_controller数组中。

void s3c2440_i2c_con_add(void){register_i2c_controller(&s3c2440_i2c_con);}

「新品首发」STM32MP157开发板火爆预售!首批仅300套

controller控制器怎么写_I2C控制器编程_框架相关推荐

  1. php ci 参数,CI如何写一个控制器,并传递参数正常解析访问?

    控制器 控制器是你整个应用的核心,因为它们决定了 HTTP 请求将被如何处理. 什么是控制器? 简而言之,一个控制器就是一个类文件,是以一种能够和 URI 关联在一起的方式来命名的. 考虑下面的 UR ...

  2. 智能空调检测程序c语言,基于单片机的智能空调节电控制器毕业设计论文C语言编程.doc...

    基于单片机的智能空调节电控制器毕业设计论文C语言编程 目录 TOC \o "1-3" \u 第1章引言 PAGEREF _Toc231960072 \h 1 1.1传感器的概述和应 ...

  3. 学习FPGA有必要写SDRAM控制器吗?

    在学习FPGA的过程中,注意是在学习过程中,联系FPGA的使用技巧,强烈建议尝试设计一个SDRAM控制器,不要使用IP核. 学习SDRAM控制器设计,能让你掌握很多知识. 更好的使用状态机去精准控制时 ...

  4. 代写python作业费用标准_代做159.272作业、代写Programming Paradigms作业、代做Python实验作业、代写Java/c++编程作业代写Database|代做R...

    代做159.272作业.代写Programming Paradigms作业.代做Python实验作业.代写Java/c++编程作业代写Database|代做RComputational Thinkin ...

  5. 大学生计算机python_人人都能学计算机:计算机科学入门与Python编程_学堂在线章节测试答案...

    查看答案 人人都能学计算机:计算机科学入门与Python编程_学堂在线章节测试答案 单击图层调板下方的新图层按钮可以产生新图层.A:错B:对 在图示的薄壁杆件截面图形中,形心与弯曲中心重合的截面有() ...

  6. 开源SDN控制器和商用SDN控制器一览

    以下是来自IT168收集的2014年可追寻到的开源SDN控制器和商用SDN控制器,此处转载以供大家知悉,更多控制器信息需要大家自己动手去查询和理解. 开源SDN控制器组织(随机排序,仅为了查看便利) ...

  7. php关于控制器和操作系统,ThinkPHP控制器学习(一)

    星空 多层控制器的使用 TP3.23对控制器做了更加细致的分层,除了默认的Controller层,还可以自定义事件控制层Event. 建立的方法是: 在模块第一级目录,即Controller层的同级目 ...

  8. Java Review - 并发编程_读写锁ReentrantReadWriteLock的原理源码剖析

    文章目录 ReentrantLock VS ReentrantReadWriteLock 类图结构 非公平的读写锁实现 写锁的获取与释放 void lock() void lockInterrupti ...

  9. 第2课第3节_Java面向对象编程_继承性_P【学习笔记】

    摘要:韦东山android视频学习笔记  面向对象程序的三大特性之继承性:继承性的主要作用就是复用代码.继承性也有一定的限制,如图一 图一 1.我们在第2课第2节_Java面向对象编程_封装性_P 中 ...

最新文章

  1. 时空AI技术:深度强化学习在智能城市领域应时空AI技术:深度强化学习在智能城市领域应用介绍...
  2. VMware的安装教程
  3. 为UINavigationBar添加自定义背景
  4. delphi中Label中文显示不全的问题解决办法
  5. nginx 的请求处理、请求的处理流程
  6. 动态规划_leetcode322
  7. ct与x光的哪个辐射大_胸片、CT、PET/CT哪个辐射大?结果你很难猜到
  8. 完全卸载oracle11g
  9. MySQL innodb下的记录锁,间隙锁,next-key锁
  10. OpenCV绘制半透明效果的代码
  11. 测试的重要性:蚊子让快递柜的触摸失灵
  12. Android计算器(仿小米计算器)
  13. Vim编辑器学习笔记
  14. Spring Cloud Gateway源码解析
  15. 年轻人要明白,职场里不只有晋升
  16. 风云滚滚唱英雄,云的江湖谁做主?
  17. pysot 中的异步多进程切图
  18. Unity 打包和切换平台|Build Settings窗口介绍
  19. 白炽灯护眼还是LED护眼?盘点专业护眼的LED护眼灯
  20. Java基础语法小结

热门文章

  1. JS中的间歇(周期)调用setInterval()与超时(延迟)调用setTimeout()相关总结
  2. Html5中Canvas(画布)的使用
  3. HTML基础知识(常见元素、列表、链接元素、图片元素)
  4. Huffman树学习
  5. node.js基础:数据存储
  6. 关于eclipse的indigo版中文注释时字体太小的问题(转)
  7. SuperSpider——打造功能强大的爬虫利器
  8. 从程序员到项目经理(15):项目管理三大目标
  9. 一个很不错的wp企业站模板
  10. MySQLdb安装的错误说明