?? eeprom.c
字號:
//-------實驗名稱:宏晶單片機EEPROM讀寫存儲功能實驗
//-------單片機型號:STC89C58RD+
//-------版本: V3
#include <reg52.h>
#include <intrins.h>
//-----------------------
//--定義與IAP有關的特殊功能寄存器
sfr ISP_DATA = 0xe2; //ISP數據寄存器地址
sfr ISP_ADDRH= 0xe3; //EEPROM,Flash存儲器高位地址
sfr ISP_ADDRL= 0xe4; //EEPROM,Flash存儲器低位地址
sfr ISP_CMD = 0xe5; //ISP指令寄存器地址
sfr ISP_TRIG = 0xe6; //ISP命令觸發器寄存器地址
sfr ISP_CONTR= 0xe7; //ISP/IAP控制寄存器
//------------------------
//--按鍵定義
sbit key1 = P1^0;
sbit key2 = P1^1;
sbit key3 = P1^2;
sbit Beep = P1^5;
sbit P0_0=P0^0;
sbit P0_1=P0^1;
sbit P0_2=P0^2;
sbit P0_3=P0^3;
sbit P0_4=P0^4;
sbit P0_5=P0^5;
sbit P0_6=P0^6;
sbit P0_7=P0^7;
sbit P2_0=P2^0;
sbit P2_1=P2^1;
sbit P2_2=P2^2;
sbit P2_3=P2^3;
sbit P1_7=P1^7;
#define Scan P3
#define Beep_on Beep=0;
#define Beep_off Beep=1;
//------------------------
//--定義變量
//------------------------
//--Flash 操作等待時間
//#define ENABLE_ISP 0x83 //<5MHz
//#define ENABLE_ISP 0x82 //<10MHz
#define ENABLE_ISP 0x81 //<20MHz 打開ISP操作功能及等待時間
//#define ENABLE_ISP 0x80 //>20MHz
#define DEBUG_DATA 0x01 //往EEPROM寫入的數據
#define uchar unsigned char
unsigned int ADD;
//------------------------
//--IAP操作模式
//------------------------
#define Read 0x01 //讀Flash命令字
#define Write 0x02 //寫Flash命令字
#define Erase 0x03 //擦除Flash命令字
uchar telnm[11];
//---------------------------
//--選擇型號STC54\58起始地址都為0x8000,51起始地址為0x2000
unsigned int DATA_FLASH_START_ADDRESS = 0x8000;
unsigned char DATA_memory;
/*---------------延時子程序----------------*/
void Delay_US (uchar us)
{
while(--us);
}
void Delay_MS (uchar ms)
{
do {Delay_US(246);Delay_US(247);}
while(--ms);
}
void Delay_S (uchar s)
{
do {Delay_MS(200);Delay_MS(200);Delay_MS(200);Delay_MS(200);Delay_MS(200);}
while(--s);
}
//---------------------------
//--觸發TRIG寄存器
void Trigger_ISP ()
{
EA = 0;
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
EA = 1;
}
//---------------------------
//--禁止IAP操作
void IAP_Disable ()
{
ISP_CONTR = 0;
ISP_CMD = 0;
ISP_TRIG = 0;
}
//---------------------------
//--讀Flash操作
void Byte_Read ()
{
uchar i;
for(i=0;i<11;i++)
{
ADD=DATA_FLASH_START_ADDRESS+i;
ISP_ADDRH = ( ADD >> 8 );//地址的高8位
ISP_ADDRL = ( ADD & 0x00ff );//地址的低8位
EA=0;//關中斷
ISP_CONTR = ENABLE_ISP; //打開IAP功能,及設置Flash操作等待時間
ISP_CMD = Read; //選擇讀 AP模式
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
telnm[i] = ISP_DATA;//存儲讀到的數據
EA = 1;
IAP_Disable();
}
}
//---------------------------
//--字節編程
void Byte_Program ()
{ uchar i;
unsigned int ADD;
for(i=0;i<11;i++)
{
ISP_DATA = DEBUG_DATA+i;
ADD=DATA_FLASH_START_ADDRESS+i;
ISP_ADDRH = ( ADD >> 8 );//地址的高8位
ISP_ADDRL = ( ADD & 0x00ff );//地址的低8位
EA = 0;
ISP_CONTR = ENABLE_ISP; //打開IAP功能,及設置Flash操作等待時間
ISP_CMD = Write;
//Trigger_ISP ();
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
EA = 1;
IAP_Disable ();
}
}
//---------------------------
//--擦除扇區
void Sector_Erase ()
{
uchar i;
for(i=0;i<11;i++)
{
ISP_CONTR = ENABLE_ISP; //打開IAP功能,及設置Flash操作等待時間
ISP_CMD = Erase;
ADD=DATA_FLASH_START_ADDRESS+i;
ISP_ADDRH = ( ADD >> 8 );//地址的高8位
ISP_ADDRL = ( ADD & 0x00ff );//地址的低8位
Trigger_ISP ();
IAP_Disable ();
}
P0=0XFF;
P2=0XFF;
}
//---------------------------
//--LED顯示
void LED()
{
if(telnm[0]==1)
{
P0_1=0;
}
if(telnm[1]==2)
{
P0_2=0;
}
if(telnm[2]==3)
{
P0_3=0;
}
if(telnm[3]==4)
{
P0_4=0;
}
if(telnm[4]==5)
{
P0_5=0;
}
if(telnm[5]==6)
{
P0_6=0;
}
if(telnm[6]==7)
{
P0_7=0;
}
if(telnm[7]==8)
{
P2_0=0;
}
if(telnm[8]==9)
{
P2_1=0;
}
if(telnm[9]==10)
{
P2_2=0;
}
if(telnm[10]==11)
{
P2_3=0;
}
// else
// P0=0x5f;
}
void Key_board ()
{
if(key1==0)
{
Delay_MS(5);
if(key1==0)
{
Byte_Read ();//KEY1按下,
LED();//顯示數據
}
while(key1==0);
}
if(key2==0)//KEY2按下
{
Delay_MS(5);
if(key2==0)
{
P0=0xff;
Byte_Program ();//寫數據到EEPROM
DATA_memory=0;
Beep_on;
P1_7=0;
Delay_MS(200);
Beep_off;
P1_7=1;
Delay_MS(200);
Beep_on;
P1_7=0;
Delay_MS(200);
Beep_off;
P1_7=1;
Delay_MS(200);
Beep_on;
P1_7=0;
Delay_MS(200);
Beep_off;
P1_7=1;
}
while(key2==0);
}
if(key3==0)
{
Delay_MS(5);
if(key3==0)
{
Sector_Erase ();//擦除EEPROM
Byte_Read ();
LED();
}
}
}
void initial ()
{
TMOD=0x20; //定時器1選擇方式2,8位自動重裝
ES=1; //允許串口中斷
PCON=0x00; //SMOD=0
SCON=0x50; //串口選擇方式1
TH1=0xfd; //波特率設置為9600
TL1=0xfd;
EA=1;
TR1=1; //開定時器T1運行控制位
}
void COM_int() interrupt 4 using 0
{
uchar com_buff;
RI=0;
com_buff=SBUF;
if(com_buff==0xab) //自定義指令為0xab
{
Delay_S(1);
ISP_CONTR=0x60; //軟件復位到ISP編程區
}
}
void main()
{
initial (); //初始化
P0 = 0xf0;
Delay_S(1);
P0 = 0x0f;
Delay_S(1);
while(1)
{
Key_board ();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -