I. Introduction to the environment

Programming software: KEil5

Operating system: Win10

MCU model: STM32F103ZET6

STM32 programming mode: register development (convenient program transplantation to other microcontrollers)

IIC bus: STM32 itself supports the IIC hardware timing, the last article has introduced the use of IIC simulation timing read and write AT24C02, this article introduces the STM32 hardware IIC configuration method, and read and write AT24C08.

The article addresses: xiaolong.blog.csdn.net/article/det…

Analog timing is more convenient to transplant to other MCU, with higher versatility, regardless of MCU; Hardware timing is more efficient, and each MCU configuration method is different, depending on the support of the hardware itself.

Device model: AT24C08 EEPROM memory chip

Complete engineering source download address, download to compile run tests (including the timing, STM32 hardware simulation IIC IIC timing driven AT24C02 and AT24C08) respectively: download.csdn.net/download/xi…

AT24C08 memory chip introduction

2.1 Functions and Features of the CHIP

AT24C08 is a serial CMOS TYPE EEPROM memory chip, AT24C0x this series contains AT24C01, AT24C02, AT24C04, AT24C08, AT24C16 these specific chip models.

Their capacities are: 1K (128 x 8), 2K (256 x 8), 8K (1024 x 8), and 16K (2048 x 8), where 8 represents 8 bits.

Their pin functions and packaging characteristics are as follows:

Chip function Description:

AT24C08 series supports I2C, bus data transfer protocol I2C, bus protocol specifies any device that transmits data to the bus as a transmitter. Any device that receives data from the bus is a receiver; Data transfer is controlled by the main device that generates the serial clock and all start stop signals. Both master and slave devices can act as transmitters or receivers, but the master controls the mode in which data is transmitted (sent or received).

Chip features:

1. Low voltage and standard voltage operation — 2.7 (VCC=2.7 to 5.5) — 1.8 (VCC=1.8 to 5.5)

2. Two-wire serial interface (SDA, SCL)

3. Write protection pins are available for hardware data protection

4. Self-timed write period (5 ms to 10 ms). Because there is an internal page buffer, after writing data to AT24C0x, it needs to wait for AT24C0x to write the buffer data to the internal EEPROM area.

5. Data can be stored for 100 years

6. 1 million erasure cycles

7. High data transmission rate of 400KHz, low speed of 100KHZ and IIC bus compatible. 100 kHz (1.8V) and 400 kHz (2.7V, 5V)

8. 8-byte page write Buffer The buffer size depends on the chip model: 8-byte pages (1K, 2K), 16-byte pages (4K, 8K, 16K)

2.2 Chip Device Addresses

Because the IIC protocol provides that each transfer of data is transmitted by 8 bytes, AT24C08 is 1024 bytes, the selection of address and AT24C02 are different;

The standard address bit for IIC devices is seven bits. In the figure above, 1010 of AT24C08 is the internal fixed value of the chip, A2 is the hardware pin, which is determined by the hardware level; P1, P0 is space storage block selection, each storage block size is 256 bytes, addressing range is 0 to 255, AT24C08 is equivalent to the structure of four AT24C02 blocks; The last one is the read/write is to write (1 is read, 0), read and write is not in the address bits, but according to the temporal order of IIC, before operating equipment, need to be sent seven address first, then send one to read and write, to start to the operation of the chip, in writing we simulated timing in order to facilitate unified for loop, in bytes to send, Therefore, 7 address bits and 1 read and write bits are generally combined together to form a byte, which is convenient for data transmission by byte.

The schematic of AT24C08 on the development board I’m using now looks like this:

Then the standard equipment address of AT24C08 is:

The first field: 0x50(hexadecimal), which corresponds to the binary: 1010000

The second field is 0x51(hexadecimal), which corresponds to 1010001 in binary

The third field: 0x52(hexadecimal), corresponding binary: 1010010

The fourth field is 0x53(hexadecimal), which corresponds to 1010011 in binary

If the read and write bits are combined, the device address of the read permission:

The first field is 0xA1(hexadecimal), the binary equivalent of which is 10100001

The second area is 0xA3(hexadecimal), which corresponds to 10100011 in binary

The third field: 0xA5(hexadecimal), the binary equivalent is: 10100101

The fourth field is 0xA7(hexadecimal), which corresponds to 10100111 in binary

If the read and write bits are combined, the address of the device with write permission:

The first field: 0xA0(hexadecimal), which corresponds to the binary: 10100000

The second field is 0xA2(hexadecimal), which corresponds to the binary 10100010

The third field: 0xA4(hexadecimal), corresponding binary: 10100100

The fourth field: 0xA6(hexadecimal), the binary equivalent is: 10100110

2.3 Instruction flow of writing data in bytes to AT24C08 (timing sequence)

** : **

1. Send the start signal first

2. Send device address (write permission)

3. Wait until AT24C08 responds and the low level is active

4. Send storage address, AT24C08 internal a total of 256 bytes of space, addressing from 0, the range is (0 to 255); Sending this memory address tells AT24C08 where to store the next data change.

5. Wait for AT24C08 to respond and the low level is active

6. Send one byte of data that you want to store in AT24C08.

7. Wait for AT24C08 to respond and the low level is active

8. Send a stop signal

 

2.3 Instruction flow of page writing data to AT24C08 (timing sequence)

Detailed explanation:

1. Send the start signal first

2. Send device address (write permission)

3. Wait until AT24C08 responds and the low level is active

4. Send storage address, AT24C08 internal a total of 256 bytes of space, addressing from 0, the range is (0 to 255); Sending this memory address tells AT24C08 where to store the next data change.

5. Wait for AT24C08 to respond and the low level is active

6. It can loop 8 bytes of data, which is the data that you want to store in AT24C08.

The page buffer of AT24C08 is 16 bytes, so the loop can only send 16 bytes at most, and any more bytes will overwrite the previous ones.

Note that the address of the page buffer also starts at 0, for example, 0 to 15 counts as page 1 and 16 to 32 counts as page 2…… And so on. If the starting address for writing data is now 3, then there are only 13 bytes left on the page to write; It’s not like you can loop 16 bytes from anywhere.

Detailed process: the program is generally used for loop implementation

(1). Send byte 1

(2). Wait for AT24C08 to respond, active low level

(3). Send bytes 2

(4). Wait for AT24C08 to respond, active low level

.

Up to eight times.

7. Wait for AT24C08 to respond and the low level is active

8. Send a stop signal

2.4 Reading Any byte data from any ADDRESS of AT24C08 (timing sequence)

AT24C08 supports current address read, arbitrary address read, the most commonly used or arbitrary address read, because you can specify the address to read data, more flexible, the above specified sequence diagram is arbitrary address read.

Detailed explanation:

1. Send the start signal first

2. Send device address (write permission)

3. Wait until AT24C08 responds and the low level is active

4. Send storage address, AT24C08 internal a total of 2048 bytes of space, addressing from 0, range (0~1024); Sending this memory address tells AT24C08 that it should return that address to the MCU next.

5. Wait for AT24C08 to respond and the low level is active

6. Re-send start signal (switch read/write mode)

7. Send device address (read permission)

8. Wait for AT24C08 to respond and the low level is active

9. Read data circularly: receive data returned by AT24C08.

There is no byte limit for reading data. It can be the first byte or read the entire chip consecutively.

10. Send non-reply (high active)

11. Send a stop signal

IIC bus introduction

2.1 Introduction to IIC Bus

I2C (Inter-Integrated Circuit) bus is a two-wire serial bus developed by PHILIPS. It is used to connect microcontrollers and their peripherals. It is a bus standard widely used in the field of microelectronic communication and control. It has the advantages of fewer interface lines, simple control mode, small device package form and higher communication rate.

The I2C protocol utilizes master/slave two-way communication. The device that sends data to the bus is defined as a transmitter, and the device that receives data is defined as a receiver. Both master and slave devices can operate in receive and send states.

The I2C bus transmits information between devices connected to the bus through serial data (SDA) lines and serial clock (SCL) lines. Each device has a unique address recognition, and each can act as a transmitter or receiver (depending on the function of the device).

The I2C works in four modes: 1. Host sending 2. Host receiving 3. Slave sending 4. From the machine to receive

The I2C bus uses only two cables: Serial Data (SDA) and Serial Clock (SCL).

The bus must be controlled by a host (usually a microcontroller) that generates a serial clock (SCL) that controls the direction of the bus transmission and generates start and stop conditions.

The data state on the SDA line changes only during the period when THE SCL is low.

2.2 Device connection diagram on IIC bus

I2C bus is very simple in physical connection. It is composed of SDA(serial data line) and SCL(serial clock line) and pull-up resistance. The communication principle is to generate signals required by I2C bus protocol for data transmission by controlling the timing sequence of high and low levels of SCL and SDA lines. When the bus is idle, the two wires are generally pulled up by the pull-up resistor connected above and kept at high level.

The pull-up resistance ranges from 4.7K to 100K.

2.3 I2C Bus Features

Each device on the I2C bus can act as either a master device or a slave device, and each slave device has a unique address (known from the I2C device data manual). Master and slave devices use this address to determine which device to communicate with. In common applications, the CPU module with I2C bus interface is regarded as the master device, and other devices connected to the bus are regarded as slave devices.

1. Number of devices that can be attached to the bus the number of devices that can be attached to the I2C bus is limited by the maximum capacitor of 400pF. If the devices of the same model are attached to the I2C bus, the number of devices that can be attached to the I2C bus is also limited by the device address. Generally, the I2C device address is a 7-bit address (there are also 10-bit addresses). The address is divided into two parts: the solidified address of the chip (which is fixed when the chip is grounded and which is connected to the power supply) and the programmable address (which is determined by the hardware to lead out the IO port). For example, if a device has a 7-bit address, the top 4 bits of 10101 XXX are fixed at the factory, and the bottom 3 bits can be determined by the designer. At least eight of these devices can be attached to an I2C bus. If all 7-bit addresses could be programmed, you could theoretically reach 128 devices, but you wouldn’t mount that many in practice.

2. Bus speed transmission speed: the data transmission rate of the I2C bus can reach 100kbit/s in standard mode, 400kbit/s in fast mode, and 3.4Mbit/s in high-speed mode. Generally, the transmission rate is adjusted by I2C bus interface programmable clock.

3. Bus data length Bidirectional data transmission is performed between the master device and slave device on the I2C bus in the unit of bytes (8 bits).

2.4 I2C bus protocol basic timing signal

Idle: BOTH SCL and SDA remain high.

Starting condition: When the bus is in idle state, both SCL and SDA remain high level. When SCL is in high level and SDA jumps from high to low, an starting condition is generated. After the initial condition is generated, the bus is in busy state and is exclusively used by the master and slave devices for data transmission. Other I2C devices cannot access the bus.

Stop condition: when SCL is high and SDA jumps from low to high, a stop condition is generated.

Promise signal: The next clock signal after the completion of each byte transmission. During the SCL high level, SDA is low, indicating a reply signal.

Non-promise signal: the next clock signal after the completion of each byte transmission. During the SCL high level, SDA is high and represents a reply signal. The answer signal or non-answer signal is sent by the receiver, and the sender detects this signal (the sender, which can be a slave device or a master device).

Note: start and end signals are always generated by the master device.

 

2.5 Start signal and Stop signal

The starting signal is: when the clock line SCL is at high level, the data line SDA changes from high level to low level. SCL=1; SDA=1; SDA=0;

Stop signal is: when the clock line SCL is at low level, the data line SDA changes from low level to high level. SCL=1; SDA=0; SDA=1;

2.6 Answer signal

The ninth bit of the data bit is the answer bit. The process for reading the reply bit is the same as reading the data bit. Example: SCL = 0; SCL=1; ACK=SDA; This ACK is the read reply state.

2.7 Timing of data bit transmission

According to the sequence diagram, the data is stable when SCL is at high level, and unstable when SCL is at low level.

So for writing one bit data (STM32– >AT24C08): SCL=0; SDA=data; SCL=1;

So for reading a bit of data (STM32<—–AT24C08): SCL=0; SCL=1; data=SDA;

2.8 Bus timing

IIC bus timing code, AT24C08 read and write code

When debugging the IIC simulation timing sequence, you can buy a 24M USB logic analyzer on Taobao. When problems occur in the timing sequence, you can quickly find the problem by analyzing the logic analyzer.

 

4.1 IIC. c This is the complete iIC hardware timing sequence code of STM32

/* Initialize the IIC bus hardware connection: SCL-- PB6 SDA-- PB7 */
void IIC_Init(void)
{
	 /*1. Configure the clock */
	 RCC->APB2ENR|=1<<3; //PB

 	 /*2. Configure the GPIO port mode */
	 GPIOB->CRL&=0x00FFFFFF;
	 GPIOB->CRL|=0xFF000000; // reuse open leakage output
	 GPIOB->ODR|=0x3<<6;
		
	 /*3. GPIO port clock configuration (correct sequence)*/
	 RCC->APB1ENR|=1<<21; / / I2C1 clock
	 RCC->APB1RSTR|=1<<21; // Enable the reset clock
	 RCC->APB1RSTR&=~(1<<21);// Turn off the reset clock
	
	 /*4. Configure the IIC core register */
	 I2C1->CR2=0x24<<0;  // set the host frequency to 36MHZ
	 I2C1->CCR|=0x2D<<0; // Set the host frequency to 400KHZ
	 I2C1->CR1|=1<<0;    // Start the IIC module
	
	/* CCR= host clock frequency /2/IIC bus frequency 45=36MHZ/ 2/400khz --0x2D */
}


