我是靠谱客的博主 昏睡超短裙,最近开发中收集的这篇文章主要介绍STC系列单片机 EEPROM/IAP 功能测试程序演示,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

STC系列单片机 EEPROM/IAP 功能测试程序演示

 

 

 

#include "reg51.H"
#include "intrins.H"
typedef unsigned char  INT8U;
typedef unsigned int   INT16U;
sfr IAP_DATA    = 0xC2;
sfr IAP_ADDRH   = 0xC3;
sfr IAP_ADDRL   = 0xC4;
sfr IAP_CMD     = 0xC5;
sfr IAP_TRIG    = 0xC6;
sfr IAP_CONTR   = 0xC7;
//定义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             0x5A  //本测试程序最终存储在 EEPROM 单元的数值
#define DATA_FLASH_START_ADDRESS 0x00  //STC5Axx 系列 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;
    P2 = 0xF0;                        //演示程序开始,让 P1[3:0] 控制的灯亮
    Delay();                          //延时
    P2 = 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 的数据显示出来
      P2 = ~0x80;
       Delay()    ;                        //延时
       P2 = ~read_eeprom;
    }
    else
    {  //数据是错的,亮 P1.3 控制的灯,然后在 P1 口上将 EEPROM 的数据显示出来
       //再将该EEPROM所在的扇区整个擦除,将正确的数据写入后,亮 P1.5 控制的灯
       P2 = ~0x08;
       Delay()    ;                        //延时
       P2 = ~read_eeprom;
       Delay()    ;                        //延时
       Sector_Erase(eeprom_address);         //擦除整个扇区
       Byte_Program(eeprom_address, DEBUG_DATA);//将 DEBUG_DATA 写入 EEPROM
       P2 = ~0x20;              //熄灭 P1.3 控制的灯,亮 P1.5 控制的灯
    }
    while (1);                   //CPU 在此无限循环执行此句
}
//读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回: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 = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                 //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    return (IAP_DATA);
}
//字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, 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 = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    //EA = 1;
    IAP_Disable();  //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                 //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
//擦除扇区, 入口:DPTR = 扇区地址
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 = 0x5A;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xA5;   //送完A5h 后,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--);
    }
}

 


 

