当前位置: 首页 > news >正文

【物联网智能网关-07】PCF8591 AD转换模块I2C通信实现

.NET Micro Framework 和.NET Compact Framework不同,并不是.NET Framework的子集,而是更贴近硬件底层,它提供了许多诸如GPIO、PWM、SPI、I2C和OneWire等硬件操作类库。由此可以让普通的软件开发人员相对平滑的过度到硬件开发领域,也足以让以前相对封闭的硬件系统通过二次开发的方式扩展硬件模块成为一种流行(随着物联网技术的深入发展,未来软件不仅需要组态化,硬件其实更需要组态化)。

由于非硬件研发出身,最早接触I2C接口是在2007年初次接触.NET Micro Framework的时候,当时并没有和实际的硬件打交道,而是从软件层面封装了一个可以进行I2C总线虚拟通信的模拟器(参见博文《.Net Micro Framework研究—带I2C总线的模拟器》),后来在2008年为TI DM355的芯片移植.NET Micro Framework,我的任务就是I2C、USB等硬件驱动的开发。在TI DM355上有一个红外遥控接收器单元(MSP430单片)和DM355通过I2C接口进行通信,从而让.NET Micro Framework可以接收遥控器的按键信息。

后续在Cortex-M3平台,所接触的模块都是SPI接口的,I2C接口的反而没有,所以相关接口一直没有调试。最近有一个客户在使用物联网智能网关时候,发现引出的IO不够,需要扩展几路AD,推荐了一个基于PCF8591芯片的AD/DA转换模块,所以我才得以再次深入研究I2C接口。

如下是.NET Micro Framework的I2C接口类库:

public class I2CDevice : IDisposable

    {

        public I2CDevice.Configuration Config;

        protected bool m_disposed;

        public I2CDevice(I2CDevice.Configuration config);

        public static I2CDevice.I2CReadTransaction CreateReadTransaction(byte[] buffer);

        public static I2CDevice.I2CWriteTransaction CreateWriteTransaction(byte[] buffer);

        public void Dispose();

        public int Execute(I2CDevice.I2CTransaction[] xActions, int timeout);

        public class Configuration

        {

            public readonly ushort Address;

            public readonly int ClockRateKhz;

            public Configuration(ushort address, int clockRateKhz);

        }

        public sealed class I2CReadTransaction : I2CDevice.I2CTransaction{}

        public class I2CTransaction

        {

            public readonly byte[] Buffer;

            protected I2CTransaction(byte[] buffer);

        }

        public sealed class I2CWriteTransaction : I2CDevice.I2CTransaction{}

   }

 

I2C的读写操作通过定义I2CDevice.I2CTransaction数组,可以实现批量操作。

物联网智能网关基于STM32F207/STM32F407芯片,其I2C接口即支持主模式也支持从模式(I2C接口类仅支持主模式),总线速度支持两种,标准速度(高达100KHz)和快速(400KHz),I2C地址支持7位和10位两种(驱动只支持7位地址)。

PCF8591芯片是8位A/D和D/A转换器,4路模拟输入,1路模拟输出。其I2C地址是可以进行硬件编码的(3个地址引脚A0、A1和A2),其地址编码规则如下:

固定部分

编码部分

 

1

0

0

1

A2

A1

A0

R/W

最高位                               最低位

        

对I2C来说,一般读操作的时候地址的最低位为1,写操作的时候地址的最低位为0。我们选用的模块,看原理图可知,A2、A1和A0管脚都被直接连接到GND,所以这部分都是0,所以对读地址来说是0x91,写地址是0x90。.NET Micro Framework底层I2C驱动实现的时候,地址会自动左移,最低位是不算地址的一部分的(所以才说是7位地址支持),所以我们在填写I2C模块地址的时候,要填写的是读地址(或写地址)右移一位的数字,也就是0x48。

总线频率我们理论上可以选择10K到400K,这里我们选择100K。

下面我们详细介绍一下PCF8591是如何进行AD读取和DA输出的。

读AD操作:

写操作

读操作

地址

控制字

地址

AD数据

    

写DA操作

写操作

地址

控制字

DA数据

 

控制字的定义如下:

0

X

X

X

0

X

X

X

 

DA标志

模拟输入模式

 

自动增量

通道号:0~3

对AD0~AD3通道来说,我们常用的控制字的值为0x0,0x1,0x2,0x3。

对DA来说,我们常用的控制字的值为0x40。

注意:如果我们循环读取AD0至AD3,由于读周期读取的AD转换值,其实是上一次的转换结果,所以我们读取AD1的时候,其实是读取的AD0,依次类推(上电第一次读取的值是0x80)。

