6、单片机与AT24C02的通讯(IIC)实验(STM32F407)

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

IIC简介

I2C(IIC,Inter-Integrated Circuit),两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。 它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。

IIC是半双工通信方式。

多主机I2C总线系统结构

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

I2C协议

  • 空闲状态

        I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

  • 开始信号

        起始信号:当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。

  • 停止信号

        停止信号:当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

  • 应答信号

        发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。 应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

         对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

  • 数据的有效性

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

        即:数据在SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件 

  • 数据传输 

         在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。

EEPROM(24C02)

总容量是256(2K/8)个字节。

接口:IIC

正点原子开发板 在硬件上设置了 A0=A1=A2=0

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

 如果A2=A1=A0=0; 那么:

读的时候 Device Address=0xA1

写的时候 Device Address=0xA0

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

 24C02字节写时序

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件

24C02读时序

i2c器件at24c02的应用实验的系统框图,单片机充电记录,单片机,stm32,嵌入式硬件 

myiic.h

#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h" 
   	   		   
//IO方向设置
#define SDA_IN()  {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;}	//PB9输入模式
#define SDA_OUT() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;} //PB9输出模式
//IO操作函数	 
#define IIC_SCL    PBout(8) //SCL
#define IIC_SDA    PBout(9) //SDA	 
#define READ_SDA   PBin(9)  //输入SDA 

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	  
#endif

myiic.c

#include "myiic.h"
#include "delay.h"

//初始化IIC
void IIC_Init(void)
{			
  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟

  //GPIOB8,B9初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
	IIC_SCL=1;
	IIC_SDA=1;
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		delay_us(2);   //对TEA5767这三个延时都是必须的
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

 24cxx.h

#ifndef __24CXX_H
#define __24CXX_H
#include "myiic.h"   

#define AT24C01		127
#define AT24C02		255
#define AT24C04		511
#define AT24C08		1023
#define AT24C16		2047
#define AT24C32		4095
#define AT24C64	    8191
#define AT24C128	16383
#define AT24C256	32767  
//Mini STM32开发板使用的是24c02,所以定义EE_TYPE为AT24C02
#define EE_TYPE AT24C02
					  
u8 AT24CXX_ReadOneByte(u16 ReadAddr);							//指定地址读取一个字节
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);		//指定地址写入一个字节
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len);					//指定地址开始读取指定长度数据
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);	//从指定地址开始写入指定长度的数据
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);   	//从指定地址开始读出指定长度的数据

u8 AT24CXX_Check(void);  //检查器件
void AT24CXX_Init(void); //初始化IIC
#endif

24cxx.c

#include "24cxx.h" 
#include "delay.h" 				 	

//初始化IIC接口
void AT24CXX_Init(void)
{
	IIC_Init();//IIC初始化
}
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址  
//返回值  :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{				  
	u8 temp=0;		  	    																 
    IIC_Start();  
	if(EE_TYPE>AT24C16)
	{
		IIC_Send_Byte(0XA0);	   //发送写命令
		IIC_Wait_Ack();
		IIC_Send_Byte(ReadAddr>>8);//发送高地址	    
	}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据 	   
	IIC_Wait_Ack(); 
    IIC_Send_Byte(ReadAddr%256);   //发送低地址
	IIC_Wait_Ack();	    
	IIC_Start();  	 	   
	IIC_Send_Byte(0XA1);           //进入接收模式			   
	IIC_Wait_Ack();	 
    temp=IIC_Read_Byte(0);		   
    IIC_Stop();//产生一个停止条件	    
	return temp;
}
//在AT24CXX指定地址写入一个数据
//WriteAddr  :写入数据的目的地址    
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{				   	  	    																 
    IIC_Start();  
	if(EE_TYPE>AT24C16)
	{
		IIC_Send_Byte(0XA0);	    //发送写命令
		IIC_Wait_Ack();
		IIC_Send_Byte(WriteAddr>>8);//发送高地址	  
	}else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据 	 
	IIC_Wait_Ack();	   
    IIC_Send_Byte(WriteAddr%256);   //发送低地址
	IIC_Wait_Ack(); 	 										  		   
	IIC_Send_Byte(DataToWrite);     //发送字节							   
	IIC_Wait_Ack();  		    	   
    IIC_Stop();//产生一个停止条件 
	delay_ms(10);	 
}
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr  :开始写入的地址  
//DataToWrite:数据数组首地址
//Len        :要写入数据的长度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{  	
	u8 t;
	for(t=0;t<Len;t++)
	{
		AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
	}												    
}

