I2C总线时序模拟(二)-加深理解总线协议
/********************************************************************
此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据
及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的
与用户程序连接并扩展..... 注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作
一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ)
********************************************************************/
#include <reg764.h> /*头文件的包含*/
#include <intrins.h>#define uchar unsigned char /*宏定义*/
#define uint unsigned int#define _Nop() _nop_() /*定义空指令*//* 常,变量定义区 *//*端口位定义*/
sbit SDA=P1^3; /*模拟I2C数据传送位*/
sbit SCL=P1^2; /*模拟I2C时钟控制位*//*状态标志*/
bit ack; /*应答标志位*//*******************************************************************起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.********************************************************************/
void Start_I2c()
{SDA=1; /*发送起始条件的数据信号*/_Nop();SCL=1;_Nop(); /*起始条件建立时间大于4.7us,延时*/_Nop();_Nop();_Nop();_Nop(); SDA=0; /*发送起始信号*/_Nop(); /* 起始条件锁定时间大于4μs*/_Nop();_Nop();_Nop();_Nop(); SCL=0; /*钳住I2C总线,准备发送或接收数据 */_Nop();_Nop();
}/*******************************************************************结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.********************************************************************/
void Stop_I2c()
{SDA=0; /*发送结束条件的数据信号*/_Nop(); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4μs*/_Nop();_Nop();_Nop();_Nop();_Nop();SDA=1; /*发送I2C总线结束信号*/_Nop();_Nop();_Nop();_Nop();
}/*******************************************************************字节数据传送函数
函数原型: void SendByte(uchar c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0 假) 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(uchar c)
{uchar BitCnt;for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/{if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/else SDA=0; _Nop();SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/_Nop(); _Nop(); /*保证时钟高电平周期大于4μs*/_Nop();_Nop();_Nop(); SCL=0; }_Nop();_Nop();SDA=1; /*8位发送完后释放数据线,准备接收应答位*/_Nop();_Nop(); SCL=1;_Nop();_Nop();_Nop();if(SDA==1)ack=0; else ack=1; /*判断是否接收到应答信号*/SCL=0;_Nop();_Nop();
}/*******************************************************************字节数据传送函数
函数原型: uchar RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数。
********************************************************************/
uchar RcvByte()
{uchar retc;uchar BitCnt;retc=0; SDA=1; /*置数据线为输入方式*/for(BitCnt=0;BitCnt<8;BitCnt++){_Nop(); SCL=0; /*置时钟线为低,准备接收数据位*/_Nop();_Nop(); /*时钟低电平周期大于4.7μs*/_Nop();_Nop();_Nop();SCL=1; /*置时钟线为高使数据线上数据有效*/_Nop();_Nop();retc=retc<<1;if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */_Nop();_Nop(); }SCL=0; _Nop();_Nop();return(retc);
}/********************************************************************应答子函数
原型: void Ack_I2c(bit a);功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(bit a)
{if(a==0)SDA=0; /*在此发出应答或非应答信号 */else SDA=1;_Nop();_Nop();_Nop(); SCL=1;_Nop();_Nop(); /*时钟低电平周期大于4μs*/_Nop();_Nop();_Nop(); SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/_Nop();_Nop();
}/*******************************************************************向无子地址器件发送字节数据函数
函数原型: bit ISendByte(uchar sla,ucahr c);
功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit ISendByte(uchar sla,uchar c)
{Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/if(ack==0)return(0);SendByte(c); /*发送数据*/if(ack==0)return(0);Stop_I2c(); /*结束总线*/ return(1);
}/*******************************************************************向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{uchar i;Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/if(ack==0)return(0);SendByte(suba); /*发送器件子地址*/if(ack==0)return(0);for(i=0;i<no;i++){ SendByte(*s); /*发送数据*/if(ack==0)return(0);s++;} Stop_I2c(); /*结束总线*/ return(1);
}
/*******************************************************************向无子地址器件读字节数据函数
函数原型: bit IRcvByte(uchar sla,ucahr *c);
功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地址sla,返回值在c.如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{Start_I2c(); /*启动总线*/SendByte(sla+1); /*发送器件地址*/if(ack==0)return(0);*c=RcvByte(); /*读取数据*/Ack_I2c(1); /*发送非就答位*/Stop_I2c(); /*结束总线*/ return(1);
}/*******************************************************************向有子地址器件读取多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{uchar i;Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/if(ack==0)return(0);SendByte(suba); /*发送器件子地址*/if(ack==0)return(0);Start_I2c();SendByte(sla+1);if(ack==0)return(0);for(i=0;i<no-1;i++){ *s=RcvByte(); /*发送数据*/Ack_I2c(0); /*发送就答位*/ s++;} *s=RcvByte();Ack_I2c(1); /*发送非应位*/Stop_I2c(); /*结束总线*/ return(1);
}/* 完毕 */
I2C总线时序模拟(二)-加深理解总线协议相关推荐
- 总线(二)CAN通讯协议介绍
文章目录 CAN(Controller Area Network)是什么? 总线拓扑图 CAN特征 CAN协议 数据帧 遥控帧 遥控帧和数据帧相关? 仲裁优先级决定 数据帧和遥控帧的优先级 标准格式和 ...
- 计算机网络资料篇(二)——快速理解网络协议
<网络编程懒人入门(一):快速理解网络通信协议(上篇)> <网络编程懒人入门(二):快速理解网络通信协议(下篇)> 一:五层模型 物理层.数据链路层.网络层.传输层.应用层 1 ...
- 串口RS232 RS485最本质的区别!-!I2C通讯协议 最简单的总线通讯!-深入理解SPi通讯协议!
5分钟看懂!串口RS232 RS485最本质的区别!-4分钟看懂!I2C通讯协议 最简单的总线通讯!-深入理解SPi通讯协议,5分钟看懂! 一.5分钟看懂!串口RS232 RS485最本质的区别! 二 ...
- 单片机软件模拟SPI接口—加深理解SPI总线协议
单片机软件模拟SPI接口-加深理解SPI总线协议 SPI(Serial Peripheral Interfacer 串行外设接口)是摩托罗拉公司推出的一种同步串行通讯接口,用于微处理器臌控制器和外 ...
- 清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(二)
I2C(Inter IC Bus)的通讯数据帧: SCL线无方向区分,SDA线上有数据的流动方向.上图中灰色的代表的是主机向从机发送数据,此时SDA线的电平控制权由主机掌控,从机只能监听该线上的电平状 ...
- I2S音频总线学习(二)I2S总线协议
I2S音频总线学习(二)I2S总线协议 一.I2S总线概述 音响数据的采集.处理和传输是多媒体技术的重要组成部分.众多的数字音频系统已经进入消费市场,例如数字音频录音带.数字声音处理器.对于设备和生产 ...
- Linux I2C总线(二)I2C设备驱动编写方法
Linux I2C总线 Linux I2C总线(一)I2C驱动框架 Linux I2C总线(二)I2C设备驱动编写方法 Linux I2C总线(二)I2C设备驱动编写方法 文章目录 Linux I2C ...
- 对I2C总线时序的一点理解以及ACK和NACK(NAK)
http://www.cnblogs.com/zym0805/archive/2011/07/31/2122890.html I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线: ...
- PCIE学习笔记(二)PCIe总线的拓扑结构,协议层,数据传输流程
目录 PCIe总线的拓扑结构 PCI Express协议分层 物理层(Physical Layer) 数据链路层(Link Layer) 处理层(Transaction Layer) 软件层(Soft ...
最新文章
- ubuntu 14 nginx php,ubuntu14.04安装nginx+php5-fpm
- 【备忘录】技术笔记整理。
- 轻量级Excel读取器ExcelReader
- 【代码笔记】Web-ionic-select
- apache mesos_试用Apache Mesos HTTP API获得乐趣和收益
- java 反射 代码_java反射机制学习代码
- Fckeditor漏洞汇总
- 计算机里的音乐怎么设置,realtek高清晰音频管理器怎么设置
- java 文档查看技巧
- stm32f103c8t9控制TFT显示屏
- 恺撒密码的python实现介绍
- 读书笔记17 《靠谱》大石哲之
- linux中管道的概念,浅谈Linux管道
- 「案例」如何解决公司采购与财务之间的工作矛盾?
- 理解逆矩阵 理解单位矩阵
- CSS cascading style sheet
- Symbian OS
- 光缆旋转传输器/光纤滑环(LZ-M40X)在大型堆取料机上的应用
- CDA Day 5 Excel透视表学习总结
- React配置baseUrl
热门文章
- mysql sql语句里连接符的使用_SQL中group_concat函数,用符号连接查询分组里字段值...
- leetcode46.全排列
- leecode刷题(4)-- 存在重复数组
- vscode php debug
- vue组件库(一):前期准备工作
- 【洛谷】【lca+结论】P3398 仓鼠找sugar
- SQL注入之Mysql报错注入
- 【线段树】HDU 3397 Sequence operation 区间合并
- 解读:百度官方公告对于6.22、6.28事件解释
- Java把表导出成Excel的代码