打印

帮忙看看单片机EEPROM写的对吗?

[复制链接]
1402|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xu0801hua|  楼主 | 2013-11-15 10:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include"reg51.h"
  #include"intrins.h"
  #define uchar unsigned char
  #define uint unsigned int
  unsigned int addr;
  /*Declare SFR associated with the ISP */
  sfr      IAP_DATA   =   0xE2;           //Flash data register        闪存数据寄存器
  sfr      IAP_ADDRH  =   0xE3;           //Flash address HIGH 闪存地址高
  sfr      IAP_ADDRL  =   0xE4;           //Flash address LOW  闪存地址低
  sfr      IAP_CMD    =   0xE5;           //Flash command register 闪存命令寄存器
  sfr      IAP_TRIG   =   0xE6;           //Flash command trigger  闪存命令触发
  sfr      IAP_CONTR  =   0xE7;           //Flash control register 闪存控制寄存器
  /*Define ISP/IAP/EEPROM command*/
  #define  CMD_IDLE        0x00               //Stand-By
  #define  CMD_READ        0x00               //unsigned char-Read
  #define  CMD_PROGRAM     0x02              //unsigned char-Program
  #define  CMD_ERASE       0x03               //Sector-Erase
  /*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
  //#define ENABLE_IAP      0x80             //if SYSCLK<30MHz
  //#define ENABLE_IAP      0x81             //if SYSCLK<24MHz
  //#define ENABLE_IAP      0x82             //if SYSCLK<200MHz
  #define   ENABLE_IAP      0x83             //if SYSCLK<12MHz
  //#define ENABLE_IAP      0x80             //if SYSCLK<6MHz
  /**EEPROM延时函数********/
  void Delay_EEprom(uchar n)
  {
   uint x;
     while(n--)
{
  x=0;
   while(++x);
}
  }
  /****关闭ISP,IAP功能*******/
  void ISP_IAP_Disable()
  {
   IAP_CONTR=0x00;//Close IAP function关闭控制寄存器
   IAP_CMD  =0x00;//clear command to standby清除命令备用
   IAP_TRIG =0x00;//Clear trigger register
   IAP_ADDRH=0x80;//Data ptr point to non-EEPROM area
   IAP_ADDRL=0x00;//Clear IAP address to prevent misuse
  }
  /**向EEPROM16位地址读出8位数据**/
   unsigned char IapReadINT8U(unsigned int addr)
  {
    unsigned char dat;
   IAP_CONTR=ENABLE_IAP;    // 打开IAP功能,设置Flash操作等待时间
   IAP_CMD  =CMD_READ;     // 对用户的应用程序Flash区及数据Flash区字节读
   IAP_ADDRH=addr>>8;     //设置目标单元地址的高8位地址
   IAP_ADDRL=addr;       //设置目标单元地址的低8位地址
   IAP_TRIG =0x46;          //触发ISP_IAP命令字节1(0x46)
   IAP_TRIG =0xb9;          //触发ISP_IAP命令字节2(0xb9)
    _nop_();         //延时一个机器周期                
   dat=IAP_DATA;      //读出数据准备
   ISP_IAP_Disable();        //关闭IAP,ISP功能
   return dat;          //返回给函数
  }
  /**向EEPROM16位地址写入8位数据**/
  void IapProgramINT8U(unsigned int addr,unsigned char dat)
  {
  
   IAP_CONTR=ENABLE_IAP;//Open IAP function,and set wait time 打开IAP功能,设置Flash操作等待时间
   IAP_CMD=CMD_PROGRAM;//对用户的应用程序Flash区及数据Flash区编程
   IAP_ADDRH=addr>>8;//设置目标单元地址的高8位地址
   IAP_ADDRL=addr;//设置目标单元地址的低8位地址
   IAP_DATA=dat; //写入数据准备
   IAP_TRIG=0x46;//Send trigger command1 (0x46)
   IAP_TRIG=0xb9;//Send trigger command1 (0xb9)
   _nop_();        //延时一个机器周期
   ISP_IAP_Disable();  //关闭IAP,ISP功能
  }
  /**扇区擦除**/
  void IapEraseSector(unsigned int addr)
  {
   IAP_CONTR = ENABLE_IAP;//打开IAP功能,设置Flash操作等待时间
   IAP_CMD   = CMD_ERASE;//对用户的应用程序Flash区及数据Flash区擦出
   IAP_ADDRH=addr>>8;//设置目标单元地址的高8位地址
   IAP_ADDRL=addr;//设置目标单元地址的低8位地址
   IAP_TRIG=0x46;//Send trigger command1 (0x46)
   IAP_TRIG=0xb9;//Send trigger command1 (0xb9)
   _nop_();
   ISP_IAP_Disable();
  }
  /**主函数**/
  void main()
  {
   
  }       
