002611j22laxp8lx2l2rqh.jpg (49.91 KB, 下載次數: 94)
下載附件
2020-9-20 08:54 上傳
- #include "reg51.h"
- #include "intrins.h"
- sfr IAP_DATA = 0xC2;
- sfr IAP_ADDRH = 0xC3;
- sfr IAP_ADDRL = 0xC4;
- sfr IAP_CMD = 0xC5;
- sfr IAP_TRIG = 0xC6;
- sfr IAP_CONTR = 0xC7;
- unsigned char state,time;
- void IapIdle()
- {
- IAP_CONTR = 0; //關閉IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除觸發寄存器
- IAP_ADDRH = 0x80; //將地址設置到非IAP區域
- IAP_ADDRL = 0;
- }
- char IapRead(int addr)
- {
- char dat;
- IAP_CONTR = 0x83; //使能IAP
- IAP_CMD = 1; //設置IAP讀命令
- IAP_ADDRL = addr; //設置IAP低地址
- IAP_ADDRH = addr >> 8; //設置IAP高地址
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_();
- dat = IAP_DATA; //讀IAP數據
- IapIdle(); //關閉IAP功能
- return dat;
- }
- void IapProgram(int addr, char dat)
- {
- IAP_CONTR = 0x83; //使能IAP
- IAP_CMD = 2; //設置IAP寫命令
- IAP_ADDRL = addr; //設置IAP低地址
- IAP_ADDRH = addr >> 8; //設置IAP高地址
- IAP_DATA = dat; //寫IAP數據
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_();
- IapIdle(); //關閉IAP功能
- }
- void IapErase(int addr)
- {
- IAP_CONTR = 0x83; //使能IAP
- IAP_CMD = 3; //設置IAP擦除命令
- IAP_ADDRL = addr; //設置IAP低地址
- IAP_ADDRH = addr >> 8; //設置IAP高地址
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_();
- IapIdle(); //關閉IAP功能
- }
- void main()
- {
- IT0 = 1; //使能INT0下降沿中斷
- EX0 = 1; //使能INT0中斷
- EA = 1; //使能總中斷
- state=IapRead(0x0400); //讀取EEPROM保存的數據
- if((state<1)||(state>3)) //判斷數據是否在有效范圍
- state=0x01; //初始化
- while(1)
- {
- time=P1; //讀取P1狀態
- time&=0xfc; //清除time低2位
- time|=state; //賦值time低2位為state
- P1=time; //改變P1低2位狀態,高6位保持原狀態
- }
- }
- void INT0_Isr() interrupt 0
- {
- if(state==0x01)
- state=0x03;
- else if(state==0x03)
- state=0x02;
- else if(state==0x02)
- state=0x01;
- IapErase(0x0400);//擦除
- IapProgram(0x0400, state);//寫入
- }
復制代碼
|