找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3909|回复: 11
收起左侧

stc单片机程序 EEPROM无法写入0和1

[复制链接]
ID:956872 发表于 2021-8-31 19:14 | 显示全部楼层 |阅读模式
后面三种状态都能写入,掉电后正常读取,为啥第一种状态死活写不进去呢,返回的一直都是FF。我把数据全部加1后测试,上电后默认第一种状态点亮,也能掉电存储了,其它几种状态都正常。当num从0或1开始就无法正常写入,第一种状态上电默认关闭,手动点亮后掉电无法存储。只有num从2开始才正常。

单片机源程序如下:
#include <STC15F2K60S2.H>  
#include <intrins.h>  
#include "eeprom.h"

sbit K1=P3^2;
sbit K2=P3^3;
sbit l1=P1^4;
sbit l2=P1^5;
sbit l3=P1^6;

static unsigned char num=0;        

void Delay30ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 2;
        j = 67;
        k = 183;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


void init()//中断初始化
{
        IT0=1;//外部中断0 跳变触发
        EX0=1;//外部中断0 p32
        EA=1;
}

void init0() interrupt 0//中断程序 K1
{        
        if(K1==0)
        {
                Delay30ms();
                 if(K1==0)
     num=num+1;
     if(num>4){num=1;}               
          while(!K1);}
}
void lsd0()
{
        while(1)
        {
                if(num!=1){return;}
                 P1=0xfe;
        }
}
void lsd1()
{
        while(1)
        {  l3=0;
                if(num!=2){return;}
                           P1=0xfd;}
        }

void lsd2()
{
        while(1)
        { l2=0;
                if(num!=3){return;}
                    P1=0xfb;}
        }
void lsd3()
{
        while(1)
        {
                P1=0xf7;
                     if(num!=4)
         {return;}
        }

}

void main()
{ char v;
        init();
        v=IapReadByte(IAP_ADDRESS);
        num=v+1;
        while(1)
        {
                 
               
                        switch(num)
                        {
                         case 1:lsd0();
                                       P1=0xfe;
                                      if(IapReadByte(IAP_ADDRESS)!=1)
                                                        {IapEraseSector(IAP_ADDRESS);             // 擦除扇区
               IapProgramByte(IAP_ADDRESS,1);}               
                                      break;
                         case 2:lsd1();
               P1=0xfd;
                                                         if(IapReadByte(IAP_ADDRESS)!=2)
               {IapEraseSector(IAP_ADDRESS);             // 擦除扇区
               IapProgramByte(IAP_ADDRESS,2);}                                       
                                      break;
                         case 3:lsd2();
                                       P1=0xfb;
                                                         if(IapReadByte(IAP_ADDRESS)!=3)
                                       {IapEraseSector(IAP_ADDRESS);             // 擦除扇区
               IapProgramByte(IAP_ADDRESS,3);        }
                                       break;//num++;
                         case 4:lsd3();
                                       P1=0xf7;
                                                         if(IapReadByte(IAP_ADDRESS)!=4)
                                       {IapEraseSector(IAP_ADDRESS);             // 擦除扇区
               IapProgramByte(IAP_ADDRESS,4);}
                                        break;
                                default:break;
                        
                        }
                        
        }         
}

回复

使用道具 举报

ID:57657 发表于 2021-8-31 23:13 | 显示全部楼层
请将 eeprom.h 里的内容发上来
回复

使用道具 举报

ID:57657 发表于 2021-8-31 23:22 | 显示全部楼层
写EEPROM 1可以写成0,0不可写成1,只有擦除才可以恢复为1(0xFF),一次至少擦1扇区(512字节)。
回复

使用道具 举报

ID:956872 发表于 2021-9-1 06:44 | 显示全部楼层
npn 发表于 2021-8-31 23:13
请将 eeprom.h 里的内容发上来

#ifndef __EEPROM_H_
#define __EEPROM_H_

typedef unsigned char BYTE;
typedef unsigned int WORD;
#define     FOSC    11059200UL
#define     BAUD    115200

#define CMD_IDLE    0               //空闲模式
#define CMD_READ    1               //IAP字节读命令
#define CMD_PROGRAM 2               //IAP字节编程命令
#define CMD_ERASE   3               //IAP扇区擦除命令

//#define ENABLE_IAP 0x80           //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81           //if SYSCLK<24MHz
//#define ENABLE_IAP  0x82            //if SYSCLK<20MHz
#define ENABLE_IAP 0x83           //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84           //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85           //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86           //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87           //if SYSCLK<1MHz

