Embedded LAN Bridge Cup IIC communication program to write AT24C02 to realize data EEPROM storage function

Programming of Embedded Blue Bridge Cup IIC Communication

First, we open the official driver file that contains the IIC code

The path is as follows:
Embedded Design and Development\I2C Reference Program.
Add these two projects to our project template.
Insert picture description here
Then we open the official data manual for AT24301.
Find the address bit introduction and
Insert picture description here
you can see that the address bit is determined by the memory size A2 A1 P1 P0 R/W to decide,
so we open the official schematic to find the chip I want to correspond to. The
Insert picture description here
official one is M24C02MN6 and ours some outlets,
but it is not important. We can guess that E0 E1 E2 corresponds to A0 A1 A2
because of these three The pins are all grounded, so we introduced that these three bits are all low,
so we can determine the address bits we want

If we want to write (W),
our address bit is
1 0 1 0 0 0 0 (0)
[Why write 0, please see the read and write sequence diagram below]
Converted to hexadecimal is 0xA0

If we want to read (R), then
1 0 1 0 0 0 0 (1)
[Why write 1 please see the read and write sequence diagram below]
converted to hexadecimal is 0xA1

Next, we will write one of our IIC read and write programs based on the training diagram

Insert picture description here
It can be clearly seen that the corresponding horizontal line above R/W is below,
so it is inferred that Chu W (write) is low level.
Then we don’t need to pay attention to the high and low level of the timing diagram
because the official library has already written the corresponding Function
What we need to pay attention to is the order in which we use official functions (just look at the top of the timing diagram) and ACK
note: This ->DEVIE ADDRESS actually corresponds to the following 8 bytes, which is the address bit of the memory chip we mentioned earlier. See that the front is 1010 and then 3 uncertain bits
and one R\W are all written bits

[ACK stands for waiting for program response]
Look from left to right
-> START
->DEVICE ADDRESS

->ACK
->WORD ADDRESS
->ACK
->DATA
->ACK
->STOP
From the training diagram, we can see that we not only need to send
to the address
of the component, we need to send the address where we store the data
and the data we want to store

One of our sending programs we wrote about this

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

Then we will write our reading program

Insert picture description here

Then it can be seen from this timing diagram
->START
->DEVIE ADDRESS
->ACK
->WROD ADRESS
->ACK

->START
->DEVEICE ADDRESS
->READ
->DATA
->NO ACK
->STOP
This read function we use the return value of I2CReceiveByte() to read the
program source code as follows

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);
}

Then we implement the function of this IIC program in the main function.
We add 1 to the power-on number displayed every time we power-on

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){
    
    			
	}
}

Insert picture description here
Below is the code of 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 code

#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

Guess you like

Origin blog.csdn.net/m0_46179894/article/details/108196306