找回密码
 注册
关于网站域名变更的通知
查看: 335|回复: 2
打印 上一主题 下一主题

STC系列单片机内部EEPROM 测试程序

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-9-10 09:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

, u' U; p4 x4 D' h5 |: I. z

3 d! J  f4 f8 i; Q/*********************************************************************************************" ]- ^# I! e4 V& W: X7 P
程序名:STC系列单片机内部EEPROM 测试程序/ s# y1 n7 {5 X7 d' M0 `
硬件电路:/ y) B8 R2 ^5 h; H
P1口接8个LED到VCC。1 N, z2 S8 P) Z: E
适用硬件:! z6 w2 H  U% N( Y4 F4 r4 n$ Y' `
STC12C2052系列(杜洋工作室改进部分)
! E3 C5 T6 f: K2 n4 Z: i, mSTC12C5AxxAD系列单片机( v- ?* y" P( ^/ R9 W& d4 B# a! y/ }
STC12C52xxAD系列单片机
8 E$ D9 I  Z& V5 wSTC11xx系列单片机
  K  I5 r7 d# w8 M2 YSTC10xx系列单片机
; }* l" j6 J7 E: G) i使用说明:9 }+ N# D- T" j' ^+ B$ w
1,程序先别P1口高4位和低4位分别点亮一次。2 k, }9 y! y9 f# K
2,检查EEPROM中对应地址内的值是否与用户测试值相同。
. ^* F/ Z. L) T) C3,如果相同则P1.7上的LED亮,然后在P1口显示EEPROM中的值。
( {( d- y: X( T5 U$ x4,如果不同则P1.3上的LED亮,然后全片擦除EEPROM并写入用户测试值到指定地址。
- t2 z2 [% e( b( e注意:
2 T( X9 j5 _+ [( k) P# 在第一次下载时为写入(第4步),复位后才会测试。1 H( U; K3 ?6 X4 I$ B# b  Z/ H+ ~
# 当供电电源低于一定值时将不能写入EEPROM,详见数据手册。  C" Y) Z- p. A
声明:) |3 z# E7 y3 }8 i& N
本程序基于宏晶公司STC11/10xx系列单片机EEPROM测试程序之上编写,详见官方数据手册。
# |) v& D! v! p( t/ O宏晶STC官网
4 `: u! p$ v' U
/ y' N/ d5 X4 E9 H  N: d. {
  • /*********************************************************************************************/
  • #include <reg51.H>
  • #include <intrins.H>
  • /*********************************************************************************************/
  • typedef unsigned char  INT8U;
  • typedef unsigned int   INT16U;
  • /*********************************************************************************************/
  • //用于STC12C2052系列单片机时选择//
  • sfr IAP_DATA    = 0xE2; //STC12C2052系列单片机的EEPRON操作地址是0xe2(以下类推)
  • sfr IAP_ADDRH   = 0xE3;
  • sfr IAP_ADDRL   = 0xE4;
  • sfr IAP_CMD     = 0xE5;
  • sfr IAP_TRIG    = 0xE6;
  • sfr IAP_CONTR   = 0xE7;
  • #define WD1 0x46 //使用STC12C2052系列单片机时,先写入0x46,然写入0xb9
  • #define WD2 0xb9
  • /*********************************************************************************************
  • //用于STC11/10xx系列单片机时选择//
  • sfr IAP_DATA    = 0xC2; //STC11xx系列单片机的EEPRON操作地址是0xc2(以下类推)
  • sfr IAP_ADDRH   = 0xC3;
  • sfr IAP_ADDRL   = 0xC4;
  • sfr IAP_CMD     = 0xC5;
  • sfr IAP_TRIG    = 0xC6;
  • sfr IAP_CONTR   = 0xC7;
  • #define WD1 0x5a //使用STC11xx系列单片机时,先写入0x5a,然写入0xa5
  • #define WD2 0xa5
  • /*********************************************************************************************/
  • //定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数//
  • //#define ENABLE_ISP 0x80 //系统工作时钟<30MHz 时,对IAP_CONTR 寄存器设置此值
  • //#define ENABLE_ISP 0x81 //系统工作时钟<24MHz 时,对IAP_CONTR 寄存器设置此值
  • #define ENABLE_ISP 0x82 //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
  • //#define ENABLE_ISP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值
  • //#define ENABLE_ISP 0x84 //系统工作时钟<6MHz 时,对IAP_CONTR 寄存器设置此值
  • //#define ENABLE_ISP 0x85 //系统工作时钟<3MHz 时,对IAP_CONTR 寄存器设置此值
  • //#define ENABLE_ISP 0x86 //系统工作时钟<2MHz 时,对IAP_CONTR 寄存器设置此值
  • //#define ENABLE_ISP 0x87 //系统工作时钟<1MHz 时,对IAP_CONTR 寄存器设置此值
  • /*********************************************************************************************/
  • #define DEBUG_DATA               0x55  //存储在 EEPROM 单元的数值(用户可修改测试)
  • #define DATA_FLASH_START_ADDRESS 0x00  //EEPROM存入地址(用户可修改测试)
  • /*********************************************************************************************/
  • union union_temp16
  • {
  •     INT16U un_temp16;
  •     INT8U  un_temp8[2];
  • }my_unTemp16;
  • INT8U Byte_Read(INT16U add);              //读一字节,调用前需打开IAP 功能
  • void Byte_Program(INT16U add, INT8U ch);  //字节编程,调用前需打开IAP 功能
  • void Sector_Erase(INT16U add);            //擦除扇区
  • void IAP_Disable();                       //关闭IAP 功能
  • void Delay();
  • /*********************************************************************************************/
  • void main (void)
  • {
  •     INT16U eeprom_address;
  •     INT8U  read_eeprom;
  •     P1 = 0xF0;                            //演示程序开始,让 P1[3:0] 控制的灯亮
  •     Delay();                              //延时
  •     P1 = 0x0F;                            //演示程序开始,让 P1[7:4] 控制的灯亮
  •     Delay()    ;                          //延时
  •     //将EEPROM 测试起始地址单元的内容读出
  •     eeprom_address = DATA_FLASH_START_ADDRESS;  //将测试起始地址送eeprom_address
  •     read_eeprom = Byte_Read(eeprom_address);    //读EEPROM的值,存到read_eeprom
  •     if (DEBUG_DATA == read_eeprom)
  •     {   //数据是对的,亮  P1.7 控制的灯,然后在 P1 口上将 EEPROM 的数据显示出来
  •         P1 = ~0x80;
  •         Delay()    ;                            //延时
  •         P1 = ~read_eeprom;
  •     }
  •     else
  •     {   //数据是错的,亮 P1.3 控制的灯,然后在 P1 口上将 EEPROM 的数据显示出来
  •         //再将该EEPROM所在的扇区整个擦除,将正确的数据写入后,亮 P1.5 控制的灯
  •         P1 = ~0x08;
  •         Delay()    ;                            //延时
  •         P1 = ~read_eeprom;
  •         Delay()    ;                            //延时
  •         Sector_Erase(eeprom_address);           //擦除整个扇区
  •         Byte_Program(eeprom_address, DEBUG_DATA);//将 DEBUG_DATA 写入 EEPROM
  •         P1 = ~0x20;                 //熄灭 P1.3 控制的灯,亮 P1.5 控制的灯
  •     }
  •     while (1);                      //CPU 在此无限循环执行此句
  • }
  • /*********************************************************************************************/
  • //读一字节,调用前需打开IAP 功能,入口PTR = 字节地址,返回:A = 读出字节
  • INT8U Byte_Read(INT16U add)
  • {
  •     IAP_DATA = 0x00;
  •     IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
  •     IAP_CMD = 0x01;                 //IAP/ISP/EEPROM 字节读命令
  •     my_unTemp16.un_temp16 = add;
  •     IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
  •     IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址
  •     //EA = 0;
  •     IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
  •     IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
  •     _nop_();
  •     //EA = 1;
  •     IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  •                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  •     return (IAP_DATA);
  • }
  • /*********************************************************************************************/
  • //字节编程,调用前需打开IAP 功能,入口PTR = 字节地址, A= 须编程字节的数据
  • void Byte_Program(INT16U add, INT8U ch)
  • {
  •     IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
  •     IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令
  •     my_unTemp16.un_temp16 = add;
  •     IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
  •     IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址
  •     IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
  •     //EA = 0;
  •     IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
  •     IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
  •     _nop_();
  •     //EA = 1;
  •     IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  •                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  • }
  • /*********************************************************************************************/
  • //擦除扇区, 入口PTR = 扇区地址
  • void Sector_Erase(INT16U add)
  • {
  •     IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
  •     IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令
  •     my_unTemp16.un_temp16 = add;
  •     IAP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
  •     IAP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址
  •     //EA = 0;
  •     IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 触发寄存器,每次都需如此
  •     IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被触发起动
  •     _nop_();
  •     //EA = 1;
  •     IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  •                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  • }
  • /*********************************************************************************************/
  • void IAP_Disable()
  • {
  •     //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  •     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  •     IAP_CONTR = 0;      //关闭IAP 功能
  •     IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
  •     IAP_TRIG  = 0;      //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
  •     IAP_ADDRH = 0;
  •     IAP_ADDRL = 0;
  • }
  • /*********************************************************************************************/
  • void Delay() //延时程序
  • {
  •     INT8U i;
  •     INT16U d=5000;
  •     while (d--)
  •     {
  •         i=255;
  •         while (i--);
  •     }
  • }
    7 K. A- z- L2 \" T+ X5 a

: i+ g9 i; _3 c
- d# E) y* e4 n0 J8 v  n

9 ^$ D) S  ^# W. I8 U

该用户从未签到

2#
发表于 2021-9-10 11:22 | 只看该作者
学习了  感谢分享

该用户从未签到

3#
发表于 2021-9-10 13:27 | 只看该作者
用的是哪块开发板呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-10-9 18:14 , Processed in 0.140625 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表