有了以上知识,我们就可以进行编程了,核心代码如下:

    

  public static void Main()

      {

           I2CDevice I2CBus = new I2CDevice(new I2CDevice.Configuration(0x48, 100));

            byte[] bytAD = new byte[4];

            byte bytDA = 0;

            while (true)

            {

                for (byte i = 0; i < 4; i++)

                {

                    byte[] bytWData = new byte[1] { i };

                    byte[] bytRData = new byte[1];

                    I2CDevice.I2CTransaction[] i2c = new I2CDevice.I2CTransaction[2];

                    i2c[0] = I2CDevice.CreateWriteTransaction(bytWData);

                    i2c[1] = I2CDevice.CreateReadTransaction(bytRData);

                    I2CBus.Execute(i2c, 100);

                    bytAD[i - 1 < 0 ? 3 : i - 1] = bytRData[0];

                }

                Debug.Print("AD0=" + ShowData(bytAD[0]) + " AD1=" + ShowData(bytAD[1]) + " AD2=" + ShowData(bytAD[2]) + " AD3=" + ShowData(bytAD[3]));

                byte[] bytWData1 = new byte[2] { 0x40, bytDA };

                I2CDevice.I2CTransaction[] i2c1 = new I2CDevice.I2CTransaction[1];

                i2c1[0] = I2CDevice.CreateWriteTransaction(bytWData1);

                I2CBus.Execute(i2c1, 100);

                Debug.Print("DA0=" + ShowData(bytDA));

                bytDA += 10;

                Thread.Sleep(1000);

            }

        }

PCF8591模块和物联网智能网关接线有四根,分别是VCC、GND、SCL和SDA,VCC可以接5V或3.3V(我们接3.3V)、SCL接PB6,SDA接PB7。程序部署运行的效果图如下: 

通过旋转模块的上的模拟开关,我们会发现AD3的值可以由0向255变化。

注意:为了正常运行本实例,物联网智能网关固件版本需要升级到V1.7.15以上,TinyBooter也需要同步升级。

固件下载地址:http://www.sky-walker.com.cn/MFRelease/firmware/MFv42_YF_Wisteria207.rar

----------------------   

源码下载:http://www.sky-walker.com.cn/MFRelease/Sample/PCF859IT_I2C.rar

MF简介:http://blog.csdn.net/yefanqiu/article/details/5711770

MF资料:http://www.sky-walker.com.cn/News.asp?Id=25

转载于:https://www.cnblogs.com/yefanqiu/archive/2012/08/04/2622608.html

相关文章:

  • 《iPhone应用程序开发名家解析》勘误表
  • 原创钢琴曲 《夏季来临之前的歌》
  • PPT(PowerPoint2007)制作技巧(持续更新 by 2010.7.28)
  • Tomcat并发数优化的方法总结
  • C和lua的互相调用
  • Win8 RTM 安装到 UEFI PC
  • 做好一个team leader的几点看法
  • 招聘信息NO.5
  • 基于maven和hudson打造持续集成环境
  • 网络字节流数据解析组件的设计与实现--Circular Buffer(Ring Buffer)
  • 小工具 cl-launch , 创建 lisp 执行脚本
  • 从“青年创业基金”说起
  • 云服务系列:Windows Azure SDK for .NET(2012 年 6 月发布的版本)的最新消息
  • vim 键盘图
  • VC++实现感染文件式加载DLL文件
  • Angular 2 DI - IoC DI - 1
  • HTTP--网络协议分层,http历史(二)
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • MYSQL 的 IF 函数
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • Vue ES6 Jade Scss Webpack Gulp
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 分享一份非常强势的Android面试题
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 马上搞懂 GeoJSON
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 微服务入门【系列视频课程】
  • raise 与 raise ... from 的区别
  • # Apache SeaTunnel 究竟是什么?
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • (20050108)又读《平凡的世界》
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (4)Elastix图像配准:3D图像
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (HAL库版)freeRTOS移植STMF103
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (五)IO流之ByteArrayInput/OutputStream
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)c++ std::pair 与 std::make
  • (转)Google的Objective-C编码规范
  • (转)Scala的“=”符号简介
  • .apk文件,IIS不支持下载解决
  • .bat批处理(六):替换字符串中匹配的子串
  • .net 获取url的方法
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .Net程序帮助文档制作
  • .Net组件程序设计之线程、并发管理(一)
  • /3GB和/USERVA开关
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @JsonSerialize注解的使用
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [ C++ ] STL---仿函数与priority_queue
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码