#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
|