当前位置:网站首页>SCM: introduction and operation of EEPROM
SCM: introduction and operation of EEPROM
2022-06-13 03:54:00 【DC-STDIO】
List of articles
EEPROM Introduce
In practical applications , Stored in the SCM RAM Data in , It was lost after power failure , Stored in the SCM FLASH Data in , It cannot be changed at will , That is, you can't use it to record the changing value . But on some occasions , We really need to record some data , And they often need to be changed or updated , Data cannot be lost after power failure , For example, the degree of our household electric meter , The channel memory in the TV , It's generally used EEPROM To save the data , It is characterized by no loss after power failure . The device we use on the board is 24C02, Is a capacity size of 2Kbits, That is to say 256 Bytes of EEPROM. In general ,EEPROM Have 30 Wan to 100 Ten thousand times of life , That is, it can be written repeatedly 30-100 Ten thousand times , The number of reads is infinite .
24C02 It's based on I2C Communication protocol device , So from now on , our I2C And our EEPROM It's about to fit . But let's be clear ,I2C It's a communication protocol , It has strict communication timing logic requirements , and EEPROM It's a device , It's just that this device is sampled I2C The interface of the protocol is connected with the single chip microcomputer , There is no necessary connection between the two ,EEPROM Other interfaces can be used ,I2C It can also be used in many other devices .
EEPROM Single byte read / write operation sequence
EEPROM Write data flow
First step , First of all I2C Start signal of , Then follow the first byte , That is what we talked about earlier I2C The device address of , And select... In the reading and writing direction “ Write ” operation .
The second step , Storage address for sending data .24C02 altogether 256 Bytes of storage space , Address from 0x00~0xFF, Where do we want to store the data , What address is written at the moment .
The third step , Send the first byte of data to be stored 、 The second byte „„ Note that in the process of writing data ,EEPROM Each byte will respond with a “ Response bit 0”, Tell us to write EEPROM Data are successfully , If there is no response, answer , Description: write failed .
In the process of writing data , Every successful byte written ,EEPROM The address of the storage space will be automatically added 1, When added to 0xFF after , Write another byte , The address will overflow and become 0x00.
EEPROM Read data flow
First step , First of all I2C Start signal of , Then follow the first byte , That is what we talked about earlier I2C The device address of , And select... In the reading and writing direction “ Write ” operation . This place may surprise some students , Why should we choose to read data “ Write ” Well ? Just said ,24C02 Altogether 256 An address , We choose to write , To write the storage address of the data to be read first , tell EEPROM Which address are we going to read . It's like we call , Dial the switchboard number first (EEPROM Device address ), And then continue to dial the extension number ( Data address ), And the act of dialing the extension number , The host is still the sender , The direction is still “ Write ”.
The second step , Send the address of the data to be read , Notice the address, not the presence EEPROM Data in , notice EEPROM Which extension do I need .
The third step , To resend I2C Start signal and device address , And select... In the direction bit “ read ” operation .
Of these three steps , Each byte is actually in “ Write ”, So every byte EEPROM Will respond to a “ Response bit 0”.
Step four , Read the data sent back from the device , Read a byte , If you want to continue reading the next byte , Just send one “ Response bit ACK(0)”, If you don't want to read , tell EEPROM, I don't want the data , Stop sending data , Then send one “ Non response bit NAK(1)”.
The same rules as the write operation , Every byte we read , The address will automatically add 1, So if we want to continue reading , to EEPROM One ACK(0) Low level , Then go on SCL Complete timing ,EEPROM Will continue to send data out . If we don't want to read , To tell EEPROM No more data , Let's just give one NAK(1) High level is enough . This place should be understood logically , You can't simply learn by rote , Be sure to understand . Sort out a few key points : A、 In this case, the single-chip microcomputer is the host ,24C02 It's a slave ; B、 Whether it's reading or writing ,SCL It is always controlled by the host ; C、 When writing, the response signal is given by the slave , Indicates whether the slave has received data correctly ; D、 When reading, the response signal is given by the host , Indicates whether to continue reading .
Let's write a program , Read EEPROM Of 0x02 A data on this address , No matter what the data was before , We all add... To the data we read 1, Write again EEPROM Of 0x02 On this address . In addition, we will I2C The program creates a file , Write a I2C.c Program files , Form another program module . You can also see , We continue these programs ,Lcd1602.c The procedures in the document are the same , In the future, we will all write 1602 The display program can also be used directly , It greatly improves the convenience of program transplantation .
/******************************I2C.c File program source code ******************************/
#include <reg52.h>
#include <intrins.h>
#define I2CDelay() {
_nop_();_nop_();_nop_();_nop_();}
sbit I2C_SCL = P3^7;
sbit I2C_SDA = P3^6;
/* Generate bus start signal */
void I2CStart(){
I2C_SDA = 1; // First, make sure SDA、SCL It's all high
I2C_SCL = 1;
I2CDelay();
I2C_SDA = 0; // Pull down first SDA
I2CDelay();
I2C_SCL = 0; // Pull down again SCL
}
/* Generate bus stop signal */
void I2CStop(){
I2C_SCL = 0; // First, make sure SDA、SCL It's all low level
I2C_SDA = 0;
I2CDelay();
I2C_SCL = 1; // Pull up first SCL
I2CDelay();
I2C_SDA = 1; // Pull up again SDA
I2CDelay();
}
/* I2C Bus write operation ,dat- Bytes to be written , Return value - The value of the slave reply bit */
bit I2CWrite(unsigned char dat){
bit ack; // Used to temporarily store the value of the reply bit
unsigned char mask; // A mask variable used to detect a bit value in a byte
for (mask=0x80; mask!=0; mask>>=1){
// From high to low
if ((mask&dat) == 0){
// The value of this bit is output to SDA On
I2C_SDA = 0;
}else{
I2C_SDA = 1;
}
I2CDelay();
I2C_SCL = 1; // pull up SCL
I2CDelay();
I2C_SCL = 0; // Pull down again SCL, Complete a bit cycle
}
I2C_SDA = 1; //8 After sending bit data , Host release SDA, To detect the slave response
I2CDelay();
I2C_SCL = 1; // pull up SCL
ack = I2C_SDA; // Read the SDA value , It is the response value of the slave
I2CDelay();
I2C_SCL = 0; // Pull down again SCL Complete response bit , And keep the bus
// The response value is reversed to conform to the usual logic :
//0= Not present or busy or write failed ,1= Exist and idle or write successfully
return (~ack);
}
/* I2C Bus read operation , And send a non reply signal , Return value - Bytes read */
unsigned char I2CReadNAK(){
unsigned char mask;
unsigned char dat;
I2C_SDA = 1; // First, make sure that the host is released SDA
for (mask=0x80; mask!=0; mask>>=1){
// From high to low
I2CDelay();
I2C_SCL = 1; // pull up SCL
if(I2C_SDA == 0){
// Read SDA Value
dat &= ~mask; // by 0 when ,dat The corresponding middle bit is cleared
}else{
dat |= mask; // by 1 when ,dat Corresponding position in 1
}
I2CDelay();
I2C_SCL = 0; // Pull down again SCL, So that the slave sends the next bit
}
I2C_SDA = 1; //8 After sending bit data , pull up SDA, Send non reply signal
I2CDelay();
I2C_SCL = 1; // pull up SCL
I2CDelay();
I2C_SCL = 0; // Pull down again SCL Complete the non reply bit , And keep the bus
return dat;
}
/* I2C Bus read operation , And send a reply signal , Return value - Bytes read */
unsigned char I2CReadACK(){
unsigned char mask;
unsigned char dat;
I2C_SDA = 1; // First, make sure that the host is released SDA
for (mask=0x80; mask!=0; mask>>=1){
// From high to low
I2CDelay();
I2C_SCL = 1; // pull up SCL
if(I2C_SDA == 0){
// Read SDA Value
dat &= ~mask; // by 0 when ,dat The corresponding middle bit is cleared
}else{
dat |= mask; // by 1 when ,dat Corresponding position in 1
}
I2CDelay();
I2C_SCL = 0; // Pull down again SCL, So that the slave sends the next bit
}
I2C_SDA = 0; //8 After sending bit data , Pull it down SDA, Send reply signal
I2CDelay();
I2C_SCL = 1; // pull up SCL
I2CDelay();
I2C_SCL = 0; // Pull down again SCL Complete response bit , And keep the bus
return dat;
}
I2C.c The document provides I2C All the underlying operating functions of the bus , Including the beginning 、 stop it 、 Byte write 、 Byte read + The reply 、 Byte read + Non response .
/***************************Lcd1602.c File program source code *****************************/
#include <reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;
/* Wait for the LCD to be ready */
void LcdWaitReady(){
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; // Read the status word
LCD1602_E = 0;
}while (sta & 0x80); //bit7 be equal to 1 Indicates that the LCD is busy , Repeat the test until it equals 0 until
}
/* towards LCD1602 LCD write one byte command ,cmd- Command value to be written */
void LcdWriteCmd(unsigned char cmd){
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* towards LCD1602 Write one byte of data to the LCD ,dat- Data value to be written */
void LcdWriteDat(unsigned char dat){
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* Set display RAM Initial address , That is, the cursor position ,(x,y)- Corresponding to the character coordinates on the screen */
void LcdSetCursor(unsigned char x, unsigned char y){
unsigned char addr;
if (y == 0){
// Calculated and displayed by the entered screen coordinates RAM The address of
addr = 0x00 + x; // The address of the first line of characters is from 0x00 start
}else{
addr = 0x40 + x; // The address of the second line of characters is from 0x40 start
}
LcdWriteCmd(addr | 0x80); // Set up RAM Address
}
/* Display string on LCD ,(x,y)- Corresponding to the starting coordinates on the screen ,str- String pointer */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str){
LcdSetCursor(x, y); // Set the starting address
while (*str != '\0'){
// Write string data continuously , Until the terminator is detected
LcdWriteDat(*str++);
}
}
/* initialization 1602 liquid crystal */
void InitLcd1602(){
LcdWriteCmd(0x38); //16*2 Show ,5*7 Lattice ,8 Bit data interface
LcdWriteCmd(0x0C); // The monitor is on , The cursor closes
LcdWriteCmd(0x06); // The words don't move , The address is automatically +1
LcdWriteCmd(0x01); // Clear the screen
}
/*****************************main.c File program source code ******************************/
#include <reg52.h>
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void I2CStart();
extern void I2CStop();
extern unsigned char I2CReadNAK();
extern bit I2CWrite(unsigned char dat);
unsigned char E2ReadByte(unsigned char addr);
void E2WriteByte(unsigned char addr, unsigned char dat);
void main(){
unsigned char dat;
unsigned char str[10];
InitLcd1602(); // Initialize the LCD
dat = E2ReadByte(0x02); // Read a byte at the specified address
str[0] = (dat/100) + '0'; // Convert to decimal string format
str[1] = (dat/10%10) + '0';
str[2] = (dat%10) + '0';
str[3] = '\0';
LcdShowStr(0, 0, str); // Display on LCD
dat++; // Set its value +1
E2WriteByte(0x02, dat); // Then write it back to the corresponding address
while (1);
}
/* Read EEPROM One byte in ,addr- Byte address */
unsigned char E2ReadByte(unsigned char addr){
unsigned char dat;
I2CStart();
I2CWrite(0x50<<1); // Addressing device , The following is the write operation
I2CWrite(addr); // Write storage address
I2CStart(); // Send repeat start signal
I2CWrite((0x50<<1)|0x01); // Addressing device , The following is the read operation
dat = I2CReadNAK(); // Read a byte of data
I2CStop();
return dat;
}
/* towards EEPROM Write a byte in ,addr- Byte address */
void E2WriteByte(unsigned char addr, unsigned char dat){
I2CStart();
I2CWrite(0x50<<1); // Addressing device , The following is the write operation
I2CWrite(addr); // Write storage address
I2CWrite(dat); // Write a byte of data
I2CStop();
}
This procedure , On the basis of the students' present , Independent analysis should not be difficult , If you don't understand any sentences, you can ask others or search in time , Understand the problem to be solved . After you copy this program , Compile it and you will find Keil The software prompts a warning :*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS, This warning means that there are variables or functions in the code that have not been called , namely I2C.c In the document I2CReadACK() This function is not used in this example .
Take a closer look at this program , We read EEPROM When , Read only one byte and tell EEPROM There is no need to read the data , Send a message directly after reading “NAK”, So only... Is called I2CReadNAK() This function , Instead of calling I2CReadACK() This function . We are likely to read several bytes continuously when reading data in the future , So this function is written in I2C.c In file , As I2C Part of the function module is necessary , It is convenient for us to migrate this file to other programs in the future , So don't worry about this warning here .
边栏推荐
- Use of Oracle PL-SQL
- Lambda termination operation Max & min
- [Yugong series] June 2022 Net architecture class 081 API customization task of distributed middleware schedulemaster
- Lambda end operation find and match findfirst
- 谈谈激光雷达的波长
- Lambda终结操作查找与匹配findFirst
- 基于PHP的轻量数码商城系统
- 2022春学期总结
- LVS four layer load balancing cluster (3) cluster function classification - HPC
- leetcode. 1 --- sum of two numbers
猜你喜欢
![[笔记]vs2015 编写汇编masm32之使用MASM32库](/img/f5/b47336af248d1b485208ec3f9ca12b.png)
[笔记]vs2015 编写汇编masm32之使用MASM32库
![[test development] advanced part - Classification of various test technologies](/img/39/aa79bf798bece478752091592a8a8b.png)
[test development] advanced part - Classification of various test technologies

单片机:Modbus 通信协议介绍

UnionPay commerce - merchant statistics service platform

What to bring to 2022

Ego planner code analysis ----cmakelists Txt and package xml

Difference between OKR and KPI

2022 spring semester summary

Time complexity

单片机:Modbus 多机通信程序设计
随机推荐
单片机外设介绍:温度传感器 DS18B20
Very simple installation and configuration of nodejs
单片机信号发生器程序
[笔记]vs2015 编写汇编masm32之使用MASM32库
扫地机器人如何才能避障不“智障”?五种主流的避障技术解析
Lambda终结操作查找与匹配findAny
Difference between OKR and KPI
[web] cookies and sessions
Triggers & built-in packages
单片机:D/A 输出
MySQL 8.0 enables remote root user access and solves the problem of you are not allowed to create a user with Grant
Multi thread writing method and the making of slot machine
【测试开发】进阶篇——各种测试技术分类
任总与系统工程领域科学家、专家会谈纪要
Fundamentals of robot obstacle avoidance system
[Yugong series] June 2022 Net architecture class 081 API customization task of distributed middleware schedulemaster
Lambda终结操作reduce归并
大疆无人机飞控系统的原理、组成及各传感器的作用
Multi thread implementation of selling tickets and producers and consumers
Lightweight digital mall system based on PHP