Programa de comunicación integrado LAN Bridge Cup IIC para escribir AT24C02 para realizar la función de almacenamiento EEPROM de datos

Programación de la comunicación IIC de Blue Bridge Cup integrada

Primero, abrimos el archivo del controlador oficial que contiene el código IIC

La ruta es la siguiente:
Diseño y desarrollo incrustados \ Programa de referencia I2C.
Agregue estos dos proyectos a nuestra plantilla de proyecto.
Inserte la descripción de la imagen aquí
Luego, abrimos la hoja de datos oficial que nos proporcionó AT24301.
Busque la introducción del bit de dirección y
Inserte la descripción de la imagen aquí
podrá ver que el bit de dirección viene determinado por el tamaño de la memoria A2 A1 P1 P0 Se decide por R / W,
entonces abrimos el diagrama esquemático que nos dio el funcionario para encontrar el chip al que quiere corresponder el IIC. El
Inserte la descripción de la imagen aquí
oficial es M24C02MN6 y el nuestro tiene algunos tomas de corriente,
pero no es importante. Podemos suponer que E0 E1 E2 corresponde a A0 A1 A2
debido a estos tres. Los pines están todos conectados a tierra, por lo que introdujimos que estos tres bits son todos bajos,
por lo que podemos determinar los bits de dirección que desear

Si queremos escribir (W),
nuestro bit de dirección es
1 0 1 0 0 0 0 (0)
[Por qué escribir 0, consulte el diagrama de secuencia de lectura y escritura a continuación]
Convertido a hexadecimal es 0xA0

Si queremos leer (R), entonces
1 0 1 0 0 0 0 (1)
[Por qué escribir 1, consulte el diagrama de secuencia de lectura y escritura a continuación]
Convertido a hexadecimal es 0xA1

A continuación, escribiremos uno de nuestros programas de lectura y escritura de IIC basados ​​en el diagrama de entrenamiento.

Inserte la descripción de la imagen aquí
Se puede ver claramente que la línea horizontal correspondiente arriba de R / W está debajo,
por lo que se infiere que Chu W (escritura) es de nivel bajo.
Entonces no necesitamos prestar atención al nivel alto y bajo del diagrama de tiempo
porque la biblioteca oficial ya ha escrito la función correspondiente.A
lo que debemos prestar atención es al orden en el que usamos las funciones oficiales (solo mire la parte superior del diagrama de tiempo) y ACK
nota: Esto -> DEVIE ADDRESS en realidad corresponde a la los siguientes 8 bytes, que es el bit de dirección del chip de memoria que mencionamos anteriormente. Vea que el frente es 1010 y luego 3 bits inciertos
y un R \ W son todos bits escritos

[ACK significa esperar respuesta del programa]
Mire de izquierda a derecha
-> INICIO
-> DIRECCIÓN DEL DISPOSITIVO

-> ACK
-> WORD ADDRESS
-> ACK
-> DATA
-> ACK
-> STOP
Desde el diagrama de entrenamiento, podemos ver que no solo necesitamos enviar
a la dirección
del componente, necesitamos enviar la dirección donde almacenamos los datos
y los datos que queremos almacenar

Uno de nuestros programas de envío que escribimos sobre esto.

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

Entonces escribiremos nuestro programa de lectura

Inserte la descripción de la imagen aquí

Entonces puede verse en este diagrama de tiempo
-> INICIO
-> DIRECCIÓN
DE DISPOSITIVO -> ACK
-> DIRECCIÓN WROD
-> ACK

-> INICIO
-> DIRECCIÓN DEL DISPOSITIVO
-> LEER
-> DATOS
-> NO ACK
-> DETENER
Esta función de lectura usamos el valor de retorno de I2CReceiveByte () para leer el
código fuente del programa de la siguiente manera

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

Luego implementamos la función de este programa IIC en la función principal.
Agregamos 1 al número de encendido que se muestra cada vez que encendemos

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

Inserte la descripción de la imagen aquí
A continuación se muestra el código de 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;
}

código 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

Supongo que te gusta

Origin blog.csdn.net/m0_46179894/article/details/108196306
Recomendado
Clasificación