I2C总线之(三)---以C语言理解IIC
为了加深对I2C总线的理解,用C语言模拟IIC总线,边看源代码边读波形:
如下图所示的写操作的时序图:


读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)---时序”
完整的程序如下:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0xa0
#define read_ADD 0xa1
uchar a;
sbit SDA=P2^;
sbit SCL=P2^;
void SomeNop(); //短延时
void init(); //初始化
void check_ACK(void);
void I2CStart(void);
void I2cStop(void);
void write_byte(uchar dat);//写字节
void delay(uint z);
uchar read_byte(); //读字节
void write(uchar addr,uchar dat); //指定地址写
uchar read(uchar addr); //指定地址读
bit flag; //应答标志位
void main()
{
init();
write_add(,0xaa); //向地址5写入0xaa
delay(); //延时,否则被坑呀!!!
P1=read_add(); //读取地址5的值
);
}
//***************************************************************************
void delay()//简单延时函数
{ ;; }
//***************************************************************************
void start() //开始信号 SCL在高电平期间,SDA一个下降沿则表示启动信号
{
sda=; //释放SDA总线
delay();
scl=;
delay();
sda=;
delay();
}
//***************************************************************************
void stop() //停止 SCL在高电平期间,SDA一个上升沿则表示停止信号
{
sda=;
delay();
scl=;
delay();
sda=;
delay();
}
//***************************************************************************
void respons() //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答
{
uchar i;
scl=;
delay();
//至多等待250个CPU时钟周期
)&&(i<))i++;
scl=;
delay();
}
//***************************************************************************
void init()//总线初始化 将总线都拉高一释放总线 发送启动信号前,要先初始化总线。即总有检测到总线空闲才开始发送启动信号
{
sda=;
delay();
scl=;
delay();
}
//***************************************************************************
void write_byte(uchar date) //写一个字节
{
uchar i,temp;
temp=date;
;i<;i++)
{
temp=temp<<;
scl=;//拉低SCL,因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化;并在此时和上一个循环的scl=1一起形成一个上升沿
delay();
sda=CY;
delay();
scl=;//拉高SCL,此时SDA上的数据稳定
delay();
}
scl=;//拉低SCL,为下次数据传输做好准备
delay();
sda=;//释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号
delay();
}
//***************************************************************************
uchar read_byte()//读一个字节
{
uchar i,k;
scl=;
delay();
sda=;
delay();
;i<;i++)
{
scl=;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦
delay();
k=(k<<)|sda;
scl=;//拉低SCL,使发送端可以把数据放在SDA上
delay();
}
return k;
}
//***************************************************************************
void write_add(uchar address,uchar date)//任意地址写一个字节
{
start();//启动
write_byte(0xa0);//发送从设备地址
respons();//等待从设备的响应
write_byte(address);//发出芯片内地址
respons();//等待从设备的响应
write_byte(date);//发送数据
respons();//等待从设备的响应
stop();//停止
}
//***************************************************************************
uchar read_add(uchar address)//读取一个字节
{
uchar date;
start();//启动
write_byte(0xa0);//发送发送从设备地址 写操作
respons();//等待从设备的响应
write_byte(address);//发送芯片内地址
respons();//等待从设备的响应
start();//启动
write_byte(0xa1);//发送发送从设备地址 读操作
respons();//等待从设备的响应
date=read_byte();//获取数据
stop();//停止
return date;//返回数据
}
I2C总线之(三)---以C语言理解IIC的更多相关文章
- SPI、I2C、UART三种串行总线协议的区别
第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART(Universal Asynchronous R ...
- SPI、I2C、UART三种串行总线协议的区别和SPI接口介绍(转)
SPI.I2C.UART三种串行总线协议的区别 第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART( ...
- IIC - 【转载】对I2C总线的时钟同步和总线仲裁的深入理解
对I2C总线的时钟同步和总线仲裁的深入理解 每一个IIC总线器件内部的SDA.SCL引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起.其中输出为漏极开路的场效应管.输入缓冲为一只高输入阻抗的同 ...
- i2c总线驱动,总线设备(适配器),从设备,从设备驱动的注册以及匹配
常用链接 我的随笔 我的评论 我的参与 最新评论 我的标签 随笔分类 ARM裸机(13) C(8) C++(8) GNU-ARM汇编 Linux驱动(24) Linux应用编程(5) Makefile ...
- [I2C].I2C总线详解
转自:https://www.cnblogs.com/BitArt/archive/2013/05/27/3101037.html 一. 基本信息 1. 概述 I²C 是Inter-Integrate ...
- Linux设备驱动模型之I2C总线
一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,提供了与具体硬件无关的I2C读写函数. (2)I2 ...
- I2C总线和S5PV210的I2C总线控制器
一.什么是I2C通信协议? 1.物理接口:SCL + SDA (1)SCL(serial clock):时钟线,传输CLK信号,一般是I2C主设备向从设备提供时钟的通道. (2)SDA(serial ...
- I2C总线驱动框架详解
一.I2C子系统总体架构 1.三大组成部分 (1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册.注销方法,I2C通信方法(”algorithm”)上层的,与 ...
- 关于具有I2C总线的TEA6320的使用
现在先了解一下TEA6320,TEA6320是一个I2C总线控制音响应用的立体声放大器,,它的I2C协议和音量控制如下: 它的主要代码: void delay1ms(unsigned int Dela ...
随机推荐
- 插入ts以及判断列是否存在(支持多数据库)
1:增加ts.dr字段,先判断ts.dr字段是否存在,其中ts字段插入的是日期,默认值为当前插入的时间,dr字段是数值型,默认值为0 * 增加ts/dr字段 * * @param tableList ...
- GUI编程笔记(java)02:java.awt和java.swing包的区别
1. java.awt和java.swing两者的概述 java.awt:(java的标准包) Abstract Window ToolKit (抽象窗口工具包),需要调用本地 ...
- git 删除配置的远程地址
删除(origin 名称需根据你本地查询出来的想删除的名字, 查询命令为 git remote -v) git remote rm origin 添加(origin 名称可根据需要添加) git re ...
- 自己做的demo---宣告可以在java世界开始自由了
package $interface; public interface ILeaveHome { public abstract int a(); public abstract int b(); ...
- Java-struts2 之中文乱码问题
中文乱码问题,是个很麻烦的问题,有时候你发现,你表单页面的编码是UTF-8 Stutrst.xml也有这么一句话 <constant name="struts.i18n.encodin ...
- Spring4.3.1 JDBCTemplate操作数据库
个人总结,转载请注明出处:http://www.cnblogs.com/lidabnu/p/5679354.html 基于Spring4.3.1官方文档总结,官方文档链接http://docs.spr ...
- UI层调用WCF服务实例(源码)
WCF原理性的东西,暂时还没有深入研究,只是在公司的项目中使用到了,会调用,然后再多做了一些了解,现在将它抽出来了一个小实例,写了一个WCF的demo. 我写的这个WCF.Demo主要包括数据契约和服 ...
- MVVM模式应用 之xml文件的读取
XML如下所示: <?xml version="1.0" encoding="utf-8" ?> <schools> <schoo ...
- [Machine Learning] Probabilistic Graphical Models:一、Introduction and Overview(1、Overview and Motivation)
一.PGM用来做什么 1. 医学诊断:从各种病症分析病人得了什么病,该用什么手段治疗 2. 图像分割:从一张百万像素级的图片中分析每个像素点对应的是什么东西 两个共同点:(1)有非常多不同的输入变 ...
- yum命令学习
yum配置文件 /etc/yum.conf yum check-update检查一下有无更新 每天都要(设置定时任务todo) 1.列出所有可更新的软件清单---yum check-update 2. ...