帮忙看看单片机EEPROM写的对吗?
在应用时不知道怎么使用,我要用AD采集的值存储在EEPROM中,再用串口将EEPROM值读取出来????

相关帖子

沙发
craaazyfor| | 2013-11-15 11:10 | 只看该作者
初步看没问题,都是按IAP来的,至于应用,你可以那样去验证

使用特权

评论回复
板凳
ningling_21| | 2013-11-15 11:21 | 只看该作者
自己写一些,再读出来就知道行不行了...

使用特权

评论回复
地板
xu0801hua|  楼主 | 2013-11-15 11:26 | 只看该作者
craaazyfor 发表于 2013-11-15 11:10
初步看没问题,都是按IAP来的,至于应用,你可以那样去验证

  #include"reg51.h"
  #include"intrins.h"
  #define uchar unsigned char
  #define uint unsigned int
     /*Declare SFR associated with the ISP */
  sfr      IAP_DATA   =   0xE2;           //Flash data register        闪存数据寄存器
  sfr      IAP_ADDRH  =   0xE3;           //Flash address HIGH 闪存地址高
  sfr      IAP_ADDRL  =   0xE4;           //Flash address LOW  闪存地址低
  sfr      IAP_CMD    =   0xE5;           //Flash command register 闪存命令寄存器
  sfr      IAP_TRIG   =   0xE6;           //Flash command trigger  闪存命令触发
  sfr      IAP_CONTR  =   0xE7;           //Flash control register 闪存控制寄存器
  /*Define ISP/IAP/EEPROM command*/
  #define  CMD_IDLE        0x00               //Stand-By
  #define  CMD_READ        0x00               //unsigned char-Read
  #define  CMD_PROGRAM     0x02              //unsigned char-Program
  #define  CMD_ERASE       0x03               //Sector-Erase
  /*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
  //#define ENABLE_IAP      0x80             //if SYSCLK<30MHz
  //#define ENABLE_IAP      0x81             //if SYSCLK<24MHz
  //#define ENABLE_IAP      0x82             //if SYSCLK<200MHz
  #define   ENABLE_IAP      0x83             //if SYSCLK<12MHz
  //#define ENABLE_IAP      0x80             //if SYSCLK<6MHz
  #define   IAP_ADDRESS     0x0000
  /**AD特殊寄存器***/
  sfr                ADC_DATA    =0xc6;
  sfr                  ADC_LOW2          =0xbe;
  sfr                  ADC_CONTR   =0xc5;
  sfr         P1M0        =0x91;
  sfr         P1M1        =0x92;
  /***按键定义*****/
  sbit  KEY_P3_4          =P3^4;   //左边拨动开关(拨向左:P3^4==0,表示需要标定电压;否则不需要标定)
  sbit  KEY_P0_0          =P0^0;   //右边红色按钮(按下时:P0^0==0,表示开始标定电压;否则不标定)
  sbit  led=P1^1;
  void ISP_IAP_Disable();
  /***程序用到的定义****/
  uint i,j,AD_finished=0,pj=0;mj=0,x=1,su[1],y;
  uchar num,result,di,flag;
  /**********延时函数*****************/
  void delayms(uint xms)
  {
   for(i=xms;i>0;i--)
     for(j=110;j>0;j--);
  }
