嵌入式蓝桥杯IIC通信程序编写AT24C02 实现数据EEPROM存储功能

嵌入式蓝桥杯IIC通信程序编写

首先我们打开官方提供的驱动文件里包含了 IIC代码

路径如下
嵌入式设计与开发\I2C参考程序
把这两个工程加入我们的工程模板中
在这里插入图片描述
然后我们打开官方给我们AT24301的数据手册
找到地址位介绍的
在这里插入图片描述
可以看到地址位是由内存大小 A2 A1 P1 P0 R/W来决定的
于是我们打开官方给我们的原理图 找到IIC想对应的芯片
在这里插入图片描述
官方的是M24C02MN6和我们的有些出路
但是不重要 我们可以猜测出 E0 E1 E2对应的就是 A0 A1 A2
因为这三个引脚都是置地的 所以我们推出这三个位都是 低电平
所以这样我们就确定的我们要的地址位

如果我们要写(W)的话
我们的地址位是
1 0 1 0 0 0 0 (0)
【为什么写是0 请看下面读写时序图】
换算成十六进制就是 0xA0

如果我们要读(R)的话
1 0 1 0 0 0 0 (1)
【为什么写是1 请看下面读写时序图】
换算成十六进制就是 0xA1

接下来我们根据实实训图来编写我们的一个IIC读写程序

在这里插入图片描述
可以清楚的看到 R/W上面对应的 横线是在下面
所以推断楚W(写)是低电平
然后我们不用关注时序图的高低电平
因为官方给我们的库中已经写好相对应的函数
我们需要注意的是我们使用官方函数的顺序(只需看时序图的上方) 和ACK
注释:这个->DEVIE ADDRESS 其实对应下面8个字节就是我们前面提到的存储芯片的地址位 可以明显看到 前面是 1010 然后3个不确定位
和一个R\W都写位

[ACK 代表等待程序响应]
从左往右看
-> START
->DEVICE ADDRESS

->ACK
->WORD ADDRESS
->ACK
->DATA
->ACK
->STOP
从实训图中我们可以看出 我们不仅要发送
给元器件的地址
发要发送我们存储数据地址
以及我们要存储的数据

对此我们编写的我们的一个发送程序

void x24c02_write(unsigned char address,unsigned char info)
{
    
    
	I2CStart(); 
	I2CSendByte(0xa0); 
	I2CWaitAck(); 
	
	I2CSendByte(address);	
    I2CWaitAck(); 
	I2CSendByte(info); 
	I2CWaitAck(); 
	I2CStop();
}

然后我们紧接着又来编写我们的读程序

在这里插入图片描述

然后从这个这个时序图可以看出
->START
->DEVIE ADDRESS
->ACK
->WROD ADRESS
->ACK

->START
->DEVEICE ADDRESS
->READ
->DATA
->NO ACK
->STOP
这个读取函数我们是用I2CReceiveByte()的返回值来读取的
程序源码如下

uint8_t x24c02_read(uint8_t address)
{
    
    
	unsigned char val;
	//发送芯片的写地址
	I2CStart(); 
	I2CSendByte(0xa0);
	I2CWaitAck(); 
	I2CSendByte(address);
	I2CWaitAck(); 
	
	I2CStart();
	I2CSendByte(0xa1); 
	I2CWaitAck();
	val = I2CReceiveByte(); 
	I2CWaitAck();
	I2CStop();
	
	return(val);
}

接着我们在主函数来实现这这个IIC的程序的功能
我们每次上电的 显示的上电数加1

int main(void)
{
    
    
	uint8_t temp;
	uint8_t string[20];
	
    SysTick_Config(SystemCoreClock/1000);  //1msÖжÏÒ»´Î

	//LCD¹¤×÷ģʽÅäÖÃ
	STM3210B_LCD_Init();
	LCD_Clear(White);
	LCD_SetTextColor(White);
	LCD_SetBackColor(Blue);
    
	LCD_ClearLine(Line0);
	LCD_ClearLine(Line1);
	LCD_ClearLine(Line2);
	LCD_ClearLine(Line3);
	LCD_ClearLine(Line4);

	LCD_DisplayStringLine(Line1,"      I2C DEMO      ");
	LCD_DisplayStringLine(Line3,"     AT24C02 R/W    ");

	LCD_SetTextColor(Blue);
	LCD_SetBackColor(White);

	i2c_init();	
	temp = IIC_read(0xff);
	Delay_Ms(2);
	IIC_write(0xff,++temp);
	Delay_Ms(2);
	
	sprintf(string,"%s%d","ADDR:0xFF,VAL:",temp);
	LCD_DisplayStringLine(Line6,string);
		
    while(1){
    
    			
	}
}

在这里插入图片描述
下面是I2C.c的代码

/*
  ³ÌÐò˵Ã÷: CT117EǶÈëʽ¾ºÈü°åGPIOÄ£ÄâI2C×ÜÏßÇý¶¯³ÌÐò
  Èí¼þ»·¾³: Keil uVision 4.10 
  Ó²¼þ»·¾³: CT117EǶÈëʽ¾ºÈü°å
  ÈÕ    ÆÚ: 2011-8-9
*/

#include "stm32f10x.h"

/** I2C ×ÜÏß½Ó¿Ú */
#define I2C_PORT GPIOB
#define SDA_Pin	GPIO_Pin_7
#define SCL_Pin GPIO_Pin_6

