打印
[STC单片机]

STC12c5a60s2的EEPROM存储(已测试,其他功能可自行添加)

[复制链接]
8447|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiaoliping1945|  楼主 | 2013-8-24 14:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<stc12c5a60s2.h>
#include"EEPROM.h"       
#include"lcd1602_595.h"
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
WORD i;
uint dat;
uchar code table[]="0123456789";
uchar  number[]="000";
void main()
  {
        led0=1;                 //处于关闭状态
                led1=1;
                led2=1;
                led3=1;
           init_lcd();        //记得初始化,不然LCD显示乱码
           write_com(0x01);
              delayus(50);
           lcd_display(0x00,0,number) ; //第X行第Y例开始显示
           Delay_EEPROM(2);
           IAPErase(IAP_ADDRESS); //擦除扇区
                for(i=0;i<512;i++)          //检测是否全部擦除,擦除后的数应该为0xff,
                {
                  if(IAPReadByte(IAP_ADDRESS+i)!=0xff)
                     goto Error;          //如果错误        ,break
                }
                led0=0;              //点亮第一个灯,表示擦除成功
                Delay_EEPROM(10);         
                 for(i=0;i<512;i++)
                  {
                        IAPWriteByte(IAP_ADDRESS+i,(BYTE)i);//写入数据0--511
                        delayus(5);
                  }
                led1=0;//表示写入成功
                for(i=0;i<512;i++)
                    {
                            dat=IAPReadByte(IAP_ADDRESS+i);
                                if(dat!=(BYTE)i) //写入的是一个字节的数据,大于255后,
                                                 //只写入了低字节数据,这里只是为了起检测作用,做个调试,
                                                                //所以没有管高字节的数据,如果要写入字,记得先写低字节,后写高字节,也可以反过来,读出来时做相应处理
                                  goto Error;        //如果读出数据与写入数据有错误,break
                                number[0]=table[ dat/100];                //写入的是0-511,由于只显示了低字节,所以显示时,会有两次0到255,
                                number[1]=table[ dat%100/10];
                                number[2]=table[ dat%10];
                                lcd_display(0x00,0,number) ; //第X行第Y例开始显示                       
                   }
          led2=0;//表示写入数据没有错误
            while(1);


          Error:
                    led3=0;          //有错误产生就灯3亮
                    while(1);       
  }
/******************EEPROM头文件****************************/
#ifndef __EEPROM_H_
#define  __EEPROM_H_
#include<intrins.h>
#define BYTE unsigned char
#define  WORD unsigned int
/*-------定义ISP/IAP/EEPROM 命令*/
#define  CMD_IDLE      0   //stand_BY
#define  CMD_READ      1   //读字节
#define  CMD_WRITE     2           //字节写
#define  CMD_ERASE     3        //擦除

/*----定义ISP/IAP/EEPROM 的IAP_CONTPTR寄存器操作吗--*/
//#define ENABLE_IAP 0X80  //晶振<30M
//#define ENABLE_IAP 0X81  //晶振<24M
#define ENABLE_IAP 0X82  //晶振<20M
//#define ENABLE_IAP 0X83  //晶振<12M
//#define ENABLE_IAP 0X84  //晶振<6M
//#define ENABLE_IAP 0X85  //晶振<3M
//#define ENABLE_IAP 0X86  //晶振<2M
//#define ENABLE_IAP 0X87  //晶振<1M

/*--------定义起始地址—————————————*/
#define IAP_ADDRESS                 0x0000

/****************函数声明***********/
void Delay_EEPROM(BYTE n);          //延时函数
void IAPIDLE();      
BYTE IAPReadByte(WORD ADDR);//读字节
void IAPWriteByte(WORD addr,BYTE dat);//写入字节
void IAPErase(WORD addr);         //扇区擦除

