51单片机——模拟I2C总线与AT24C02通信

这篇具有很好参考价值的文章主要介绍了51单片机——模拟I2C总线与AT24C02通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、写在前面

二、功能描述

三、主要模块介绍

3.1 I2C总线介绍

3.2 I2C总线协议

3.2.1数据有效规定

3.2.2起始信号和停止信号 

3.2.3 发送应答和接收应答

3.2.4 主机发送一个字节和接收一个字节

3.3 AT24C02介绍

3.3 字节写和随机读

四、测试文件test.c

五、现象描述


一、写在前面

  • AT24C02芯片有I2C接口,但是51单片机是没有I2C接口的,是用软件程序模拟I2C总线。
  • 51单片机是主机,AT24C02是从机。在这个实验中最重要的就是,弄清是主机还是从机去发送或接收数据。
  • 默认是主机控制SCL、SDA线。从机想控制SDA线,发送数据就要主机释放总线(SDA=1)。

二、功能描述

        用单片机模拟I2C与AT24C02通信,把数据写入AT24C02中,利用AT24C02存储数据掉电不丢失的特点,在单片机重新启动后,把对应地址的数据读取出来。

三、主要模块介绍

3.1 I2C总线介绍

        I2C 总线(Inter IC Bus)只有两根双向信号线。一根是数据线 SDA,另一根是时钟线 SCL。有时钟线而且是由主机发送,从机接收或者由从机发送,主机接收,所以I2C是同步、半双工的通讯方式。

51单片机模拟i2c,51单片机,c语言,嵌入式硬件

3.2 I2C总线协议

3.2.1数据有效规定

        I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

51单片机模拟i2c,51单片机,c语言,嵌入式硬件

3.2.2起始信号和停止信号 

  • 起始信号:当SCL为高电平时,SDA由高电平向低电平变化。
  • 停止信号:当SCL为高电平时,SDA由低电平向高电平变化。

51单片机模拟i2c,51单片机,c语言,嵌入式硬件

        起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。

起始和终止信号由程序模拟如下:

/*
     *函数名:	I2C_star()
     *函数功能:I2C的起始信号
     *输入:	无
     *输出:	无
*/
void I2C_star()
{
	I2C_SDA=1;
	I2C_SCL=1;
	I2C_SDA=0;
	I2C_SCL=0;	
}
/*
     *函数名:	I2C_stop()
     *函数功能:I2C的停止信号
     *输入:	无
     *输出:	无
*/
void I2C_stop()
{
	 I2C_SDA=0;
	 I2C_SCL=1;
	 I2C_SDA=1;
}

3.2.3 发送应答和接收应答

        发送应答和接收应答都是相对于主机而言的。应答是低电平脉冲,非应答是高电平脉冲。

  • 发送应答:当主机在接收从机发送的一个数据后,主机发送应答信号给从机,还要不要继续发送数据。
  • 接收应答:主机发送一个数据给从机后,从机通过控制SDA(此时主机要释放总线)发送应答信号,主机根据应答信号决定还要不要发送数据。

 程序模拟如下:

/*
     *函数名:	 I2C_SendAck(bit ack)
     *函数功能:  主机发送应答
     *输入:	     ack:发送的一个应答
     *输出:	     无
*/
void I2C_SendAck(bit ack)//主机发送应答
{
	I2C_SDA=ack;
	I2C_SCL=1;
	I2C_SCL=0;
}
/*
     *函数名:	  I2C_ReadAck()
     *函数功能:   主机接收应答
     *输入:	      无
     *输出:	      ack:接收的应答
*/
bit I2C_ReadAck()//主机接收应答
{
	bit ack=0;
	I2C_SDA=1;//释放总线
	I2C_SCL=1;
	ack=I2C_SDA;
	I2C_SCL=0;
	return ack;
}

3.2.4 主机发送一个字节和接收一个字节

  1. 主机发送一个字节数据:在SCL低电平时,主机把数据依次写到SDA线上(高位在前),再拉高SCL,从机将在SCL高电平期间读取数据位,循环8次,即可发送一个字节数据。
  2. 主机接收一个字节数据:首先主机释放总线(SDA=1),在SCL低电平时,从机把数据依次写到SDA线上(高位在前),再拉高SCL,主机将在SCL高电平期间读取数据位,循环8次,即可接收一个字节数据。

程序如下:

/*
     *函数名:	 I2C_Writebyte(unsigned char byte)
     *函数功能: I2C总线主机发送一个字节数据
     *输入:	 byte:要发送的字节数据
     *输出:	 无
*/
void I2C_Writebyte(unsigned char byte)//主机发送一个字节的数据
{
	unsigned char i=0;
	for(i=0;i<8;i++)
	{
		I2C_SDA=byte&(0x80>>i);
		I2C_SCL=1;
		I2C_SCL=0;
	}
}
/*
     *函数名:	 I2C_Readbyte()
     *函数功能: I2C总线主机接收一个字节数据
     *输入:	 无
     *输出:	 byte:读取的数据
*/
unsigned char I2C_Readbyte()//主机接收一个字节数据
{
	unsigned char i,byte=0;
	I2C_SDA=1;//释放总线
	for(i=0;i<8;i++)
	{
		I2C_SCL=1;
		if(I2C_SDA==1){byte|=(0x80>>i);}//I2C_SDA上的数据已经是从机发送的数据
		I2C_SCL=0;
	}
	return byte;
}

3.3 AT24C02介绍

        我们开发板上使用的是 AT24C02(EEPROM)芯片,此芯片具有 I2C 通信接口,芯片内保存的数据在掉电情况下都不丢失, 所以通常用于存放一些比较重要的数据等。

51单片机模拟i2c,51单片机,c语言,嵌入式硬件

3.3 字节写和随机读

        I2C总线寻址按照从机地址位数可分为两种,一种是 7 位,另一种是 10 位。采用 7 位的寻址字节的位定义如 下:

51单片机模拟i2c,51单片机,c语言,嵌入式硬件

        一个从机 的 7 位寻址位有 4 位是固定位,3 位是可编程位。

  •  AT24C02的固定为是1010,可编程位本开发板上为000。从机地址加读/写位(0/1),就是起始信号后的第一个字节。
  1.  字节写的顺序:起始信号+从机地址带读/写位(0/1)+接收应答+指定写入数据的地址+接收应答+写入的数据+接收应答+停止信号。51单片机模拟i2c,51单片机,c语言,嵌入式硬件
  2.  随机读的顺序:起始信号+从机地址带读/写位(0/1)+接收应答+指定读取数据的地址+接收应答+   起始信号+从机地址带读/写位(0/1)+接收应答+主机接收数据+发送应答+停止信号。51单片机模拟i2c,51单片机,c语言,嵌入式硬件

 程序如下:

#define AT24C02_address 0xA0  //AT24C02的地址
/*
     *函数名:	AT24C02_Writebyte(unsigned char word_address,byte)
     *函数功能:向AT24C02中的某个地址写入一个字节数据
     *输入:	word_address:字节地址	 byte:写入的字节数据
     *输出:	无
*/
void AT24C02_Writebyte(unsigned char word_address,byte)
{
	bit ack=0;
	I2C_star();
	I2C_Writebyte(AT24C02_address);
	ack=I2C_ReadAck();
	I2C_Writebyte(word_address);
	ack=I2C_ReadAck();
	I2C_Writebyte(byte);
	ack=I2C_ReadAck();
	I2C_stop();
}
/*
     *函数名:	  AT24C02_Readbyte(unsigned char word_address)
     *函数功能:  主机读取AT24C02的指定地址的数据
     *输入:	  word_address:数据的地址
     *输出:	  byte:被读取的字节数据
*/
unsigned char AT24C02_Readbyte(unsigned char word_address)
{
	unsigned char byte=0;
	bit ack=0;
	I2C_star();
	I2C_Writebyte(AT24C02_address);
	ack=I2C_ReadAck();
	I2C_Writebyte(word_address);
	ack=I2C_ReadAck();
	I2C_star();
	I2C_Writebyte(AT24C02_address|0x01);
	ack=I2C_ReadAck();
	byte=I2C_Readbyte();
	I2C_SendAck(1);
	I2C_stop();
	return byte;
}

四、测试文件test.c

#include <REGX52.H>
#include"I2C.h"
#include"LCD1602.h"
#include"AT24C02.h"
#include"Independentkey.h"
#include"Delay.h"
int main()
{
	unsigned char keynum,num=0;
	LCD_Init();
	LCD_ShowNum(1,1,0,3);
	AT24C02_Writebyte(0x01,1);
	Delay(5);
	AT24C02_Writebyte(0x02,2);
	Delay(5);
	AT24C02_Writebyte(0x03,3);
	Delay(5);
	AT24C02_Writebyte(0x04,4);
	Delay(5);
	while(1)
	{
		keynum=Independentkey();
		if(keynum!=0)
		{
			 if(keynum==1)
			 {
			 	num=AT24C02_Readbyte(0x01);
				LCD_ShowNum(1,1,num,3);
			 }
			 if(keynum==2)
			 {
			 	num=AT24C02_Readbyte(0x02);
				LCD_ShowNum(1,1,num,3);
			 }
			 if(keynum==3)
			 {
			 	num=AT24C02_Readbyte(0x03);
				LCD_ShowNum(1,1,num,3);
			 }
			 if(keynum==4)
			 {
			 	num=AT24C02_Readbyte(0x04);
				LCD_ShowNum(1,1,num,3);
			 }
		}
	}
}

