一 STC32G 单片机EEPROM简介
STC32G系列单片机内部集成了大量的EEPROM,特别是STC32G12K128集成多达128K EEPROM。
STC32G内部EEPROM可擦写10万次,分若干扇区,每个扇区512字节。EEPROM的写操作只能将1写为0。要将0写为1,必须擦除扇区。EEPROM的读写是以字节为单位,擦除是以扇区为单位进行,要修改扇区内容,需要先将整个扇区内容读入内存,然后擦除整个扇区,然后再将内容写入扇区。STC32G的EEPROM操作时间与系统频率相关,设置好IAP_TPS寄存器值后,操作所需时间由硬件自动控制,IAP_TPS寄存器值 = 系统频率 / 1000000,如系统频率是30MHz,IAP_TPS寄存器值设为30.
与EEPROM相关的寄存器如下:
STC32G12K128的数据寄存器,仅IAP_DATA有效。
操作EEPROM的命令如下:
STC32G系列单片机仅支持命令CMD0~CMD3.
要操作STC32G EEPROM必须将IAP_CONTR寄存器的IAPEN设为1.在设置完操作地址与操心命令后必须分别向IAP_TRIG分别写入0x5A、0xA5,才能使命令生效。
二 与STC32G 单片机EEPROM 操作相关库函数的编写
EEPROM 的操作离不开操作与EEPROM相关的寄存器,如果不写相关的库函数,每次都直接去写操作寄存器的代码,非常麻烦,且工作量大,我们先写好库函数,后面要用时,调用即可,就会省去很多麻烦,提高效率。下面是我写的库函数。先看下头文件。
- /*STC32G_EEPROM.h
- Designed by Bill Liu
- Version 0.0
- Modified last by Bill Liu on 07/18/2022
- //macro function/
- IAP_STANDBY(); //idle,no operation command
- IAP_READ(); //read command
- IAP_WRITE(); //write command
- IAP_ERASE(); //erase section command
- IAP_ENABLE(); //IAP operation enable
- IAP_DISABLE(); //IAP operation disable
-
- //Function
- EEPROM_Disable(); //Set eeprom operating disable, return void
- EEPROM_Trig(); //set INT state,then send eeprom operating trigger signal, resore INT state,return void
- EEPROM_SectorErase(u32 EE_address); //erase EEPROM section, return void
- EEPROM_Read_nChar(ui32 EE_address,ui8* destData, u16 number); //read n char from eeprom begine from EE_address,return void
- EEPROM_Write_nChar(u32 EE_address,ui8* sourceData,u16 number); //write n char to eeprom begine from EE_address, return void
- EEPROM_Write_Integer(u32 EE_address,i16 sourceData); //write integer to eeprom begine from EE_address, return void
- EEPROM_Write_Long(u32 EE_address,i32 sourceData); //write long to eeprom begine from EE_address, return void
- EEPROM_Write_Float(u32 EE_address,f32 sourceData); //write float to eeprom begine from EE_address,return void
- EEPROM_Write_Double(u32 EE_address,f64 sourceData); //write double to eeprom begine from EE_address,return void
- EEPROM_Write_String(u32 EE_address,char* sourceStr); //read string from eeprom begine from EE_address, return void
- EEPROM_Read_Integer(u32 EE_address,i16* destData); //read integer from eeprom begine from EE_address,return i16
- EEPROM_Read_Long(u32 EE_address,i32* destData); //read long from eeprom begine from EE_address, return i32
- EEPROM_Read_Float(u32 EE_address,f32* destData); //ead float from eeprom begine from EE_address,return f32
- EEPROM_Read_Double(u32 EE_address,f64* destData); //read double from eeprom begine from EE_address, return f64
- EEPROM_Read_String(u32 EE_address,char* str); //read string from eeprom begine from EE_address,return void
- EEPROM_Read_StringnChar(u32 EE_address,char* str, ui16 number); //read string n char from eeprom begine from EE_address, return void
-
- */
-
- #ifndef __STC32G_EEPROM_H
- #define __STC32G_EEPROM_H
-
- #include "config.h"
- #include "mtype.h"
- #include <STC32G.h>
-
- #define IAP_STANDBY() {IAP_CMD = 0x00;} //idle,no operation command
- #define IAP_READ() {IAP_CMD = 0x01;} //read command
- #define IAP_WRITE() {IAP_CMD = 0x02;} //write command
- #define IAP_ERASE() {IAP_CMD = 0x03;} //erase section command
- #define IAP_ENABLE() {IAPEN = 1; IAP_TPS = FOSC / 1000000;} //FOSC defined in config.h
- #define IAP_DISABLE() {IAP_CONTR = 0; IAP_CMD = 0; IAP_TRIG = 0; IAP_ADDRH = 0xFF; IAP_ADDRL = 0xFF;}
-
- /*********************************************************
- Function: EEPROM_Disable();
- Return value: void
- Discription: Set eeprom operating disable
- Example:
- EEPROM_Disable();
- *********************************************************/
- void EEPROM_Disable();
-
- /****************************************************************
- Function: EEPROM_Trig();
- Return value: void
- Discription: set INT state,then send eeprom operating trigger signal, resore INT state
- Example:
- EEPROM_Trig();
- ****************************************************************/
- void EEPROM_Trig();
-
- /*********************************************************
- Function: EEPROM_SectorErase(u32 EE_address);
- Return value: void
- EE_address: eeprom address
- Discription: erase EE_address eeprom section
- Example:
- EEPROM_SectorErase(0x90F);
- *********************************************************/
- void EEPROM_SectorErase(u32 EE_address);
-
- /*********************************************************
- Function: EEPROM_Write_nChar(u32 EE_address,ui8* sourceData,u16 number);
- Return value: void
- EE_address: eeprom address
- sourceData: char arry name to write to eeprom
- Discription: write n char to eeprom begine from EE_address
- Example:
- EEPROM_Write_nChar(0x90F,mCharArray, 30);
- *********************************************************/
- void EEPROM_Write_nChar(u32 EE_address,ui8* sourceData,u16 number);
-
- /*********************************************************
- Function: EEPROM_Read_nChar(ui32 EE_address,ui8* destData, u16 number);
- Return value: void
- EE_address: eeprom address
- destData: char arry name to store read data
- Discription: read n char from eeprom begine from EE_address
- Example:
- EEPROM_Read_nChar(0x90F,mCharArray, 30);
- *********************************************************/
- void EEPROM_Read_nChar(ui32 EE_address,ui8* destData, u16 number);
-
- /*********************************************************
- Function: EEPROM_Write_Integer(u32 EE_address,i16 sourceData);
- Return value: void
- EE_address: eeprom address
- sourceData: data to write to eeprom
- Discription: write integer to eeprom begine from EE_address
- Example:
- EEPROM_Write_Integer(0x90F,1600);
- *********************************************************/
- void EEPROM_Write_Integer(u32 EE_address,i16 sourceData);
-
- /*********************************************************
- Function: EEPROM_Write_Long(u32 EE_address,i32 sourceData);
- Return value: void
- EE_address: eeprom address
- sourceData: data to write to eeprom
- Discription: write long to eeprom begine from EE_address
- Example:
- EEPROM_Write_Long(0x90F,1600);
- *********************************************************/
- void EEPROM_Write_Long(u32 EE_address,i32 sourceData);
-
- /*********************************************************
- Function: EEPROM_Write_Float(u32 EE_address,f32 sourceData);
- Return value: void
- EE_address: eeprom address
- sourceData: data to write to eeprom
- Discription: write float to eeprom begine from EE_address
- Example:
- EEPROM_Write_Long(0x90F,1600.53);
- *********************************************************/
- void EEPROM_Write_Float(u32 EE_address,f32 sourceData);
-
- /*********************************************************
- Function: EEPROM_Write_Double(u32 EE_address,f64 sourceData);
- Return value: void
- EE_address: eeprom address
- sourceData: data to write to eeprom
- Discription: write double to eeprom begine from EE_address
- Example:
- EEPROM_Write_Double(0x90F,1600.53);
- *********************************************************/
- void EEPROM_Write_Double(u32 EE_address,f64 sourceData);
-
- /*********************************************************
- Function: EEPROM_Write_String(u32 EE_address,char* sourceStr);
- Return value: void
- EE_address: eeprom address
- sourceStr: string to write to eeprom
- Discription: write string to eeprom begine from EE_address
- Example:
- EEPROM_Write_String(0x90F,"Hello world");
- *********************************************************/
- void EEPROM_Write_String(u32 EE_address,char* sourceStr);
-
- /*********************************************************
- Function: EEPROM_Read_Integer(u32 EE_address,i16* destData);
- Return value: i16
- EE_address: eeprom address
- destData: addess to store data to read
- Discription: read integer from eeprom begine from EE_address
- Example:
- i16 tem;
- EEPROM_Read_Integer(0x90F,&tem);
- *********************************************************/
- i16 EEPROM_Read_Integer(u32 EE_address,i16* destData);
-
- /*********************************************************
- Function: EEPROM_Read_Long(u32 EE_address,i32* destData);
- Return value: i32
- EE_address: eeprom address
- destData: addess to store data to read
- Discription: read long from eeprom begine from EE_address
- Example:
- i32 tem;
- EEPROM_Read_Long(0x90F,&tem);
- *********************************************************/
- i32 EEPROM_Read_Long(u32 EE_address,i32* destData);
-
- /*********************************************************
- Function: EEPROM_Read_Float(u32 EE_address,f32* destData);
- Return value: f32
- EE_address: eeprom address
- destData: addess to store data to read
- Discription: read float from eeprom begine from EE_address
- Example:
- f32 tem;
- EEPROM_Read_Float(0x90F,&tem);
- *********************************************************/
- f32 EEPROM_Read_Float(u32 EE_address,f32* destData);
-
- /*********************************************************
- Function: EEPROM_Read_Double(u32 EE_address,f64* destData);
- Return value: f64
- EE_address: eeprom address
- destData: addess to store data to read
- Discription: read double from eeprom begine from EE_address
- Example:
- f64 tem;
- EEPROM_Read_Double(0x90F,&tem);
- *********************************************************/
- f64 EEPROM_Read_Double(u32 EE_address,f64* destData);
-
- /*********************************************************
- Function: EEPROM_Read_String(u32 EE_address,char* str);
- Return value: void
- EE_address: eeprom address
- str: addess to store data to read
- Discription: read string from eeprom begine from EE_address
- Example:
- char str[20];
- EEPROM_Read_String(0x90F,str);
- *********************************************************/
- void EEPROM_Read_String(u32 EE_address,char* str);
-
- /*********************************************************
- Function: EEPROM_Read_StringnChar(u32 EE_address,char* str);
- Return value: void
- EE_address: eeprom address
- str: addess to store read data
- number: number of char to read
- Discription: read string n char from eeprom begine from EE_address
- Example:
- char str[20];
- EEPROM_Read_StringnChar(0x90F,str, 10);
- *********************************************************/
- void EEPROM_Read_StringnChar(u32 EE_address,char* str, ui16 number);
-
- #endif
头文件的开头注释部分列出了定义的宏函数与函数,编程使用是直接复制粘贴,替换参数即可:
再看下库函数的源码:
- /*STC32G_EEPROM.h
- Designed by Bill Liu
- Version 0.0
- Modified last by Bill Liu on 07/18/2022
- */
-
- #include "STC32G_EEPROM.h"
-
- //****************************************************************
- void EEPROM_Disable()
- {
- IAP_CONTR = 0;
- IAP_CMD = 0;
- IAP_TRIG = 0;
- IAP_ADDRE = 0xff; //set a disable operate addr
- IAP_ADDRH = 0xff; //set a disable operate addr
- IAP_ADDRL = 0xff; //set a disable operate addr
- }
- //End of EEPROM_Disable(void)
-
- //****************************************************************
- void EEPROM_Trig()
- {
- F0 = EA; //save EA state
- EA = 0; //INT disable
- IAP_TRIG = 0x5A;
- IAP_TRIG = 0xA5;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EA = F0; //restore EA
- }
- //End of EEPROM_Disable()
-
- //****************************************************************
- void EEPROM_SectorErase(u32 EE_address)
- {
- IAP_ENABLE();
- IAP_ERASE();
-
- IAP_ADDRL = (u8)EE_address;
- IAP_ADDRH = (u8)(EE_address >> 8);
- IAP_ADDRE = (u8)(EE_address >> 16);
-
-
- EEPROM_Trig();
- EEPROM_Disable();
- }
- //End of EEPROM_SectorErase(u32 EE_address)
-
- //****************************************************************
- void EEPROM_Write_nChar(u32 EE_address,ui8* sourceData,u16 number)
- {
- IAP_ENABLE();
- IAP_WRITE();
- do
- {
- IAP_ADDRL = (u8)EE_address;
- IAP_ADDRH = (u8)(EE_address >> 8);
- IAP_ADDRE = (u8)(EE_address >> 16);
- IAP_DATA = *sourceData;
-
- EEPROM_Trig();
-
- EE_address++;
- sourceData++;
- }while(--number);
- EEPROM_Disable();
- }
- //End of EEPROM_Write_nChar(u32 EE_address,ui8* sourceData,u16 number)
-
- //****************************************************************
- void EEPROM_Read_nChar(ui32 EE_address,ui8* destData, u16 number)
- {
- IAP_ENABLE();
- IAP_READ();
- do
- {
- IAP_ADDRL = (u8)EE_address;
- IAP_ADDRH = (u8)(EE_address >> 8);
- IAP_ADDRE = (u8)(EE_address >> 16);
-
- EEPROM_Trig();
-
- *destData = IAP_DATA;
-
- EE_address++;
- destData++;
- }while(--number);
-
- EEPROM_Disable();
- }
- //End of EEPROM_Read_nChar(ui32 EE_address,ui8* destData, u16 number)
-
- //****************************************************************
- void EEPROM_Write_Integer(u32 EE_address,i16 sourceData)
- {
- typedef union
- {
- i16 mData;
- char arry[2];
- }mySoure;
- mySoure source;
- source.mData = sourceData;
- EEPROM_Write_nChar(EE_address,source.arry,2);
- }
- //End of EEPROM_Write_Integer(u32 EE_address,i16 sourceData)
-
- //****************************************************************
- void EEPROM_Write_Long(u32 EE_address,i32 sourceData)
- {
- typedef union
- {
- i32 mData;
- char arry[4];
- }mySoure;
- mySoure source;
- source.mData = sourceData;
- EEPROM_Write_nChar(EE_address,source.arry,4);
- }
- //End of EEPROM_Write_Long(u32 EE_address,i32 sourceData)
-
- //*************************************************************
- void EEPROM_Write_Float(u32 EE_address,f32 sourceData)
- {
- typedef union
- {
- f32 mData;
- char arry[4];
- }mySoure;
- mySoure source;
- source.mData = sourceData;
- EEPROM_Write_nChar(EE_address,source.arry,4);
- }
- //End of EEPROM_Write_Float(u32 EE_address,f32 sourceData)
-
- //************************************************************
- void EEPROM_Write_Double(u32 EE_address,f64 sourceData)
- {
- typedef union
- {
- f32 mData;
- char arry[8];
- }mySoure;
- mySoure source;
- source.mData = sourceData;
- EEPROM_Write_nChar(EE_address,source.arry,8);
- }
- //End of EEPROM_Write_Double(u32 EE_address,f64 sourceData)
-
- //***********************************************************
- void EEPROM_Write_String(u32 EE_address,char* sourceStr)
- {
- EEPROM_Write_nChar(EE_address,sourceStr,strlen(sourceStr));
- EEPROM_Write_nChar(EE_address+strlen(sourceStr),0,1);
- }
- //End of EEPROM_Write_String(u32 EE_address,char* sourceStr)
-
- //***********************************************************************
- i16 EEPROM_Read_Integer(u32 EE_address,i16* destData)
- {
- typedef union
- {
- i16 mData;
- char arry[2];
- }myDest;
- myDest dest;
- EEPROM_Read_nChar(EE_address,dest.arry, 2);
- *destData = dest.mData;
- return *destData;
- }
- //End of EEPROM_Read_Integer(u32 EE_address,i16* destData)
-
- //***********************************************************************
- i32 EEPROM_Read_Long(u32 EE_address,i32* destData)
- {
- typedef union
- {
- i32 mData;
- char arry[4];
- }myDest;
- myDest dest;
- EEPROM_Read_nChar(EE_address,dest.arry, 4);
- *destData = dest.mData;
- return *destData;
- }
- //End of EEPROM_Read_Long(u32 EE_address,i32* destData)
-
- //***********************************************************************
- f32 EEPROM_Read_Float(u32 EE_address,f32* destData)
- {
- typedef union
- {
- f32 mData;
- char arry[4];
- }myDest;
- myDest dest;
- EEPROM_Read_nChar(EE_address,dest.arry, 4);
- *destData = dest.mData;
- return *destData;
- }
- //End of EEPROM_Read_Float(u32 EE_address,f32* destData)
-
- //***********************************************************************
- f64 EEPROM_Read_Double(u32 EE_address,f64* destData)
- {
- typedef union
- {
- f64 mData;
- char arry[8];
- }myDest;
- myDest dest;
- EEPROM_Read_nChar(EE_address,dest.arry, 8);
- *destData = dest.mData;
- return *destData;
- }
- //End of EEPROM_Read_Double(u32 EE_address,f64* destData)
-
- //***********************************************************************
- void EEPROM_Read_String(u32 EE_address,char* str)
- {
- ui8 tem = 0xFF;
- memset(str,0, strlen(str));
- while(tem != 0)
- {
- EEPROM_Read_nChar(EE_address,&tem, 1);
- *str = tem;
- str++;
- EE_address++;
- }
- }
- //End of EEPROM_Read_String(u32 EE_address,char* str)
-
- //***********************************************************************
- void EEPROM_Read_StringnChar(u32 EE_address,char* str, ui16 number)
- {
- memset(str,0, strlen(str));
- EEPROM_Read_nChar(EE_address, str, number);
- }
- //End of EEPROM_Read_nString(u32 EE_address,char* str, ui16 number)
三 调试验证
下面写一个程序,调用库函数,先将数据写入EEPROM,然后再读出,将读出的数据通过串口发送到串口助手,显示出来从而确定其正确性。
maim.h代码:
- /*main.h
- Designed by Bill Liu
- Version 0.0
- Modified last by Bill Liu on 06/22/2022
- */
-
- #ifndef __MAIN_H__
- #define __MAIN_H__
- //#include "myport.h"
- #include "STC32G_GPIO.h"
- //#include "STC32G_PWM.h"
- #include "STC32G_UART.h"
- //#include "STC32G_UART.h"
- //#include "STC32G_ADC.h"
- #include "STC32G_EEPROM.H"
-
-
- #endif
config.h代码:
- ifndef __CONFIG_H__
- #define __CONFIG_H__
-
- #define PRINTF_SEGLED //printfÊä³öÖض¨Ïòµ½ISPÏÂÔØÈí¼þÖеÄ7¶ÎÊýÂë¹Ü
- //#define PRINTF_HID //printfÊä³öÖ±½ÓÖض¨Ïòµ½USB HID½Ó¿Ú
-
- #define FOSC 30000000UL
- //#define F11_0592MHz
- //#define F12MHz
- //#define F18_432MHz //18.432MHz
- //#define F20MHz
- //#defimne F22_1184MHz //22.1184MHz
- //#define F24MHz
- //#define F27MHz
- #define F30MHz
- //#define F33MHz
- //#define F33_1776MHz //33.1776MHz
- //#define F35MHz
- //********************************************************
- void SysInit(); //init System speed fastest
-
-
- #endif
config.c代码:
- /*config.c
- Designed by Bill Liu
- Version 0.0
- Modified last by Bill Liu on 06/22/2022
- */
-
- #include <STC32G.h>
- #include "config.h"
-
-
- //********************************************************
- void SysInit() //init System speed fastest
- {
- EAXFR = 1; //visit XFR enable
- CKCON = 0x00; //set outer data bus speed fastest
- WTST = 0x00; //CPU wait 0 to run program
- }
- //End of SysInit()
main.c代码:
- /*main.c
- Designed by Bill Liu
- Version 0.0
- Modified last by Bill Liu on 11/26/2022
- */
-
- #include "main.h"
- //#include "config.h"
- //#include "STC32G_Timer.h"
- #include "STC32G_Delay.h"
- //#include "STC32G_comparator.h"
-
-
- ui8 t1 = 250;
- ui16 t2 = 65533;
- i32 t3 = -165533;
- f32 t4 = 51.25;
- f64 t5 = -3.14;
- ui8 t6 = 0;
- ui16 t7 = 0;
- i32 t8 = 0;
- f32 t9 = 0;
- f64 t10 = 0;
- ui8 str[20] = {0};
- ui8 str1[20] = "Hello World";
-
-
- void main()
- {
- SysInit();
- Uart1_Init(VBAUD_8BITS,G1, 0, 9600);
- EEPROM_SectorErase(0x00);
- EEPROM_Write_nChar(0x00,&t1,1);
- EEPROM_Write_Integer(0x01,t2);
- EEPROM_Write_Long(0x03,t3);
- EEPROM_Write_Float(0x07,t4);
- EEPROM_Write_Double(0x0B,t5);
- EEPROM_Write_String(0x13,str1);
- while(1)
- {
- EEPROM_Read_nChar(0x00,&t6,1);
- LongToString(t6,str);
- Uart1_SendString(str);
- Uart1_SendString("\r\n");
-
- EEPROM_Read_Integer(0x01,&t7);
- LongToString(t7,str);
- Uart1_SendString(str);
- Uart1_SendString("\r\n");
-
- EEPROM_Read_Long(0x03,&t8);
- LongToString(t8,str);
- Uart1_SendString(str);
- Uart1_SendString("\r\n");
-
- EEPROM_Read_Float(0x07,&t9);
- FloatString(t9,str,2);
- Uart1_SendString(str);
- Uart1_SendString("\r\n");
-
- EEPROM_Read_Double(0x0B,&t10);
- FloatString(t10,str,2);
- Uart1_SendString(str);
- Uart1_SendString("\r\n");
-
- EEPROM_Read_String(0x13,str);
- Uart1_SendString(str);
- Uart1_SendString("\r\n");
- Uart1_SendString("\r\n");
-
- Delayxms(1000);
- }
- }
- //End of main()
编译结果:
下载到单片机的设置如下:
打开串口,串口助手中的结果如下:
可以看出数据写入与读出正确,其中3.14变成了3.15并非写入与读出错误,而是单片机处理浮点数的不足。