void Delay_EEPROM(BYTE n)
{
      WORD x;
          while(n--)
          {
                     x=0;
                   while(++x);
          }
}
void IAPIDLE()
{
          IAP_CONTR=0;//  close IAP fuction
          IAP_CMD=0;  //  CLEAR COMMAND to standby
          IAP_TRIG=0; //Clear tigger regester
          IAP_ADDRH=0x80;//data ptr to nom_eeprom area
          IAP_ADDRL=0; //clear iap address to prevent misuse
}
BYTE IAPReadByte(WORD addr)          //读字节
{
          BYTE dat;
          IAP_CONTR=ENABLE_IAP;//open iap fuction
          IAP_CMD=CMD_READ;
          IAP_ADDRL=addr;
          IAP_ADDRH=addr>>8;
          IAP_TRIG=0X5A;                //每次必须要有这两句
          IAP_TRIG=0XA5;                //不然操作不成功
          _nop_();
          dat=IAP_DATA;
          IAPIDLE();
          return dat;
}
void IAPWriteByte(WORD addr,BYTE dat)
{
         IAP_CONTR=ENABLE_IAP;//open iap fuction
         IAP_CMD=CMD_WRITE;
          IAP_ADDRL=addr;
          IAP_ADDRH=addr>>8;
          IAP_DATA=dat;
          IAP_TRIG=0X5A;                //每次必须要有这两句
          IAP_TRIG=0XA5;                //不然操作不成功
           _nop_();
          IAPIDLE();
}
void IAPErase(WORD addr)         //扇区擦除
{
          IAP_CONTR=ENABLE_IAP;//open iap fuction
          IAP_CMD=CMD_ERASE;
          IAP_ADDRH=addr;
          IAP_ADDRH=addr>>8;
          IAP_TRIG=0X5A;                //每次必须要有
          IAP_TRIG=0XA5;                //不然操作不成功

          IAPIDLE();                    //闲置等待状态,不知道是不是这么翻译的,大概是这意思吧,英语水平不行。
}
#endif
/**********************LCD1602*************************************/
#ifndef __lcd1602_595_H__
#define __lcd1602_595_H__
#define uint unsigned int
#define uchar unsigned char
sbit rs=P2^2;
//rw=0;   只往lcd写入,不读出,故rw=0;
sbit en=P2^1;

sbit sclk=P2^2;           //移位时钟
sbit ds=P2^0;           //数据线
sbit rclk=P2^1        ;           //锁存输出时钟
/*-----------函数声明------------*/
void delay(uint z);
void delayus(uint i);
void write_595(uchar date);
void write_com(uchar com) ;//写指令
void write_data(uchar date );        //写数据
void init_lcd();        //注意,里面有清屏命令
void lcd_display(uchar x,uchar y,uchar *s) ; //第X行第Y例开始显示
void delay(uint z)
{        
    uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void delayus(uint i)
{
   while(i--);
}
void write_595(uchar date)
{
        uchar i;
        for(i=0;i<8;i++)
         {
          sclk=0;
          ds=date&0x80;
          delay(2);
          sclk=1;
          date<<=1;                 //sclk给一个上升沿脉冲即可读走一位
         }
}

void write_com(uchar com) //写指令
{
   write_595(com);
   rs=0;
   delay(1);
   //rw=0;
   rclk=1;
   delay(1);
   rclk=0;                  //令595输出,并用en输出一个高脉冲
}
void write_data(uchar date )        //写数据
{
   write_595(date);                //写入数据
   rs=1;
   delay(5);
   rclk=1;
   delayus(10);
   rclk=0;                                //令595输出,并用en输出一个高脉冲
}
void init_lcd()
{   
    write_com(0x38);
        delayus(50);
    write_com(0x0c);
        delayus(50);
    write_com(0x06);
        delayus(50);
   // write_com(0x01);
   //        delayus(50);
}
void lcd_display(uchar x,uchar y,uchar *s)  //第X行第Y例开始显示
{
         init_lcd();
         write_com(0x80+x+y);
         while(*s!='\0')
            {
                        write_data(*s++);
                        delay(5);               
                }
}
#endif

相关帖子

沙发
aimie| | 2013-8-24 16:57 | 只看该作者
在需要保存数据的场合 很好用

使用特权

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

本版积分规则

11

主题

74

帖子

3

粉丝