//STC 12C5A60S2系列单片机EEPROM/IAP 功能测试程序演示
#include "reg5 1.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//IAP相关端口定义
sfr  IAP_DATA   = 0xC2;      //Flash 数据寄存器
sfr  IAP_ADDRH  = 0xC3;      //Flash 高位地址
sfr  IAP_ADDRL  = 0xC4;      //Flash 低位地址
sfr  IAP_CMD    = 0xC5;      //Flash 命令寄存器
sfr  IAP_TRIG   = 0xC6;      //Flash 命令触发
sfr  IAP_CONTR  = 0xC7;      //Flash 控制寄存器
//IAP命令定义
#define   CMD_IDLE      0    //待机
#define   CMD_READ      1    //位-读
#define   CMD_WRITE     2    //位-程序
#define   CMD_ERASE     3    //扇区-擦除
//IAP时间常数
//#define   ENABLE_IAP   0x80    //如果系统时钟<30MHz
//#define   ENABLE_IAP   0x81    //如果系统时钟<24MHz
//#define   ENABLE_IAP   0x82    //如果系统时钟<20MHz
//#define   ENABLE_IAP   0x83    //如果系统时钟<12MHz
//#define   ENABLE_IAP   0x84    //如果系统时钟<6MHz
//#define   ENABLE_IAP   0x85    //如果系统时钟<3MHz
//#define   ENABLE_IAP   0x86    //如果系统时钟<2MHz
//#define   ENABLE_IAP   0x87    //如果系统时钟<1MHz
#define    IAP_ADDRESS   0x0000  //STC12C5A60S2 系列 EEPROM 起点地址
void Delay(unsigned char n);
void IapIdle();                                     //保护
unsigned char IapReadByte(unsigned int addr);
void IapWriteByte(unsigned int addr, unsigned char dat);
void IapEraseSector(unsigned int addr);                     //擦除扇区
void main()
{
    unsigned int i;                                         //unsigned int i
    P1 = 0xfe;                                      // 1111 ,1110 系统复位 OK
    Delay(10);                                      //延时
    IapEraseSector(IAP_ADDRESS);                    //擦除扇区(60s2两个扇区)
    for (i=0; i<512; i++)                           //校验全部扇区数据是否是0xFF
    {
        if (IapReadByte(IAP_ADDRESS+i) != 0xff)
            goto Error;                             //如果错误, break
    }
    P1 = 0xfc;                                      // 1111 ,11 00 P1指示擦除完成
    Delay(10);                                      //延时
    for (i=0; i<512; i++)                           //Program 512 字节数据 into data flash
    {
        IapWriteByte(IAP_ADDRESS+i, (unsigned char)i);
    }
    P1 = 0xf8;                                      // 1111 ,1000 P1指示程序完成
    Delay(10);                                      //延时
    for (i=0; i<512; i++)                           //确认 512 字节数据
    {
    if (IapReadByte(IAP_ADDRESS+i) != (unsigned char)i)
        goto Error;                                 //如果错误, break
    }
    P1 = 0xf0;                                      // 1111 ,0000 确认完成
    while ( 1);
    Error:
    P1 &= 0x7f;                                     //0xxx,xxxx IAP 操作失败
    while ( 1);
}
/*----------------------------Software delay function----------------------------*/
void Delay(unsigned char n)
{
    unsigned int x;
    while (n--)
    {
        x = 0;
        while (++x);
    }
}
/**********************************************************
** 函数名称: void IapIdle();
** 功能描述: 退出IAP功能
**********************************************************/
void IapIdle()
{
    IAP_CONTR = 0;       //关闭 IAP 功能
    IAP_CMD   = 0;       //清除命令寄存器进入待机模式
    IAP_TRIG  = 0;       //清除触发寄存器
    IAP_ADDRH = 0xFF;    //IAP指针移动到非 EEPROM 区域
    IAP_ADDRL = 0xFF;
}
/**********************************************************
** 函数名称: unsigned char IapReadByte(unsigned int addr);
** 功能描述: 读EEPROM
** 输   入: unsigned int addr  地址
** 输   出: unsigned char dat  数据
**********************************************************/
unsigned char IapReadByte(unsigned int addr)
{
    unsigned char dat;        //数据缓冲
    IAP_CONTR = ENABLE_IAP;   //打开 IAP 过程, 并设置等待时间
    IAP_CMD   = CMD_READ;     //设置 ISP/IAP/EEPROM 为读命令
    IAP_ADDRL = addr;         //设置 ISP/IAP/EEPROM 低位地址
    IAP_ADDRH = addr >> 8;    //设置 ISP/IAP/EEPROM 高位地址
    IAP_TRIG  = 0x5a;         //发送触发命令 1 (0x5a)
    IAP_TRIG  = 0xa5;         //发送触发命令 2 (0xa5)
    _nop_();                  //MCU 延迟等待 ISP/IAP/EEPROM 作业完成
    _nop_();                  //兼容15F104E一个bug,NOP3次
    _nop_();                  //
    dat = IAP_DATA;           //读取 ISP/IAP/EEPROM 数据
    IapIdle();                //关闭 ISP/IAP/EEPROM 过程
    return dat;               //返回 Flash 数据
}
/**********************************************************
** 函数名称: void IapWriteByte(unsigned int addr, unsigned char dat);
** 功能描述: 写EEPROM扇区
** 输   入: unsigned int addr  写地址
             unsigned char dat  写数据
**********************************************************/
void IapWriteByte(unsigned int addr, unsigned char dat)
{
    IAP_CONTR = ENABLE_IAP;    //打开 IAP 过程, 并设置等待时间
    IAP_CMD   = CMD_WRITE;     //设置 ISP/IAP/EEPROM 为写命令
    IAP_ADDRL = addr;          //设置 ISP/IAP/EEPROM 低位地址
    IAP_ADDRH = addr >> 8;     //设置 ISP/IAP/EEPROM 高位地址
    IAP_DATA  = dat;           //写 ISP/IAP/EEPROM 数据
    IAP_TRIG  = 0x5a;          //发送触发命令 1 (0x5a)
    IAP_TRIG  = 0xa5;          //发送触发命令 2 (0xa5)
    _nop_();                   //MCU 延迟等待 ISP/IAP/EEPROM 作业完成
    _nop_();                   //兼容15F104E一个bug,NOP3次
    _nop_();                   //
    IapIdle();                 //关闭 ISP/IAP/EEPROM 过程
}
/**********************************************************
** 函数名称: void IapEraseSector(unsigned int addr);
** 功能描述: 擦除EEPROM扇区
** 输   入: unsigned int addr 擦除地址
**********************************************************/
void IapEraseSector(unsigned int addr)
{
    IAP_CONTR = ENABLE_IAP;   //打开 IAP 过程, 并设置等待时间
    IAP_CMD   = CMD_ERASE;    //设置 ISP/IAP/EEPROM 为擦除命令
    IAP_ADDRL = addr;         //设置 ISP/IAP/EEPROM 低位地址
    IAP_ADDRH = addr >> 8;    //设置 ISP/IAP/EEPROM 高位地址
    IAP_TRIG  = 0x5a;         //发送触发命令 1 (0x5a)
    IAP_TRIG  = 0xa5;         //发送触发命令 2 (0xa5)
    _nop_();                  //MCU 延迟等待 ISP/IAP/EEPROM 作业完成
    _nop_();                  //兼容15F104E一个bug,NOP3次
    _nop_();                  //
    IapIdle();                //关闭 ISP/IAP/EEPROM 过程
}

 

https://blog.csdn.net/givenkiss/article/details/45457975?locationNum=8

最后

以上就是昏睡超短裙为你收集整理的STC系列单片机 EEPROM/IAP 功能测试程序演示的全部内容,希望文章能够帮你解决STC系列单片机 EEPROM/IAP 功能测试程序演示所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部