//在AT24CXX里面的指定地址开始读出长度为Len的数据
//该函数用于读出16bit或者32bit的数据.
//ReadAddr   :开始读出的地址 
//返回值     :数据
//Len        :要读出数据的长度2,4
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{  	
	u8 t;
	u32 temp=0;
	for(t=0;t<Len;t++)
	{
		temp<<=8;
		temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1); 	 				   
	}
	return temp;												    
}
//检查AT24CXX是否正常
//这里用了24XX的最后一个地址(255)来存储标志字.
//如果用其他24C系列,这个地址要修改
//返回1:检测失败
//返回0:检测成功
u8 AT24CXX_Check(void)
{
	u8 temp;
	temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX			   
	if(temp==0X55)return 0;		   
	else//排除第一次初始化的情况
	{
		AT24CXX_WriteOneByte(255,0X55);
	    temp=AT24CXX_ReadOneByte(255);	  
		if(temp==0X55)return 0;
	}
	return 1;											  
}

//在AT24CXX里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
//pBuffer  :数据数组首地址
//NumToRead:要读出数据的个数
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
	while(NumToRead)
	{
		*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);	
		NumToRead--;
	}
}  
//在AT24CXX里面的指定地址开始写入指定个数的数据
//WriteAddr :开始写入的地址 对24c02为0~255
//pBuffer   :数据数组首地址
//NumToWrite:要写入数据的个数
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
	while(NumToWrite--)
	{
		AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
		WriteAddr++;
		pBuffer++;
	}
}

 main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "24cxx.h"
#include "key.h"  

//要写入到24c02的字符串数组
const u8 TEXT_Buffer[]={"Explorer STM32F4 IIC TEST"};
#define SIZE sizeof(TEXT_Buffer)	 
	
int main(void)
{ 
	u8 key;
	u16 i=0;
	u8 datatemp[SIZE];	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);    //初始化延时函数
	uart_init(115200);	//初始化串口波特率为115200
	
	LED_Init();					//初始化LED 
 	LCD_Init();					//LCD初始化 
	KEY_Init(); 				//按键初始化  
	AT24CXX_Init();			//IIC初始化 
 	POINT_COLOR=RED; 
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"IIC TEST");	
	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,110,200,16,16,"2023/11/30");	 
	LCD_ShowString(30,130,200,16,16,"KEY1:Write  KEY0:Read");	//显示提示信息		
 	while(AT24CXX_Check())//检测不到24c02
	{
		LCD_ShowString(30,150,200,16,16,"24C02 Check Failed!");
		delay_ms(500);
		LCD_ShowString(30,150,200,16,16,"Please Check!      ");
		delay_ms(500);
		LED0=!LED0;//DS0闪烁
	}
	LCD_ShowString(30,150,200,16,16,"24C02 Ready!");    
 	POINT_COLOR=BLUE;//设置字体为蓝色	  
	while(1)
	{
		key=KEY_Scan(0);
		if(key==KEY1_PRES)//KEY1按下,写入24C02
		{
			LCD_Fill(0,170,239,319,WHITE);//清除半屏    
 			LCD_ShowString(30,170,200,16,16,"Start Write 24C02....");
			AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);
			LCD_ShowString(30,170,200,16,16,"24C02 Write Finished!");//提示传送完成
		}
		if(key==KEY0_PRES)//KEY0按下,读取字符串并显示
		{
 			LCD_ShowString(30,170,200,16,16,"Start Read 24C02.... ");
			AT24CXX_Read(0,datatemp,SIZE);
			LCD_ShowString(30,170,200,16,16,"The Data Readed Is:  ");//提示传送完成
			LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串
		}
		i++;
		delay_ms(10);
		if(i==20)
		{
			LED0=!LED0;//提示系统正在运行	
			i=0;
		}		   
	} 	    
}

实验效果:

说明:先按下KEY0查看EEPROM所存内容,再按下KEY1写入新内容,最后再次按下KEY0查看内容是否变更为所写新内容

IIC实验效果文章来源地址https://www.toymoban.com/news/detail-830568.html

