/*
程序名称: STC89C51/2内部EEPROM测试程序
程序效果: 数码管以动态扫描方式显示从EEPROM读来的字节数据,然后把该数据加1后存到单元,下次上电可以看到该数据加1的结果。
*/
#include <AT89X52.H> //包含头文件
#define shuma P0 //定义P0口为数码管数据口
#define ENABLE_ISP 0x82 //<20MHz
#define DEBUG_DATA 0x5A
//----------------------------flash 存储的起始地址
#define DATA_FLASH_START_ADDRESS 0x2800 //stc12c2052ad ////////////???????????
#define uchar unsigned char
#define uint unsigned int
sbit LED_0=P1^0; //以下定义P1各口为控制口
sbit LED_1=P1^1;
sbit LED_2=P1^2;
sbit LED_3=P1^3;
sfr ISP_DATA = 0xE2; //IAP有关功能寄存器
sfr ISP_ADDRH = 0xE3;
sfr ISP_ADDRL = 0xE4;
sfr ISP_CMD = 0xE5;
sfr ISP_TRIG = 0xE6;
sfr ISP_CONTR = 0xE7;
unsigned char tx_buf[3] = {0,0,0};
extern void Delay(uint number); //晶振=11059200,机器周期=1.085069444us,"加"的机器周期=1
extern void send_char_com(uchar ch);
extern void send_string_com(uchar *str,uchar strlen);
unsigned char Byte_Read(uint address);
void Sector_Erase(uint address);
void Byte_Program(uint address,uchar ch);
void delay(unsigned int x); //声明延时函数
void display1(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4);
//声名数码管显示函数1
/*定义段码=====0-9=====A-G=====*/
unsigned char a[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//共阳极数码管的段码0 1 2 3 4 5 6 7 8 9 A B C D E F
void main()
{
unsigned char res;
unsigned char d2,d3,d4;
res=0; //结果变量清零
res=Byte_Read(0x10); //读0X10单元内的数据
res++; //数据加1
Sector_Erase(0x10); //擦除单元
Byte_Program(0x10,res); //把加1的数据存入该地址
while(1)
{
//在主循环中动态扫描显示已经存入的数据,效果为每上一次电,显示值加1
d2=(res/100)%10;
d3=(res/10)%10;
d4=(res%10);
display1(0,d2,d3,d4);
}
}
void delay(unsigned int x)
{
unsigned int i;
for(i=0;i<x;i++);
}
void display1(unsigned char d1,unsigned char d2,unsigned char d3,unsigned char d4)
{
shuma=a[d1]; //选中第一位,发送第一位段码
LED_0=0;
delay(100);
LED_0=1;
shuma=a[d2]; //选中第二位,发送第二位段码
LED_1=0;
delay(100);
LED_1=1;
shuma=a[d3]; //选中第三位,发送第三位段码
LED_2=0;
delay(100);
LED_2=1;
shuma=a[d4]; //选中第四位,发送第四位段码
LED_3=0;
delay(100);
LED_3=1;
}
//------------------------------------------------------
//功能: 读一字节;调用前需打开IAP功能
//调用方法: uint address=页地址0~512,为了提高处理速度,最好用0~256的范围
//------------------------------------------------------
uchar Byte_Read(uint address)
{
uchar data ch;
ISP_CONTR = ENABLE_ISP; //打开IAP功能,设置Flash操作等待时间
ISP_CMD = 0x01; //选择读AP模式
address = DATA_FLASH_START_ADDRESS+address;
ISP_ADDRH = (uchar)(address>>8); //填页地址
ISP_ADDRL = (uchar)(address); //填页地址
EA = 0;
ISP_TRIG = 0x46; //出发ISP处理器
ISP_TRIG = 0xB9;
ch = ISP_DATA; //保存数据
EA = 1;
//在处理器完成之前,CUP将暂停
//关闭IAP功能,清与ISP有关的特殊功能寄存器
ISP_CONTR = 0;
ISP_CMD = 0;
ISP_TRIG = 0;
return ch;
}
//------------------------------------------------------
//功能: 擦除扇区
//调用方法: uint address=页地址0~512,为了提高处理速度,最好用0~256的范围
//------------------------------------------------------
void Sector_Erase(uint address)
{
ISP_CONTR = ENABLE_ISP; //打开IAP功能,设置Flash操作等待时间
ISP_CMD = 0x03; //选择页擦除模式
address = DATA_FLASH_START_ADDRESS+address;
ISP_ADDRH = (uchar)(address>>8); //填页地址
ISP_ADDRL = (uchar)(address); //填页地址
EA = 0;
ISP_TRIG = 0x46; //出发ISP处理器
ISP_TRIG = 0xB9;
EA = 1;
//关闭IAP功能,清与ISP有关的特殊功能寄存器
ISP_CONTR = 0;
ISP_CMD = 0;
ISP_TRIG = 0;
}
//------------------------------------------------------
//功能: 字节编程,写一个字节数据到相应地址
//调用方法: uint address=页地址0~512,为了提高处理速度,最好用0~256的范围;uchar ch=要写的数据
//------------------------------------------------------
void Byte_Program(uint address,uchar ch)
{
ISP_CONTR = ENABLE_ISP; //打开IAP功能,设置Flash操作等待时间
ISP_CMD = 0x02; //选择字节编程模式
address = DATA_FLASH_START_ADDRESS+address;
ISP_ADDRH = (uchar)(address>>8); //填页地址
ISP_ADDRL = (uchar)(address); //填页地址
ISP_DATA = ch;
EA = 0;
ISP_TRIG = 0x46; //出发ISP处理器
ISP_TRIG = 0xB9;
EA = 1;
//关闭IAP功能,清与ISP有关的特殊功能寄存器
ISP_CONTR = 0;
ISP_CMD = 0;
ISP_TRIG = 0;
}
//------------------------------------------------------
//功能: 字节编程,写字符串
//调用方法: uint address=页地址0~512,为了提高处理速度,
// 最好用0~256的范围;uchar ch=要写的数据
// len=字符串的长度
//------------------------------------------------------
void Morebyte_Program(uint address,uchar *ch,uchar len)
{
uchar k = 0;
Sector_Erase(address);
do
{
Byte_Program(address,*(ch + k));
address++;
k++;
}while(k < len);
}
//------------------------------------------------------
//功能: 读多字节;调用前需打开IAP功能
//调用方法: uint address=页地址0~512,为了提高处理速度,最好用0~256的范围
//------------------------------------------------------
void Moreyte_Read(uint address)
{
uchar k = 0;
do
{
tx_buf[k] = Byte_Read(address);
address++;
k++;
}while(k < 3);
}