/* Function function: the process of data line changing from high level to low level when the clock line is high when sending the initial signal */
void IIC_SendStart(void)
{
	I2C1->CR1|=1<<8; // Generate a start signal
	while(! (I2C1->SR1&1<<0)) {}// Wait for the start signal to complete
	I2C1->SR1=0; // Clear the status bit
}

/* Function function: the process of data line changing from low level to high level when clock line is high level when stop signal */
void IIC_SendStop(void)
{
		I2C1->CR1|=1<<9;
}

/* Function Send address data */
void IIC_SendAddr(u8 addr)
{
	u32 s1,s2;
	I2C1->DR=addr; // Send data
	while(1)
	{
			s1=I2C1->SR1;
			s2=I2C1->SR2;
		  if(s1&1<<1) // Check whether the address was sent successfully
			{
					break; }}}/*
函数功能: 发送数据
*/
void IIC_SendOneByte(u8 addr)
{
	u32 s1,s2;
	I2C1->DR=addr; // Send data
	while(1)
	{
			s1=I2C1->SR1;
			s2=I2C1->SR2;
			if(s1&1<<2) // Check whether the data is successfully sent
			{
					break; }}}/* Receives one byte of data */
u8 IIC_RecvOneByte(void)
{
	u8 data=0;
	I2C1->CR1|=1<<10; // Enable reply
	while(! (I2C1->SR1&1<<6)) {}// Wait for data
	data=I2C1->DR;
	I2C1->CR1&=~(1<<10); // Disable the answer function
	return data;
}
Copy the code

4.2 AT24C08.c This is the complete read and write code of AT24C08