//测试地址
#define IAP_ADDRESS 0x0400


void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);

#endif
回复

使用道具 举报

ID:956872 发表于 2021-9-1 06:47 | 显示全部楼层
npn 发表于 2021-8-31 23:22
写EEPROM 1可以写成0,0不可写成1,只有擦除才可以恢复为1(0xFF),一次至少擦1扇区(512字节)。

那就是说只有擦除后恢复默认1,不能自己写1是吗,那就只能从2开始写了?
回复

使用道具 举报

ID:213173 发表于 2021-9-1 06:49 | 显示全部楼层
  1. #include <STC15F2K60S2.H>  
  2. #include <intrins.h>  
  3. #include "eeprom.h"

  4. sbit K1=P3^2;
  5. sbit K2=P3^3;
  6. sbit l1=P1^4;
  7. sbit l2=P1^5;
  8. sbit l3=P1^6;

  9. static unsigned char num=0;        

  10. void Delay30ms()                //@11.0592MHz
  11. {
  12.         unsigned char i, j, k;
  13.         _nop_();
  14.         _nop_();
  15.         i = 2;
  16.         j = 67;
  17.         k = 183;
  18.         do
  19.         {
  20.                 do
  21.                 {
  22.                         while (--k);
  23.                 } while (--j);
  24.         } while (--i);
  25. }


  26. void init()//中断初始化
  27. {
  28.         IT0=1;//外部中断0 跳变触发
  29.         EX0=1;//外部中断0 p32
  30.         EA=1;
  31. }

  32. void init0() interrupt 0//中断程序 K1
  33. {        
  34.         if(K1==0)
  35.         {
  36.                 Delay30ms();
  37.                 if(K1==0)
  38.                         num=num+1;
  39.                 if(num>4){num=1;}
  40.                 while(!K1);
  41.         }
  42. }

  43. void main()
  44. {
  45.         char v;
  46.         init();
  47.         num=IapReadByte(IAP_ADDRESS);//判断数据在设定范围
  48.         if(num>4||num<0)
  49.                 num=0;
  50.         v=num;        //数据保存在临时变量v
  51.         P1=~num;//LED低电平显示
  52.         while(1)
  53.         {
  54.                 if(num!=v)//判断num有变化
  55.                 {
  56.                         IapEraseSector(IAP_ADDRESS);    // 擦除扇区
  57.                         IapProgramByte(IAP_ADDRESS,num);// 写数据
  58.                         v=num;//数据保存在临时变量v
  59.                         P1=~num;//LED低电平显示
  60.                 }
  61.         }         
  62. }

复制代码
回复

使用道具 举报

ID:57657 发表于 2021-9-1 07:46 | 显示全部楼层
PEB188 发表于 2021-9-1 06:47
那就是说只有擦除后恢复默认1,不能自己写1是吗,那就只能从2开始写了?

1是二进制的1,懂?
回复

使用道具 举报

ID:879348 发表于 2021-9-1 08:18 | 显示全部楼层
先搞清楚基本概念
回复

使用道具 举报

ID:130230 发表于 2021-9-1 11:23 | 显示全部楼层
stc的不是eeprom是flash,擦除后才能重新写。你这多半是擦除函数写的有问题。
回复

使用道具 举报

ID:956872 发表于 2021-9-2 17:25 | 显示全部楼层
npn 发表于 2021-9-1 07:46
1是二进制的1,懂?

搞不懂,实际测试反正写0和1都有问题,只有从2开始写才能达到我想要的效果
回复

使用道具 举报

ID:624769 发表于 2021-9-2 19:40 | 显示全部楼层
PEB188 发表于 2021-9-2 17:25
搞不懂,实际测试反正写0和1都有问题,只有从2开始写才能达到我想要的效果

我看你关于这类问题,开了好几个帖子了。
建议:
你先别搞的这么复杂,写个最简单的串口发数据,让Eeprom写,然后,让Eeprom读出来给你串口发回来。STC的下载器里有例程,你先确保能正确读写了,再搞其他的。
回复

使用道具 举报

ID:956872 发表于 2021-9-2 21:16 | 显示全部楼层
188610329 发表于 2021-9-2 19:40
我看你关于这类问题,开了好几个帖子了。
建议:
你先别搞的这么复杂,写个最简单的串口发数据,让Eepr ...

现在不自己去输入,直接写入变量名,变量从1到100的,到是没啥问题了,正常擦写读取了。也有可能之前读取数值的地方改来改去改的有问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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