| ningling_21 发表于 2014-8-5 15:30  看看头文件中 寄存器定义对不对。。。
 
 sfr IAP_DATA  = 0xC2;              //ISP/IAP Flash数据寄存器
#include<reg51.h>
 #include<intrins.h>
 
 #define SomeNop();{_nop_();_nop_();}
 #define INC(x,y) if(++x>=y) x=0
 
 sbit P0_4=P0^4;
 
 typedef unsigned char BYTE;
 typedef unsigned char WORD;
 /*声明关联IAP的特殊功能寄存器*/
 sfr IAP_DATA=0xc2;
 sfr IAP_ADDRH=0xc3;
 sfr IAP_ADDRL=0xc4;
 sfr IAP_CMD=0xc5;
 sfr IAP_TRIG=0xc6;
 sfr IAP_CONTR=0xc7;
 
 /*定义ISP/IAP/EEPROM命令*/
 #define CMD_IDLE 0;
 #define CMD_READ 1;
 #define CMD_PROGRAM 2;
 #define CMD_ERASE 3;
 
 /*声明串口的特殊功能寄存器*/
 sfr AUXR = 0x8E;
 sfr AUXR1 = 0xA2;
 sfr BRT = 0x9c;
 
 #define ENABLE_IAP 0x83                 //允许IAP,晶振11.0592M<12M,选择3
 
 #define IAP_ADDRESS1 0x0000
 #define IAP_ADDRESS2 0x0200
 #define IAP_ADDRESS3 0x0400
 
 sbit RE=P3^5;
 
 unsigned int f68,faa;
 unsigned char Time1;
 unsigned char TempH1,TempL1;
 unsigned char addrH1,addrL1;
 unsigned char TxTime;
 unsigned char TempH,TempL;
 unsigned char addrH,addrL;
 
 unsigned char MingLing[64];             //命令储存数组
 unsigned char Pwrite=0;                 //命令数组计数
 unsigned char Pread=0;
 
 unsigned char HYMingLing[12];           //命令储存数组
 
 unsigned int  f10ms,fuart,u10ms ;       //接收数据标志
 
 
 //void IapEraseSector(WORD addr);
 /************************************************************
 
 延时函数
 
 ************************************************************/
 /*函数功能:延时1ms*/
 void delay1ms()
 {
 unsigned char i,j;
 for(i=0;i<10;i++)
 for(j=0;j<33;j++)
 ;
 }
 /*函数功能:延时若干秒,入口参数:n*/
 void delay (unsigned char n)
 {
 unsigned char i;
 for (i=0;i<n;i++)
 delay1ms();
 }
 /***********************************************************
 
 EEPROM设置:把采集周期、温度门限、系列号写入
 
 ***********************************************************/
 /*关闭IAP功能,使MCU进入安全模式*/
 void IAP_Disable()
 {
 IAP_CONTR=0;                        //关闭IAP功能
 IAP_CMD=0;                          //清命令寄存器,使寄存器无命令
 IAP_TRIG=0;                         //清触发寄存器,使触发寄存器无触发
 IAP_ADDRH=0x80;                     //数据指针指向non-EEPROM地方
 IAP_ADDRL=0;                        //清IAP地址防止被误用
 }
 /*从EEPROM中读一个字节,入口参数:addr,出口参数:Flash data*/
 BYTE IapReadByte(WORD addr)
 {
 BYTE dat;
 IAP_CONTR=ENABLE_IAP;               //打开IAP功能,设置flash操作等待时间
 IAP_CMD=CMD_READ;                   //IAP/ISP/EEPROM字节读命令
 IAP_ADDRH=addr;                     //设置目标单元位置的高8位地址
 IAP_ADDRL=addr>>8;                  //设置目标单元位置的低8位地址
 IAP_TRIG=0x5a;                      //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此搜索
 IAP_TRIG=0xa5;                      //送完A5h 后,ISP/IAP 命令立即被触发起动
 _nop_();
 dat=IAP_DATA;
 IAP_Disable();
 return dat;
 }
 /*写入字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据*/
 void IapProgramByte(WORD addr,BYTE dat)
 {
 IAP_CONTR=ENABLE_IAP;               //打开 IAP 功能, 设置Flash 操作等待时间
 IAP_CMD=CMD_PROGRAM;                //IAP/ISP/EEPROM 字节编程命令
 IAP_ADDRL=addr;                     //设置目标单元地址的高8 位地址
 IAP_ADDRH=addr>>8;                  //设置目标单元地址的低8 位地址
 IAP_DATA=dat;                       //要编程的数据先送进IAP_DATA 寄存器
 IAP_TRIG=0X5A;                      //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
 IAP_TRIG=0XA5;                      //送完A5h 后,ISP/IAP 命令立即被触发起动
 _nop_();
 IAP_Disable();                      //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态
 }
 /*擦除扇区, 入口:DPTR = 扇区地址*/
 void IapEraseSector(WORD addr)
 {
 IAP_CONTR=ENABLE_IAP;               //打开 IAP 功能, 设置Flash 操作等待时间
 IAP_CMD=CMD_ERASE;                  //IAP/ISP/EEPROM 扇区擦除命令
 IAP_ADDRL=addr;                     //设置目标单元地址的高8 位地址
 IAP_ADDRH=addr>>8;                  //设置目标单元地址的低8 位地址
 IAP_TRIG=0X5A;                      //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
 IAP_TRIG=0XA5;                      //送完A5h 后,ISP/IAP 命令立即被触发起动
 _nop_();
 IAP_Disable();                      //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态
 }
 /*把采集周期、温度门限、系列号写入1,2,3号扇区*/
 void SheZhiCanShu()
 {
 IapEraseSector(IAP_ADDRESS1);
 delay(10);
 IapProgramByte(0x0000,0xAA);
 _nop_();
 IapProgramByte(0x0002,0x01);
 _nop_();
 IapProgramByte(0x0004,0x00);
 _nop_();
 IapProgramByte(0x0006,0x0A);
 _nop_();
 IapProgramByte(0x0008,0x00);
 _nop_();
 IapProgramByte(0x000A,0x01);
 _nop_();
 }
 /*把采集周期、温度门限、系列号读出*/
 void DuChuCanShu()
 {
 TxTime=IapReadByte(0x0002);
 _nop_();
 TempH=IapReadByte(0x0004);
 _nop_();
 TempL=IapReadByte(0x0006);
 _nop_();
 addrH=IapReadByte(0x0008);
 _nop_();
 addrL=IapReadByte(0x000A);
 _nop_();
 
 
 /*    if(Data!=0xAA)
 {
 SheZhiCanShu();
 }*/
 }
 /************************************************************
 
 定时器T0,普通定时,做数据接收是否完成标志
 
 ************************************************************/
 /*定时器中断*/
 void T0_time(void) interrupt 1
 {
 TF0=0;
 TR0=0;                               //关中断
 --u10ms;
 if(u10ms==0)
 {
 f10ms=1;
 }
 TH0=0xfe;                            //重新赋初值
 TL0=0x0b;
 TR0=1;                               //开中断
 }
 /*定时器初始化*/
 void T0_init()
 {
 TMOD=0x01;                            //设置定时器0为工作方式1
 TH0=0xfe;                             //重装初始值(65535-500)=65035=0xfe0b
 TL0=0x0b;
 ET0=1;                                //允许定时中断
 TR0=0;                                //启动定时中断
 }
 /************************************************************
 
 485通信
 
 ************************************************************/
 /*485串口初始化,独立波特率*/
 void UartInit(void)                                //9600bps@11.0592MHz
 {
 PCON &= 0x7f;                                //波特率不倍速
 SCON = 0x50;                                //8位数据,可变波特率
 BRT = 0xFD;                                    //设定独立波特率发生器重装值
 AUXR &= 0xfb;                                //独立波特率发生器时钟为Fosc/12,即12T
 AUXR |= 0x01;                                //串口1选择独立波特率发生器为波特率发生器
 AUXR |= 0x10;                                //启动独立波特率发生器
 AUXR1=0x80;                         //串口P1
 ES=1;
 //    EA=1;
 }
 /*485串口中断程序*/
 void USART_TI(void) interrupt 4
 {
 
 if(RI==1)
 {
 RI=0;
 MingLing[Pwrite]=SBUF;            //把命令保存在数组里
 INC(Pwrite,64);                   //防止数组溢出
 if(MingLing[0]==0x68)
 {
 f68=1;
 }
 else
 {
 Pwrite=0;
 }
 }
 }
 /*命令解析,并进行相对应的回应*/
 void JieXiMingLing()
 {
 unsigned int i;
 unsigned char CRC=0;
 if(Pwrite>=6)
 {
 if(f68==1)                          //命令首字节为0x68,否则无效
 {
 if(MingLing[1]==0x77)           //地址查询命令
 {
 if((MingLing[2]==0x00)&&(MingLing[3]==0x00)&&(MingLing[4]==0xdf)&&(MingLing[5]==0x0d))
 {
 HYMingLing[0]=0x77;
 HYMingLing[1]=0x68;
 HYMingLing[2]=addrH;
 HYMingLing[3]=addrL;
 HYMingLing[4]=0x0d;
 RE=1;
 for(i=0;i<5;i++)
 {
 SBUF=HYMingLing;     //查询地址回应
 while(!TI);
 TI=0;
 }
 RE=0;
 Pwrite=0;
 Pread=0;
 }
 
 }
 }
 }
 }
 
 /***************************************************************
 
 主函数
 
 ***************************************************************/
 void main()
 {
 //    unsigned int i;
 unsigned char Data;
 delay(50);
 RE=0;
 UartInit();
 delay(10);
 T0_init();
 delay(10);
 EA=1;                               //打开总中断
 Data=IapReadByte(0x0000);
 if(Data!=0xAA)
 {
 SheZhiCanShu();
 }
 
 while(1)
 {
 DuChuCanShu();
 if(Pwrite!=Pread)
 {
 Pread=Pwrite;
 TR0=1;
 u10ms=2;
 f10ms=0;
 fuart=1;
 }
 if((f10ms==1)&&(fuart==1))
 {
 fuart=0;
 TR0=0;
 JieXiMingLing();
 }
 }
 }
 看看我完整的程序,应该回应我77 68 00 01 0D,现在回应总是77 68 FF FF 0D,感觉没有读出EEPROM中的数据。
 |