模拟IIC总线汇编程序软件包
一、概述
为了非常方便地对 I2C 从器件进行快速的、正确的读写操作,我们为此而设计出虚拟 I2C 总线操作平台软件包。本软件包是主方式下的虚拟 I2C 总线软件包,只要用户给子程序提供几个主要的参数,即可轻松地完成任何 I2C 总线外围器件的应用程序设计。
I2C 总线是 PHILIPS 公司推出的芯片间串行数据传输总线,2 根线(SDA、SCL)即可实现完善的全双工同步数据传送,能够十分方便地地构成多机系统和外围器件扩展系统。I2C 器件是把 I2C 的协议植入器件的 I/O 接口,使用时器件直接挂到 I2C 总线上,这一特点给用户在设计应用系统带来了极大的便利。I2C 器件无须片选信号,否选中是由主器件发出的 I2C 从地址决定的,而 I2C 器件的从地址是由 I2C 总线委员会实行统一发配。我们推出的 I2C 总线的操作平台软件包,只要你给出器件从地址[,子地址,注 PCF8574 无子地址 ] 即可进行字节读、字节写、多字节读、多字节写,能够非常方便地使用 I2C 器件,无须你介入底层的 I2C 操作协议。
二、编程序软件包
此软件包是用在单主 I2C 总线上,硬件接口是SDA、SCL,使用MCU 的 I/O 口来模拟 SDA/SCL 总线。设计有/无子地址的子程序是根据 I2C 器件的特点,目的在于将地址和数据彻底分开。软件包的接口界面为
IRDBYTE 无子地址 读单字节数据 现行地址读
IWRBYTE 无子地址 写单字节数据 现行地址写
IRDNBYTE 有子地址 读 N 字节数据
IWRNBYTE 有子地址 写 N 字节数据
说明:现行地址读/写即专指无子地址的器件,不给定子地址的读/写操作。
软件包占用内部资源:R0 R1 R2 R3 ACC Cy。
使用前须定义变量:SLA 器件从地址,SUBA 器件子地址,NUMBYTE 读/写的字节数,位变量 ACK
使用前须定义常量:SDA、SCL 总线位,MTD 发送数据缓冲区首址, MRD 接收数据缓冲区首址。
;**************************************************************************************
;VI2C_ASM.ASM
;I2C 软件包的底层子程序,使用前要定义好 SCL 和 SDA。在标准 80C51 模式(12 Clock)下,对主频要求是;不高于 12MHz(1 个机器周期 1us);若 Fosc>12MHz,则要增加相应的 NOP 指令数.;在使用本软件包时,请在你的程序的未尾加入$INCLUDE (VI2C_ASM.ASM)即可
;*************************************************************************************
;启动 I2C 总线子程序
START:
SETB SDA ;setb:一个指令周期,一个机器周期,1us
NOP ;nop:一个指令周期,一个机器周期,1us
SETB SCL ;起始条件建立时间大于 4.7us
NOP
NOP
NOP
NOP
NOP
CLR SDA ;clr:一个指令周期,1us
NOP ;起始条件锁定时大于 4us
NOP
NOP
NOP
NOP
CLR SCL ;钳住总线,准备发数据
NOP
RET ;ret:2个指令周期,2us
;结束总线子程序
STOP:
CLR SDA
NOP
SETB SCL ;发送结束条件的时钟信号
NOP ;结束总线时间大于 4us
NOP
NOP
NOP
NOP
SETB SDA ;结束总线
NOP ;保证一个终止信号和起始信号的空闲时间大于 4.7us
NOP
NOP
NOP
RET
;发送应答信号子程序
MACK:
CLR SDA ;将 SDA 置 0
NOP
NOP
SETB SCL
NOP ;保持数据时间 即 SCL 为高时间大于 4.7us
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;发送非应答信号
MNACK:
SETB SDA ;将 SDA 置 1
NOP
NOP
SETB SCL
NOP
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
; 检查应答位子程序
; 返回值,ACK=1 时表示有应答
CACK:
SETB SDA
NOP
NOP
SETB SCL
CLR ACK
NOP
NOP
MOV C,SDA
JC CEND ;jc:2个指令周期,2us
SETB ACK ;判断应答位
CEND:
NOP
CLR SCL
NOP
RET
;发送字节子程序
;字节数据放入 ACC
;每发送一字节要调用一次CACK子程序,取应答位
WRBYTE:
MOV R0,#08H
WLP:
RLC A ;取数据位 rlc:1个指令周期,1us
JC WR1
SJMP WR0 ;判断数据位 sjmp:2个指令周期,2us
WLP1:
DJNZ R0,WLP ;djnz:2个指令周期,2us
NOP
RET
WR1:
SETB SDA ;发送 1
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
WR0:
CLR SDA ;发送 0
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
;读取字节子程序
;读出的值在 ACC
;每取一字节要发送一个应答/非应答信号
RDBYTE:
MOV R0,#08H
RLP:
SETB SDA
NOP
SETB SCL ;时钟线为高,接收数据位
NOP
NOP
MOV C,SDA ;读取数据位
MOV A,R2
CLR SCL ;将SCL拉低,时间大于4.7us
RLC A ;进行数据位的处理
MOV R2,A
NOP
NOP
NOP
DJNZ R0,RLP ;未够8位,再来一次
RET
; 无子地址器件写字节数据
; 入口参数: 数据为 ACC 器件从地址SLA
; 占用: A R0 CY
IWRBYTE:
PUSH ACC
IWBLOOP:
LCALL START ;起动总线
MOV A,SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETWRB ;无应答则跳转
POP ACC ;写数据
LCALL WRBYTE
LCALL CACK
LCALL STOP
RET
RETWRB:
POP ACC
LCALL STOP
RET
;无子地址器件读字节数据
;入口参数: 器件从地址 SLA
;出口参数: 数据为 ACC
;占用 AR0 R2CY
IRDBYTE:
LCALL START
MOV A,SLA ;发送器件从地址
INC A
LCALL WRBYTE
LCALL CACK
JNB ACK,RETRDB
LCALL RDBYTE ;进行读字节操作
LCALL MNACK ;发送非应信号
RETRDB:
LCALL STOP ;结束总线
RET
; 向器件指定子地址写 N 个数据
; 入口参数: 器件从地址 SLA 器件子地址 SUBA发送数据缓冲区 MTD 发送字节数 NUMBYTE
; 占用AR0R1R3CY
IWRNBYTE:
MOV A,NUMBYTE
MOV R3,A
LCALL START ;起动总线
MOV A,SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETWRN ;无应答则退出
MOV A,SUBA ;指定子地址
LCALL WRBYTE
LCALL CACK
MOV R1,#MTD
WRDA:
MOV A,@R1
LCALL WRBYTE ;开始写入数据
LCALL CACK
JNB ACK,IWRNBYTE
INC R1
DJNZ R3,WRDA ;判断写完没有
RETWRN:
LCALL STOP
RET
;向器件指定子地址读取 N 个数据
;入口参数: 器件从地址 SLA 器件子地址 SUBA 接收字节数 NUMBYTE
;出口参数: 接收数据缓冲区 MTD
;占用 AR0R1R2R3CY
IRDNBYTE:
MOV R3,NUMBYTE
LCALL START
MOV A,SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETRDN
MOV A,SUBA ;指定子地址
LCALL WRBYTE
LCALL CACK
LCALL START ;重新起动总线
MOV A,SLA
INC A ;准备进行读操作
LCALL WRBYTE
LCALL CACK
JNB ACK,IRDNBYTE
MOV R1,#MRD
RDN1:
LCALL RDBYTE ;读操作开始
MOV @R1,A
DJNZ R3,SACK
LCALL MNACK ;最后一字节发非应答位
RETRDN:
LCALL STOP ;并结束总线
RET
SACK:
LCALL MACK
INC R1
SJMP RDN1
三、应用举例
;为软件包定义变量
ACK BIT 10H ;应答标志位
SLA DATA 50H ;器件从地址
SUBA DATA 51H ;器件子地址
NUMBYTE DATA 52H ;读/写的字节数
;使用前定义常量
SDA EQU P1. ;I2C总线定义
SCL EQU P1.
MTD EQU 30H ;发送数据缓冲区首址(缓冲区 30H-3FH)
MRD EQU 40H ;接收数据缓冲区首址(缓冲区 40H-4FH)
;定义器件地址
CSI24WCXX EQU 0A0H
ORG 0000H
AJMP MAIN
ORG 0080H
MAIN:
MOV R4,#0F0H ;延时,等待其它芯片复位好
DJNZ R4,$
;对24WCXX 指定单元进行写操作,指定的子地址放入SUBA,数据依次放入MTD缓冲区
WR24WCXX:
MOV SLA,#CSI24WCXX
MOV SUBA,#30H ;指定存储地址
MOV NUMBYTE,#01H ;写入一字节数据
MOV MTD,#58H ;写入的数据放入 MTD 缓冲区
LCALL IWRNBYTE
SJMP $ ;操作结束
;
$INCLUDE (VI2C_ASM.ASM) ;包含 VIIC 软件包
;
END
模拟IIC总线汇编程序软件包的更多相关文章
- C51—模拟IIC总线实现EEPROM存取数据
a - 什么是IIC总线 -什么是EEPROM -IIC总线的通信格式 模块化设计注解 整体代码 - 什么是IIC总线 IIC总线是同步通信的一种特殊形式,具有接线口少.控制简单.器件封装形式小.通信 ...
- 用I/O口模拟IIC总线协议遇到的一些问题
最近做的一个项目,是基于IIC总线通信的传感器系统.由于另外一个传感器使用的是类IIC协议,而不是标准IIC,所以MCU不能与其通信,最后没有办法,只有通过I/O口模拟的方式实现IIC的总线通信.具体 ...
- 模拟IIC总线多设备挂载(12864OLED屏幕+GY30光照传感器)
最终效果展示 OLED屏幕和GY30光照传感器(BH1750FVI)都连接在一个IIC(I2C)总线上,所以只需要接4根线即可.获取到的光照强度可以在OLED上实时显示并通过串口打印.IIC是IO模拟 ...
- RT-thread 设备驱动组件之IIC总线设备
本文主要介绍RT-thread中IIC总线设备驱动,涉及到的主要文件有:驱动框架文件(i2c_core.c,i2c_dev.c,i2c-bit-ops.c,i2c_dev.h,i2c.h):底层硬件驱 ...
- IIC总线
一. 概述 1. IIC总线是PHILIPS公司推出的一种串口总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串口总线. 2. IIC总线只有两根双向信号线.一根是数据线SDA,一 ...
- stm32软件模拟IIC读取PX4FLOW光流传感器数据
这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模 ...
- 模拟IIC协议时序
IIC是飞利浦公司开发的两线式串行总线,主要应用在单片机和外围电子器件之间的数据通讯. IIC总线优点是节约总线数,稳定,快速,是目前芯片制造上非常流行的一种总线,大多数单片机已经片内集成了IIC总线 ...
- lpc1788IO口模拟IIC
#ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #in ...
- STM32F10X -- 模拟IIC程序
听说STM32的IIC硬件做的很鸡肋,所以在这里通过模拟的方式实现IIC协议.此程序能成功对AT24C02操作. 程序中的带参数宏 IIC_DELAY(time)的功能是延时time us,在实际中具 ...
随机推荐
- 同行blog收集
姜楠:http://www.slyar.com/blog/ 赵劼:http://blog.zhaojie.me/ 研究者July:http://my.csdn.net/v_JULY_v 王卓群:htt ...
- 【转】Install SmartGit via PPA in Ubuntu 13.10/13.04/12.04/Linux Mint
原文网址:http://ubuntuhandbook.org/index.php/2013/09/install-smartgit-via-ppa-ubuntu-linux-mint/ This tu ...
- Hello Bolg!
初来乍到,将就闹点小情绪吧 博客, 作为一个即将毕业的小码农, 第一次写这东西似乎生涩了点. 而且第一眼看到这东西还觉得特玄乎,不过“化抽象为具体, 化复杂为简单”不正是自己的职业操守吗. 于是, 我 ...
- Codeforce 217 div2
C 假设每种颜色的个数都相同,可以用轮换的方式,让答案达到最大n,当不同的时候,可以每次从每种颜色中取出相同个数的手套来操作; 一直迭代下去直到只剩下1种颜色; 再将这一种颜色与之前交换过的交换就行了 ...
- POJ2367 Genealogical tree (拓扑排序)
裸拓扑排序. 拓扑排序 用一个队列实现,先把入度为0的点放入队列.然后考虑不断在图中删除队列中的点,每次删除一个点会产生一些新的入度为0的点.把这些点插入队列. 注意:有向无环图 g[] : g[i] ...
- poj 3666 Making the Grade(dp)
Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more tha ...
- python高级编程:缓存
# -*- coding: utf-8 -*-__author__ = 'Administrator'#缓存"""对于运行代价很高的函数和方法结果,可以进行缓存,只要:1 ...
- Android Fragment详解(五):Fragment与Activity通讯
与activity通讯 尽管fragment的实现是独立于activity的,可以被用于多个activity,但是每个activity所包含的是同一个fragment的不同的实例. Fragment可 ...
- Unity 3D 动画帧事件
前几天在项目开发中碰到一个这样的需求,RPG游戏中,特效和动画播放不同步的.假如主角在攻击NPC时,先实例化特效,后播放动画.动画毕竟是有一个时间长度的.等到动画播放攻击挥刀的那一瞬间时,特效可能早就 ...
- Java 编程下使用 Class.forName() 加载类
在一些应用中,无法事先知道使用者将加载什么类,而必须让使用者指定类名称以加载类,可以使用 Class 的静态 forName() 方法实现动态加载类.下面的范例让你可以指定类名称来获得类的相关信息. ...