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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

9 Z' d3 B( B- A
1 N; M8 @9 q- o6 \4 ^9 p0 a$ d: U
/*********************************************************************************************
  ~0 R2 |5 @3 _& t* p. R, K; q程序名:STC系列单片机内部EEPROM 测试程序
5 w/ m( G7 H8 z: H硬件电路:2 E9 R. C1 s5 d. n- ~6 b& {& j7 z
P1口接8个LED到VCC。4 n3 R# t% D  d, ]& l" m2 }
适用硬件:' h; v2 R' y% {( _. z$ ~
STC12C2052系列(杜洋工作室改进部分)
* g$ ^: G; @) KSTC12C5AxxAD系列单片机0 E) l  G% S: f) Z9 V
STC12C52xxAD系列单片机/ M  f5 k7 U8 r8 i& P# U
STC11xx系列单片机. J# y2 L( j" t+ @: j% z  v) f
STC10xx系列单片机3 S! c" }- T: |$ }. W
使用说明:
  L2 z0 b, ~9 L6 B1,程序先别P1口高4位和低4位分别点亮一次。. J% l1 ~+ O5 C( r
2,检查EEPROM中对应地址内的值是否与用户测试值相同。8 p1 B; a  ]* Y: O( {
3,如果相同则P1.7上的LED亮,然后在P1口显示EEPROM中的值。
( F3 U* U2 {. ?5 @* p4,如果不同则P1.3上的LED亮,然后全片擦除EEPROM并写入用户测试值到指定地址。
% x# x' z" I- t! Z% u- F注意:7 ?; m6 {6 |- H& I
# 在第一次下载时为写入(第4步),复位后才会测试。0 `/ s5 h. Q& a4 f5 l
# 当供电电源低于一定值时将不能写入EEPROM,详见数据手册。
- A0 {; ~) `3 H' A/ Y' i声明:
& L$ T% ~' e+ g1 F1 {本程序基于宏晶公司STC11/10xx系列单片机EEPROM测试程序之上编写,详见官方数据手册。$ R. L+ {8 S( _) {! w
宏晶STC官网
0 g: ^. v% J0 |
' i7 Z3 @0 |) J) A$ k
  • /*********************************************************************************************/
  • #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--);
  •     }
  • }3 m- \2 J# K, D8 {
/ e: h* x9 J( w( R' {0 E

5 {& \$ Q" ]# j2 z, e
. N, K0 `$ x) {5 l9 K6 t% j  `

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-20 06:27 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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