到了这里,关于6、单片机与AT24C02的通讯(IIC)实验(STM32F407)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • (十一)51单片机——用AT24C02实现存储秒表数据(附成果展示)

    目录 存储器 RAM ROM 存储器简化模型 AT24C02介绍  引脚及应用电路  内部结构框图 I2C总线 I2C总线介绍 I2C电路规范 I2C时序结构 起始条件 终止条件 发送一个字节  接受一个字节  发送应答  接收应答 I2C数据帧 AT24C02数据帧 字节写 随机读 代码部分 遇到的问题  代码  硬件  

    2024年04月25日
    浏览(40)
  • STM32软件模拟实现IIC写入和读取AT24C02(STM32CubeMx配置)

    IIC:Inter Integrated Circuit,集成电路总线,是一种 同步 串行 半双工 通信总线。 在使用IIC时分为硬件IIC以及软件IIC,下图为两者的区别: 在使用IIC前先来了解一下IIC总线结构图,即下图: 从图中可以看出IIC有两个双向信号线,一根是数据线SDA,一根是时钟线SCL,并且都接上拉

    2024年02月04日
    浏览(62)
  • 蓝桥杯嵌入式(G4系列)HAL:IIC通信之AT24C02与MCP4017

    目录 前言: IIC协议简介: 1、起始信号和停止信号: 2、应答信号: 3、读写字节: AT24C02: 字节写操作: 页写操作: 读操作: MCP4017: 写操作: 读操作:         本篇文章主要介绍IIC通信协议,同时给大家介绍一下蓝桥杯嵌入式的模块的AT24C02和MCP4017,此外本篇博客会采

    2023年04月09日
    浏览(92)
  • M24C02和AT24C02读写失败的原因

    最近做项目发现换了个st 的24c02 ,导致 24c02 读写失败。一般不认真看规格书,很难发现问题根源。原来是停止信号时序问题。脸都搞绿了,后来还怀疑是芯片不良导致了,换了几个芯片还是一样的问题。芯片厂家不厚道。没意思。 解决办法: 代码如下,恭喜有缘人少走一个

    2024年02月12日
    浏览(41)
  • AT24C02芯片使用介绍

    AT24C02简介       AT24C02是一个2K位串行CMOS E2PROM,内部含有256个8位字节,有一个16字节页写缓冲器。该器件通过IIC总线接口进行操作,有专门的写保护功能。应用于AT24C02制造过程的先进CMOS技术实质上减少了器件的功耗。              AT24C02特性       1、采用I2C 总线传输数据

    2023年04月14日
    浏览(44)
  • AT24C02读写操作 一

    #include \\\"stm32f10x.h\\\" //STM32头文件 #include \\\"sys.h\\\" #include \\\"delay.h\\\" #include \\\"usart.h\\\" #include \\\"at24c02.h\\\" int main (void){//主程序     u8 a;     u8 recvbuf[10]={0};          //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级     NVIC_Configuration();   

    2024年01月19日
    浏览(57)
  • AT24C32、AT24C64、AT24C128、AT24C256、AT24C512系列EEPROM芯片单片机读写驱动程序

    1.AT24C01/AT24C02系列EEPROM芯片单片机读写驱动程序 2.AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序 3.AT24C32、AT24C64、AT24C128、AT24C256、AT24C512系列EEPROM芯片单片机读写驱动程序 4.x24Cxx系列EEPROM芯片C语言通用读写程序 在前两篇博文中,分别记录了AT24C01、AT24C02,以及AT24C04、

    2024年02月02日
    浏览(51)
  • STM32——AT24C02(EEPROM )

    1、简介 AT24C02是一种2 Kb(256 × 8)串行电子可擦可编程只读存储器(EEPROM)芯片,支持标准I2C总线通信协议。 AT24C02的编程操作是以页为单位完成的,每次最多可编程8个连续字节。具体来说,AT24C02的一页大小为8个字节,每次写入数据时,需要确保写入的数据不跨页。因此,

    2024年04月13日
    浏览(45)
  • STM32速成笔记—EEPROM(AT24C02)

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! AT24C01/02/04/08/16…是一个1K/2K/4K/8K/16K位电可擦除PROM,内部含有128/256/512/1024/2048个8位字节,AT24C01有一个8字节页写缓冲器,AT24C02/04/08/16有一个16字节页写缓冲器。电压可允许低

    2024年02月11日
    浏览(63)
  • AT24C02(I2C总线)通信的学习

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

    2024年02月20日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包