IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 嵌入式工程师成长之路(三十二)之I2C通信以及51单片机程序 -> 正文阅读

[嵌入式]嵌入式工程师成长之路(三十二)之I2C通信以及51单片机程序

I2C通信以及51单片机程序

I2C总线是PHLIPS公司推出的一种双向串行总线,只有两根双向信号线。一根是数据/地址线SDA,另一根是时钟线SCL,半双工。
这两根信号线上挂载着主机与从机,一般来说,谁控制SCL信号线,谁就是主机。
1、空闲状态: 两根总线接上拉电阻,且都为高电平时,说明两根总线为空闲状态。
2、8位数据传输:
在这里插入图片描述
规则: I2C总线进行数据传送时,SCL为高电平期间,SDA上的数据必须保持稳定,只有在SCL上的信号为低电平期间,SDA上的高电平或低电平状态才允许变化。
就看这张图,下面一边介绍原理一边写程序:
(1)起始信号,既然是两根信号线来传输数据,那么就需要协议,也就是I2C协议,此协议包括起始信号,如上图所示,当SCL为高电平时,SDA由高电平变为低电平时,表示可以传输数据了,也就是所谓的起始信号
那么程序怎么写?很简单,基于51单片机的起始信号程序如下:

void startiic()
{

SDA=1;
delay();
delay();
SCL=1;//初始状态数据线与时钟线为高电平
delay();
SDA=0;//在时钟线为高电平的情况下拉低数据线表示起始信号
delay();
SCL=0;//起始信号完成后需要传输数据,所以拉低时钟线允许数据变化
delay();

}

注意:开始信号结束后,SCL信号线为低电平
(2)有了起始信号,接着就可以传输数据了,需要注意的是,数据传输从高位开始到低位传输结束,一共8位数据,开始信号结束后,SCL信号线为低电平,那么传输数据里的读数据程序第一步就要将SCL电平拉高,保持数据信号线上的数据可读,且读8位
51单片机的读8位数据程序如下:

unsigned char readbit8()
{
unsigned char i;
unsigned char dat=0;//定义一个8位数来存储读出的数据
for(i=0;i<8;i++)
{
SCL=1;//时钟线为高电平时因数据保持不变才可读数据
dat<<=1;
dat|=(unsigned char)SDA;//数据从高位开始读出,并保存在dat中
SCL=0;//时钟线为低电平时才允许数据变化传入
delay();
}
return(dat);

}

注意:8位的数据传输完毕后,SCL的电平状态为低电平
我们再来看一下写数据程序应该如何写,首先数据信号线要改变电平状态,SCL的电平要为低电平,所以写数据的程序第一步就是SCL的电平状态要先拉低,当我们的起始信号开始后,SCL的电平信号正好为低,那么只需写一句SDA=(bit)(dat&0x80);就把dat变量的最高位传递给SDA了,接下来将SCL拉高保持数据稳定,再拉低使数据可以改变,从而在稳定状态时实现传输
51单片机的写8位数据的程序如下:

void writebit8(unsigned char dat)
{

unsigned char i;
for(i=0;i<8;i++)
{


SDA=(bit)(dat&0x80);
delay();
SCL=1;	
dat<<=1;
delay();
SCL=0;

}	

}

注意:8位的数据传输完毕后,SCL的电平状态为低电平
(3)数据传输完毕之后,需要有个应答信号,表示8位的数据已经传输完毕,在SCL的信号线为低电平的情况下拉高SDA信号线,实质上是主机释放SDA线的控制权,将控制权交给从机,如果从机将SDA信号线拉低,说明8位数据已经正常传输
51单片机的应答信号的程序如下:

bit ack()
{
	
bit a;
SDA=1;//释放总线使SDA线由从机控制
SCL=1;//SCL为高电平保持数据
delay();	
a=SDA;
SCL=0;
return(a);
	
}

注意:应答信号完毕后,SCL的电平状态为低电平
3、I2C总线器件的地址
为什么要了解I2C总线器件的地址呢?因为主机要想传送数据给从机必须要知道它的地址才能传送。
I2C总线是由数据线SDA 和时钟线SCL构成的串行总线,可发送和接受数据。在单片机与被控器件之间、器件与器件之间均可进行双向信息传送。器件地址共7位,它与方向位构成了I2C总线器件的寻址字节SLA。
在这里插入图片描述
I . DA3 DA2 DA1 DA0:器件地址位,是I2C总线外围接口器件固有的地址编码,器件出厂时就给定了(使用者不能改变)。如I2C总线器件AT24CXX系列器件的地址为1010。
II. A2 A1 A0:引脚地址位,是由I2C总线外围器件的地址端口根据接地或电源的不同而形成的地址数据(由使用者控制)。
III.R/W:数据方向位。R/W=1时,为接收(读出);R/W=0时,为发送(写入)。
AT24C02的芯片地址(0xa0为写,0xa1为读)
4、51单片机与AT24C02通讯的数据传输程序
读数据:读数据就是先寻找从机器件地址,然后再寻找器件的寄存器地址,然后再从寄存器里把数据读出来 ,程序如下:

unsigned char  readdate(unsigned char address)
{  /*要一个地址返回一个数据*/
  /*读数据*/
  unsigned char dat;
	 startiic();//开始读数据
	writebit8(WRITECOMDE);//确定从器件地址
	 ack();	  //回应一下
	 writebit8(address); //存放数据的地址
	 ack();	 //回应一下 
	 startiic();//开始读数据
	writebit8(READCOMDE);//确定从器件地址,读操作
	 ack();	  //回应一下
	dat=readbit8();//读出来的数据
	 stopiic(); 
	 return dat;
}

写数据:写数据就是先寻找从机器件地址,然后再寻找器件的寄存器地址,然后再把数据写进寄存器里 ,程序如下:

void writedate(unsigned char address,unsigned dat)
{
   startiic();
	 writebit8(WRITECOMDE);//确定从器件地址
	 ack();	  //回应一下
	 writebit8(address); //存放数据的地址
	 ack();	 //回应一下 
	 writebit8(dat);//想要写入的数据
	 ack();	  //回应一下
	 stopiic();
	 delaynms(2);
}

5、51单片机与AT24C02通讯的电路图
在这里插入图片描述在这里插入图片描述
6、51单片机与AT24C02通讯的完整程序

#include <reg51.h>        
#include <intrins.h>      //包含_nop_()函数定义的头文件
#define	READCOMDE	  0xa1		// 器件地址以及读取操作,0xa1即为1010 0001B
#define	WRITECOMDE  0xa0		// 器件地址以及写入操作,0xa1即为1010 0000B
sbit SDA=P3^4;          //将串行数据总线SDA位定义在为P3.4引脚
sbit SCL=P3^3;         //将串行时钟总线SDA位定义在为P3.3引脚
unsigned char code table[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  void delay1ms()
{
   unsigned char i,j;	
	 for(i=0;i<10;i++)
	  for(j=0;j<33;j++);		 
 }
 void delay()//延时两行空语句的时间,约2us
{ ;; }
void delaynms(int n)
 {
   int i;
	for(i=0;i<n;i++)
	   delay1ms();
 }
void startiic()
{

SDA=1;
delay();
delay();
SCL=1;//初始状态数据线与时钟线为高电平
delay();
SDA=0;//在时钟线为高电平的情况下拉低数据线表示起始信号
delay();
SCL=0;//起始信号完成后需要传输数据,所以拉低时钟线允许数据变化
delay();

}
unsigned char readbit8()
{
unsigned char i;
unsigned char dat=0;//定义一个8位数来存储读出的数据
for(i=0;i<8;i++)
{
SCL=1;//时钟线为高电平时因数据保持不变才可读数据
dat<<=1;
dat|=(unsigned char)SDA;//数据从高位开始读出,并保存在dat中
SCL=0;//时钟线为低电平时才允许数据变化传入
delay();
}
return(dat);

}

void writebit8(unsigned char dat)
{

unsigned char i;
for(i=0;i<8;i++)
{


SDA=(bit)(dat&0x80);
delay();
SCL=1;	
dat<<=1;
delay();
SCL=0;
}	

}
bit ack()
{
	
bit a;
SDA=1;//释放总线使SDA线由从机控制
SCL=1;//SCL为高电平保持数据
delay();	
a=SDA;
SCL=0;
	
	return(a);
	
}
void stopiic()
{


SDA=0;
delay();
SCL=1;	
delay();
SDA=1;
delay();
}
unsigned char  readdate(unsigned char address)
{  /*要一个地址返回一个数据*/
  /*读数据*/
  unsigned char dat;
	 startiic();//开始读数据
	writebit8(WRITECOMDE);//确定从器件地址
	 ack();	  //回应一下
	 writebit8(address); //存放数据的地址
	 ack();	 //回应一下 
	 startiic();//开始读数据
	writebit8(READCOMDE);//确定从器件地址,读操作,所以后面为1
	 ack();	  //回应一下
	dat=readbit8();//读出来的数据送往P3口
	 stopiic(); 
	 return dat;
}
void writedate(unsigned char address,unsigned dat)
{
   startiic();
	 writebit8(WRITECOMDE);//确定从器件地址
	 ack();	  //回应一下
	 writebit8(address); //存放数据的地址
	 ack();	 //回应一下 
	 writebit8(dat);//想要写入的数据
	 ack();	  //回应一下
	 stopiic();
	 delaynms(2);
}
void main()
{
	 
	  unsigned char k;
    unsigned char i;
while(1)
{
	for(i=0;i<8;i++)
	{
	   writedate(8,table[i]);
	   k=readdate(8);
	   P1=k; 
		delaynms (1000);

	}
	 i=0;

}



}

7、详细文档
I2C通信协议详细文档连接

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 12:54:10  更:2021-07-30 12:54:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:50:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码