/*********串口/定时器初始化***************/
  void init()
  {
    TMOD=0x21;//设定T1定时器工作方式2 0010 0001
    TH1=0xfd;//T1定时器高8位赋值
    TL1=0xfd;//T1定时器低8位赋值
        TH0=0x4c;//T0定时器高8位赋值
        TL0=0x00;//T0定时器低8位赋值
    SCON=0x40;//设定串口工作方式1
    EA=1;//开中断
        TR0=1;//开启定时器T0
    TR1=1;//开启定时器T1
        ET0=1;//开定时器0中断
    ES=1;//允许串口中断
    REN=1;//允许串口接收
  }
   void fas(uint a)//1.32===int 1.0//==132
  {
   ES=0;
   SBUF=a;//接收数据
   while(!TI);
   TI=0;
   ES=1;
  }
  /*********AD函数**************/
  void AD_init()
  {
   P1M0=0x80;P1M1=0x00;
   ADC_DATA=0;
   ADC_CONTR=0xe0;//1110 0000开启启动电源和选择转换速度
   delayms(60);
  }
  /*****AD转换函数*********/
  uint getAD()
  {
   uchar AD_finished=0;
   ADC_CONTR|=0x07; //1110 0000 | 1111 1111 或上AD口的值
   ADC_CONTR|=0x08;//0000 1000启动AD电源
   while(AD_finished==0)//等待A/D转换结束
   (AD_finished=(ADC_CONTR&0x10));//0000 1000 & 0001 0000 =0000 0000查询ADC_FLAG位是否置1
        ADC_CONTR=0Xf7;//1111 0111//关闭启动位
   return ADC_DATA;        //值返回给高8位
  }       
      /*********定时中断***********/
  void T0_time() interrupt 1
  {
   TH0=0x4c;
   TL0=0x00;
   num++;
    if(num>=20)
   {
    num=0;
    pj=1;
   }
  }
  /****关闭ISP,IAP功能*******/
  void ISP_IAP_Disable()
  {
   IAP_CONTR=0x00;//Close IAP function关闭控制寄存器
   IAP_CMD  =0x00;//clear command to standby清除命令备用
   IAP_TRIG =0x00;//Clear trigger register
   IAP_ADDRH=0x80;//Data ptr point to non-EEPROM area
   IAP_ADDRL=0x00;//Clear IAP address to prevent misuse
  }
  /**向EEPROM16位地址读出8位数据**/
   unsigned char IapReadINT8U(unsigned int addr)
  {
    unsigned char dat;
   IAP_CONTR=ENABLE_IAP;    // 打开IAP功能,设置Flash操作等待时间
   IAP_CMD  =CMD_READ;     // 对用户的应用程序Flash区及数据Flash区字节读
   IAP_ADDRH=addr>>8;     //设置目标单元地址的高8位地址
   IAP_ADDRL=addr;       //设置目标单元地址的低8位地址
   IAP_TRIG =0x46;                 //触发ISP_IAP命令字节1(0x46)
   IAP_TRIG =0xb9;                 //触发ISP_IAP命令字节2(0xb9)
    _nop_();         //延时一个机器周期                
   dat=IAP_DATA;      //读出数据准备
   ISP_IAP_Disable();        //关闭IAP,ISP功能
   return dat;          //返回给函数
  }
  /**向EEPROM16位地址写入8位数据**/
  void IapProgramINT8U(unsigned int addr,unsigned char dat)
  {
  
   IAP_CONTR=ENABLE_IAP;//Open IAP function,and set wait time 打开IAP功能,设置Flash操作等待时间
   IAP_CMD=CMD_PROGRAM;//对用户的应用程序Flash区及数据Flash区编程
   IAP_ADDRH=addr>>8;//设置目标单元地址的高8位地址
   IAP_ADDRL=addr;//设置目标单元地址的低8位地址
   IAP_DATA=dat; //写入数据准备
   IAP_TRIG=0x46;//Send trigger command1 (0x46)
   IAP_TRIG=0xb9;//Send trigger command1 (0xb9)
   _nop_();        //延时一个机器周期
   ISP_IAP_Disable();  //关闭IAP,ISP功能
  }
  /**扇区擦除**/
  void IapEraseSector(unsigned int addr)
  {
   IAP_CONTR = ENABLE_IAP;//打开IAP功能,设置Flash操作等待时间
   IAP_CMD   = CMD_ERASE;//对用户的应用程序Flash区及数据Flash区擦出
   IAP_ADDRH=addr>>8;//设置目标单元地址的高8位地址
   IAP_ADDRL=addr;//设置目标单元地址的低8位地址
   IAP_TRIG=0x46;//Send trigger command1 (0x46)
   IAP_TRIG=0xb9;//Send trigger command1 (0xb9)
   _nop_();
   ISP_IAP_Disable();
  }
   /*****定时1s去采集AD信号**********/
  void AD_cj()
  {
     if(pj>=1)
        {
         pj=0;
         mj++;
        }
        if(mj>=x)
        {
         mj=0;
         fas(su[0]);
        }
  }
   /****存电压值*********/
  void dy()
  {
   if(KEY_P0_0==0)
    {
     delayms(20);
          if(KEY_P0_0==0)
           {
            AD_init();
                IapEraseSector(IAP_ADDRESS);//擦出扇区
                IapProgramINT8U(IAP_ADDRESS,getAD());//从0x0000地址写入AD采样值
                su[0]=IapReadINT8U(0x0000);//读出E2PROM中值赋给su【0】
                //su[0]=getAD();
                fas(su[0]);
                while(!KEY_P0_0);  
                while(1);
           }
        }
  }
/**主函数***/
    void main()
  {
   init();
   while(1)
   {  
   //void IapProgramINT8U(unsigned int addr,unsigned char dat);
    if(!KEY_P3_4)
        {
         dy();led=0;   }
        else   
            AD_cj();led=1;
                       
   }
        }
我采用stc12c5608AD的单片机,在调试功能时我在按下  KEY_P0_0   时怎么串口没有发出AD采用值,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

81

帖子

1

粉丝