找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 660|回复: 9
打印 上一主题 下一主题
收起左侧

STC8H单片机里面EEPROM检查是否第一次上电问题

[复制链接]
跳转到指定楼层
楼主
ID:298743 发表于 2024-7-4 11:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我这里的        if(dat != First_ON)                //检测是否第一次上电     我这个程序无论多少次上电都会触发条件,求各位大佬指点一下为啥




#define First_ON 0x88



void main()
{
        unsigned char dat;
        Uart1_Init();
        dat = IapRead(0x0200);
        sendByte(dat);

        sendByte(IapRead(0x0000));

        if(dat != First_ON)                //检测是否第一次上电
        {
                    IapProgram(0x0200, 0x88);
                        sendByte(IapRead(0x0200));
                    IapProgram(0x0000, 0x0A);
                        dat = 1;
        }

        sendByte(dat);

        dat = IapRead(0x0000);
        sendByte(dat);

        IapErase(0x0000);
        dat = IapRead(0x0000);
        sendByte(dat);


    IapProgram(0x0000, 0x05);
        dat = IapRead(0x0000);
        sendByte(dat);


        while(1);        
}

void Uart1_Init(void)        //4800bps@11.0592MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        AUXR &= 0xBF;                //定时器时钟12T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x20;                //设置定时器模式
        TL1 = 0xFA;                        //设置定时初始值
        TH1 = 0xFA;                        //设置定时重载值
        ET1 = 0;                        //禁止定时器中断
        TR1 = 1;                        //定时器1开始计时
}

void IapIdle()        
{
    IAP_CONTR = 0;                              //关闭IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除触发寄存器
    IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}

char IapRead(int addr) //扇区读取函数 读一个字节
{
    char dat;

    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 11;                               //设置等待参数12MHz
    IAP_CMD = 1;                                //设置IAP读命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //读IAP数据
    IapIdle();                                  //关闭IAP功能

    return dat;
}

void IapProgram(int addr, char dat)                   //写一个字节
{
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 11;                               //设置等待参数12MHz
    IAP_CMD = 2;                                //设置IAP写命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_DATA = dat;                             //写IAP数据
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();
    IapIdle();                                  //关闭IAP功能
}

void IapErase(int addr)        //扇区擦除函数
{
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 11;                               //设置等待参数12MHz
    IAP_CMD = 3;                                //设置IAP擦除命令
    IAP_ADDRL = addr;                           //设置IAP低地址
    IAP_ADDRH = addr >> 8;                      //设置IAP高地址
    IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
    _nop_();                                    //
    IapIdle();                                  //关闭IAP功能
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:298743 发表于 2024-7-4 11:46 | 只看该作者
我用串口输出检测到第二次上电时,dat已经是等于0x88了,但是还是满总条件进入IF里面了
回复

使用道具 举报

板凳
ID:276663 发表于 2024-7-4 15:36 | 只看该作者
直接改if(dat != 0x88)试试
没看出来问题。
回复

使用道具 举报

地板
ID:1012735 发表于 2024-7-5 05:25 | 只看该作者
        if(dat != First_ON)                //检测是否第一次上电
        {
                      IapErase(0x0200);                             //
                     IapProgram(0x0200, 0x88);
                     sendByte(IapRead(0x0200));

                     IapErase(0x0000);                            //
                     IapProgram(0x0000, 0x0A);
                         dat = 1;
         }
回复

使用道具 举报

5#
ID:298743 发表于 2024-7-5 08:34 | 只看该作者
IdeaMing 发表于 2024-7-4 15:36
直接改if(dat != 0x88)试试
没看出来问题。

这样也不行,这样也会每次触发
回复

使用道具 举报

6#
ID:277550 发表于 2024-7-5 10:07 | 只看该作者
应该是符号(char 和 unsigned char)问题,,,,没芯片环境测试。

用别的单片机试了一下,和8#说的原因一致。


回复

使用道具 举报

7#
ID:744809 发表于 2024-7-5 10:45 | 只看该作者
asdadqw2 发表于 2024-7-5 08:34
这样也不行,这样也会每次触发

你要改成if(dat == First_ON)吧?!=感觉不对啊
回复

使用道具 举报

8#
ID:744809 发表于 2024-7-5 10:46 | 只看该作者
IapProgram(0x0000, 0x0A);你看看这个是不是按页擦除的,可能是你写0x0000地址的时候,把0x0200的数据也一起擦除掉了
回复

使用道具 举报

9#
ID:226055 发表于 2024-7-5 13:55 | 只看该作者
单片机型号很关键,STC8H说的太笼统了。有些出厂是没有片内EEPROM的,尽可能选择出厂就带EEPROM的来测试。
回复

使用道具 举报

10#
ID:402383 发表于 2024-7-10 16:54 | 只看该作者
烧录勾选擦除后,初次上电去读取数据,数据值默认是0XFF,我是参考STC8H EEPROM的例程《EEPROM基本操作》得出的结论。
这样改判断语句:如果dat==0XFF 就被认为初次上电,然后赋dat某一个值进行“复位”。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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