U8 addr Specifies the location of the data (0~1023U8 data data range (0~255) * /void AT24C08_WriteOneByte(u16 addr,u8 data)
{
    u8 read_device_addr=AT24C08_READ_ADDR;
	u8 write_device_addr=AT24C08_WRITE_ADDR;
    if(addr<256*1) // first block
    {
        write_device_addr|=0x0<<1;
        read_device_addr|=0x0<<1;
    }
    else if(addr<256*2) // The second block
    {
        write_device_addr|=0x1<<1;
        read_device_addr|=0x1<<1;
    }
    else if(addr<256*3) // the third block
    {
        write_device_addr|=0x2<<1;
        read_device_addr|=0x2<<1;
    }
    else if(addr<256*4) // block 4
    {
        write_device_addr|=0x3<<1;
        read_device_addr|=0x3<<1;
    }
    addr=addr%256; // Get the address range

    
    IIC_SendStart(a);// Start signal
    IIC_SendAddr(write_device_addr);// Send device address
    IIC_SendOneByte(addr); // Address where data is stored
    IIC_SendOneByte(data); // Send the data to be stored
    IIC_SendStop(a);// Stop signal
    DelayMs(10); / / wait for writing
}


/* Function function: read a byte function parameter: u8 addr Data location (0 to 1023) Return value: read data */
u8 AT24C08_ReadOneByte(u16 addr)
{
    u8 data=0;
    u8 read_device_addr=AT24C08_READ_ADDR;
	u8 write_device_addr=AT24C08_WRITE_ADDR;
    if(addr<256*1) // first block
    {
        write_device_addr|=0x0<<1;
        read_device_addr|=0x0<<1;
    }
    else if(addr<256*2) // The second block
    {
        write_device_addr|=0x1<<1;
        read_device_addr|=0x1<<1;
    }
    else if(addr<256*3) // the third block
    {
        write_device_addr|=0x2<<1;
        read_device_addr|=0x2<<1;
    }
    else if(addr<256*4) // block 4
    {
        write_device_addr|=0x3<<1;
        read_device_addr|=0x3<<1;
    }
    addr=addr%256; // Get the address range

    IIC_SendStart(a);// Start signal
    IIC_SendAddr(write_device_addr);// Send device address
    IIC_SendOneByte(addr); // The address where the data will be read
    IIC_SendStart(a);// Start signal
    IIC_SendAddr(read_device_addr);// Send device address
    data=IIC_RecvOneByte(a);// Read data
    IIC_SendStop(a);// Stop signal
    return data;
}


Function Parameter: u16 addr Location of the data (0 to 1023) u16 len Length of the data to be read U8 * Buffer That stores the read data Returned value: Read data */
void AT24C08_ReadByte(u16 addr,u16 len,u8 *buffer)
{
	 u16 i=0;
	IIC_SendStart(a);// Start signal
	IIC_SendAddr(AT24C08_WRITE_ADDR);// Send device address
	IIC_SendOneByte(addr); // The address where the data will be read
	IIC_SendStart(a);// Start signal
	IIC_SendAddr(AT24C08_READ_ADDR);// Send device address
	
	for(i=0; i<len; i++) { buffer[i]=IIC_RecvOneByte(a);// Read data
	}
	IIC_SendStop(a);// Stop signal
}


/* Function Function: AT24C08 page write function Function Parameters: u16 addr Position of the data to be written (0 to 1023) u8 len Length of the data to be written (16 bytes per page) u8 * Buffer Stores the read data */
void AT24C08_PageWrite(u16 addr,u16 len,u8 *buffer)
{
		u16 i=0;
		IIC_SendStart(a);// Start signal
		IIC_SendAddr(AT24C08_WRITE_ADDR);// Send device address
		IIC_SendOneByte(addr); // Address where data is stored
		for(i=0; i<len; i++) {IIC_SendOneByte(buffer[i]); // Send the data to be stored
		}
		IIC_SendStop(a);// Stop signal
		DelayMs(10); / / wait for writing
}


Function Parameter: u16 addr Location of data (0 to 1023) u16 len Length of data to be written U8 * Buffer To store data to be written Returned value: Read data */
void AT24C08_WriteByte(u16 addr,u16 len,u8 *buffer)
{
		u8 page_byte=16-addr%16; // Get the number of bytes remaining on the current page
		if(page_byte>len) // Determine whether the current page has enough byte space to write
		{
				page_byte=len; // It can be written all at once
		}
		while(1)
		{
				AT24C08_PageWrite(addr,page_byte,buffer); / / write one page
				if(page_byte==len)break; / / finished
				buffer+=page_byte; // The pointer is offset
				addr+=page_byte;// Address offset
				len-=page_byte;// Get the remaining length
				if(len>16)page_byte=16;
				else page_byte=len; // It can be written in one time}}Copy the code

This is the AT24C08 test code

#include "stm32f10x.h"
#include "beep.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
#include "exti.h"
#include "timer.h"
#include "rtc.h"
#include "adc.h"
#include "ds18b20.h"
#include "ble.h"
#include "esp8266.h"
#include "wdg.h"
#include "oled.h"
#include "rfid_rc522.h"
#include "infrared.h"
#include "iic.h"
#include "at24c08.h"

u8 buff_tx[50] ="1234567890";
u8 buff_rx[50];
u8 data=88;
u8 data2;
int main(a)
{   
    u8 key;
    LED_Init(a);KEY_Init(a);BEEP_Init(a);TIM1_Init(72.20000); // auxiliary serial port 1 receives data. The timeout period is 20ms
    USART_X_Init(USART1,72.115200);

    IIC_Init(a);//IIC bus initialization
    printf("usart1 ok\n");

    while(1)
    {
        key=KEY_Scanf(a);if(key)
        {
            / / AT24C08_WriteByte (100, 50, buff_tx);
            / / AT24C08_ReadByte (100, 50, buff_rx);
            //printf("buff_rx=%s\n",buff_rx);

               // Test block 0
// data=AT24C08_ReadOneByte(0);
// AT24C08_WriteOneByte(0,data+1);
// printf("data=%d\n",data);
               // test block 1
// data=AT24C08_ReadOneByte(300);
// AT24C08_WriteOneByte(300,data+1);
// printf("data=%d\n",data);
               // test block 2
// data=AT24C08_ReadOneByte(600);
// AT24C08_WriteOneByte(600,data+1);
// printf("data=%d\n",data);
               // Test block 3
             data=AT24C08_ReadOneByte(900);
             AT24C08_WriteOneByte(900,data+1);
             printf("data=%d\n",data); }}}Copy the code

Serial debugging assistant source download address: blog.csdn.net/xiaolong112…