五、现象描述

        在AT24C02的0x01,0x02,0x03,0x04地址处,写入1,2,3,4,然后按下独立按键,分别读取出来(可掉电不丢失数据),并显示在LCD1602上。文章来源地址https://www.toymoban.com/news/detail-634943.html

  • 写在后面:当遇到听不懂的或者程序出现什么问题,首先不应该去抱怨什么什么这么难,先是静下心来,一遍听不懂我就听两遍,两边不懂就三遍,直到听懂为止。也可以出去走走,把思路捋清,再回去看视频,有些东西别人以为你是知道的就没说,但实际上你是不知道的,导致思路很混乱,觉得为什么是这样的啊,从而卡在那里很久。写在前面的内容就是我在看视频过程中不知道的点和值得注意的点。程序运行不出来就仔细找问题的原因,以前一直以为Warning没什么用,就只是报出个警告,程序照样可以运行,这次找问题找半天,原来是有个if()语句判断相等的时候只有一个“=”号,编译器报警告但是没有报错,我就以为是我程序哪个地方写的不对,改改改的,浪费很多时间。最后,遇到问题最重要的就是静下心来,仔细寻找问题原因,然后去解决问题。

到了这里,关于51单片机——模拟I2C总线与AT24C02通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AT24C02(I2C总线)通信的学习

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 学习AT24C02(I2C总线)芯片 RAM()存储速度较快,但容易丢失数据。ROM(Read Only Memory)存储速度较慢,但掉电不丢失数据。在使用时需要两者结合先存入RAM再转存到ROM中。 AT24C02是一种可以实现掉电不丢失

    2024年02月20日
    浏览(45)
  • 【GD32】从0开始学GD32单片机(8)—— I2C外设详解+主机从机发送和接收例程

    I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。 I2C总线是一个真正的多主机总线,如果两个或多个主机同时初始化数据传输,可以通过冲突检测和仲裁防止数据破坏,每个连接到总线上的器件都有

    2024年02月02日
    浏览(83)
  • 【单片机】UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB、SD卡、1-WIRE、Ethernet等常见通信方式

    在单片机开发中,UART、I2C、RS485等普遍在用,这里做一个简单的介绍 UART口指的是一种物理接口形式(硬件)。 UART是异步(指不使用时钟同步,依靠帧长进行判断),全双工(收发可以同时进行)串口总线。它比同步串口复杂很多。有两根线,一根TXD用于发送,一根RXD用于接收

    2024年02月11日
    浏览(39)
  • I2C总线 | I2C总线介绍

    目录 I2C 总线 | I2C 总线介绍 I2C 总线介绍 I2C有如下特点: I2C 总线术语 I2C 总线位传输 IIC总线数据传输 1.字节格式 2.应答响应 IIC 总线寻址方式 1.7位寻址 2.10位寻址 快速和高速模式 1.快速模式 2.高速模式 I2C ( Inter - Intergrated Circuit )总线(也称 IIC 或 I2C )是由 PHILIPS 公司开发

    2024年02月04日
    浏览(53)
  • I2C总线驱动

    SOC芯片平台的外设分为: 一级外设:外设控制器集成在SOC芯片内部 二级外设:外设控制器由另一块芯片负责,通过一些通讯总线与SOC芯片相连 Inter-Integrated Circuit: 字面意思是用于“集成电路之间”的通信总线,简写:IIC(或者I2C) i2c传输的要点就是: 传输一个字节 后面必然

    2024年02月15日
    浏览(40)
  • I2C总线的通讯距离

    I2C总线不适合远距离通信,尤其是使用线缆与接口器件进行通信时一般不选择 I2C。使用I2C总线都是在用一个开发板上或者距离比较近,如果是远距离通信,比如说超过2米,这个时候对硬件就有特殊的要求了。 ① 通信线缆小于0.2米,一般可以采用10K的上拉电阻,这个也是很多

    2024年02月10日
    浏览(35)
  • day9 STM32 I2C总线通信

            I2C(Inter-Integrated Circuit)总线(也称IIC或I2C)是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备,是微电子通信控制领域广泛采用的一种总线标准。         它是同步通信的一种特殊形式,具有接口线少,控制方式简单,期间封装形式少,通

    2024年02月12日
    浏览(51)
  • AT89C51单片机实现单片机串口互动(中断方式,单片机--单片机,应答)

     说一下功能:客户机发送0x01到服务机 2服务单片机应答0xf2到客户机 3客户机接收到0xf2,发送信息153432这6个数字到服务机 4client发送完信息后发送0xaa结束通信 5server接收到0xaa后回复0xaa结束通信,从此老死不相往来 看代码: 服务端代码:    

    2024年02月13日
    浏览(53)
  • 51单片机(At89C51)组成,引脚介绍

    一,单片机的发展史 单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/0口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路

    2023年04月13日
    浏览(53)
  • STM32之I2C总线知识和HAL库函数

    一、 I2C总线知识 I2C总线物理拓扑结构 I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接

    2024年02月21日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包