#define FAILURE 0
#define SUCCESS 1

//ÅäÖÃSDAÐźÅÏßΪÊäÈëģʽ
void SDA_Input_Mode()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = SDA_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}

//ÅäÖÃSDAÐźÅÏßΪÊä³öģʽ
void SDA_Output_Mode()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = SDA_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}

//
void SDA_Output( uint16_t val )
{
    
    
	if ( val ) {
    
    
		GPIO_SetBits(I2C_PORT,SDA_Pin);
	} else {
    
    
		GPIO_ResetBits(I2C_PORT,SDA_Pin);
	}
}

//
void SCL_Output( uint16_t val )
{
    
    
	if ( val ) {
    
    
		GPIO_SetBits(I2C_PORT,SCL_Pin);
	} else {
    
    
		GPIO_ResetBits(I2C_PORT,SCL_Pin);
	}
}

//
uint8_t SDA_Input()
{
    
    
	return GPIO_ReadInputDataBit( I2C_PORT, SDA_Pin);
}

//ÑÓʱ³ÌÐò
void delay1(unsigned int n)
{
    
    
	unsigned int i;
	for ( i=0;i<n;++i);
}

//I2C×ÜÏßÆô¶¯
void I2CStart(void)
{
    
    
	SDA_Output(1);delay1(500);
	SCL_Output(1);delay1(500);
	SDA_Output(0);delay1(500);
	SCL_Output(0);delay1(500);
}

//I2C×ÜÏßÍ£Ö¹
void I2CStop(void)
{
    
    
	SCL_Output(0); delay1(500);
	SDA_Output(0); delay1(500);
	SCL_Output(1); delay1(500);
	SDA_Output(1); delay1(500);

}

//µÈ´ýÓ¦´ð
unsigned char I2CWaitAck(void)
{
    
    
	unsigned short cErrTime = 5;
	SDA_Input_Mode(); 
	delay1(500);
	SCL_Output(1);delay1(500);
	while(SDA_Input())
	{
    
    
		cErrTime--;
		delay1(500);
		if (0 == cErrTime)
		{
    
    
			SDA_Output_Mode();
			I2CStop();
			return FAILURE;
		}
	}
	SDA_Output_Mode();
	SCL_Output(0);delay1(500); 
	return SUCCESS;
}

//·¢ËÍÓ¦´ðλ
void I2CSendAck(void)
{
    
    
	SDA_Output(0);delay1(500);
	delay1(500);
	SCL_Output(1); delay1(500);
	SCL_Output(0); delay1(500);

}

//
void I2CSendNotAck(void)
{
    
    
	SDA_Output(1);
	delay1(500);
	SCL_Output(1); delay1(500);
	SCL_Output(0); delay1(500);

}

//ͨ¹ýI2C×ÜÏß·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ý
void I2CSendByte(unsigned char cSendByte)
{
    
    
	unsigned char  i = 8;
	while (i--)
	{
    
    
		SCL_Output(0);delay1(500); 
		SDA_Output(cSendByte & 0x80); delay1(500);
		cSendByte += cSendByte;
		delay1(500); 
		SCL_Output(1);delay1(500); 
	}
	SCL_Output(0);delay1(500); 
}

//´ÓI2C×ÜÏß½ÓÊÕÒ»¸ö×Ö½ÚÊý¾Ý
unsigned char I2CReceiveByte(void)
{
    
    
	unsigned char i = 8;
	unsigned char cR_Byte = 0;
	SDA_Input_Mode(); 
	while (i--)
	{
    
    
		cR_Byte += cR_Byte;
		SCL_Output(0);delay1(500); 
		delay1(500); 
		SCL_Output(1);delay1(500); 
		cR_Byte |=  SDA_Input(); 
	}
	SCL_Output(0);delay1(500); 
	SDA_Output_Mode();
	return cR_Byte;
}

//I2C×ÜÏß³õʼ»¯
void i2c_init()
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStructure.GPIO_Pin = SDA_Pin | SCL_Pin;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 // **

  	GPIO_Init(I2C_PORT, &GPIO_InitStructure);

}
//自己写的代码
void IIC_write(unsigned char address,unsigned char info)
{
    
    
   I2CStart();
	 I2CSendByte(0xa0);
	 I2CWaitAck();
	
	 I2CSendByte(address);
	 I2CWaitAck();
	 I2CSendAck();
	 I2CWaitAck();
	 I2CStop();
}
u8 IIC_read(u8 adress)
{
    
    
	unsigned char val;
	I2CStart();
	I2CSendByte(0XA0);
	I2CWaitAck();
	
	I2CSendByte(adress);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	val=I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	
	return val;
}

i2c.h的代码

#ifndef  __I2C_H__
#define  __I2C_H__
#include "stm32f10x.h"
void i2c_init(void);
void delay1(unsigned int n);

void I2CStart(void);
void I2CStop(void);
void I2CSendAck(void);
void I2CSendNotAck(void);
unsigned char I2CWaitAck(void);

void I2CSendByte(unsigned char cSendByte);
unsigned char I2CReceiveByte(void);
void IIC_write(unsigned char address,unsigned char info);
u8 IIC_read(u8 adress);
#endif

猜你喜欢

转载自blog.csdn.net/m0_46179894/article/details/108196306