#include     <reg52.h>        //上电后写字符表内容到内部EEPROM
               #include     <intrins.h>        //从内部EEPROM取数据显示
               #define      uchar unsigned char
               #define      uint unsigned int
               #define      NOP  _nop_()
               uint         Font_Counter;              //文字总数
               typedef      uchar BYTE;           
               typedef      uint  WORD;               
               uchar        kcounter,kstatus;          //按键计数标志 按键状态标志
               uint         aa=0;
               uint         s,i,j,k;                   //移动汉字的总数。
               uchar        a_data,b_data,c_data;      //
               uint         move,total,step;           //location为0取文字右半部数据。
               bit          mflag;                     //位变量移动显示标志
               sbit         OE=P1^1;                   //74HC245 A1
               sbit         A1=P1^4;                   //74HC138A
               sbit         B1=P1^3;                   //74HC138B
               sbit         SRCK=P1^2;                 //11脚    移位时钟
               sbit         RCK=P3^7;                  //12脚    锁存时钟
               sbit         SER=P3^6;                  //14      脚数据输入
               sbit         key_in1=P3^2;
               sbit         key_in2=P3^3;
               sbit         SDA=P3^0;                               /****EEPROM数据****/
               sbit         SCL=P3^1;                               /****EEPROM脉冲****/
               bdata        char com_data;                          /****暂用 ****/
               sbit         mos_bit=com_data^7;                     /****高位****/
               sbit         low_bit=com_data^0;                     /****低位****/
 /***********************************************/
               #define      URMD 2                     //0:使用定时器 2 作为波特率发生器
               #define      CMD_IDLE 0                 //空闲模式
               #define      CMD_READ 1                 //IAP 字节读命令
               #define      CMD_PROGRAM 2              //IAP 字节编程命令
               #define      CMD_ERASE 3                //IAP 扇区擦除命令
               uint         iap_eepromadd;             //EEPROM编辑地址
               uint         IAP_ADD;                   //EEPROM地址
               uchar        RDEEPROM_ADD;              //需增加文字总数读出后写IAP_TOTAL 0x0000
               #define      IAP_TOTAL 0x0000           //文字计数器 地址 第128个字节 EEPROM首地址
               #define      IAP_TOTAL 0x0000           //文字计数器 地址 第128个字节 EEPROM首地址
               #define      IAP_ADDA  0x0200           //EEPROM首地址  第一文字存储扇区   
               #define      IAP_ADDB  0x0400           //EEPROM首地址  第二文字存储扇区
               #define      IAP_ADDC  0x0600           //EEPROM首地址  第三文字存储扇区
               #define      IAP_ADDD  0x0800           //EEPROM首地址  第四文字存储扇区
               #define      IAP_ADDE  0x0A00           //EEPROM首地址  第五文字存储扇区    
               #define      IAP_ADDF  0x0C00           //EEPROM首地址  第六文字存储扇区
               #define      IAP_ADDG  0x0E00           //EEPROM首地址  第七文字存储扇区
               #define      ENABLE_IAP 0x82            //if SYSCLK<20MHz
               uint         ISPIAPADD;
 /***********************************************/
         /*----关闭IAP----------------------------*/
               void IapIdle()
               {
               IAP_CONTR = 0;                     //关闭IAP功能
               IAP_CMD = 0;                       //清除命令寄存器
               IAP_TRIG = 0;                      //清除触发寄存器
               IAP_ADDRH = 0x80;                  //将地址设置到非IAP区域
               IAP_ADDRL = 0;
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               _nop_();
               _nop_();
               _nop_();
               _nop_();
               }
 /*-从ISP/IAP/EEPROM区域读取一字节-*/
               BYTE IapReadByte(WORD addr)
               {
               BYTE dat;                          //数据缓冲区
               IAP_CONTR = ENABLE_IAP;            //使能IAP
               IAP_CMD = CMD_READ;                //设置IAP命令
               IAP_ADDRL = addr;                  //设置IAP低地址
               IAP_ADDRH = addr >> 8;             //设置IAP高地址
               IAP_TRIG = 0x5a;                   //写触发命令(0x5a)
               IAP_TRIG = 0xa5;                   //写触发命令(0xa5)
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               _nop_();
               _nop_();
               _nop_();
               _nop_();
               dat = IAP_DATA;                    //读ISP/IAP/EEPROM数据
               IapIdle();                         //关闭IAP功能
               return dat;                        //返回
               }
 /*-写一字节数据到ISP/IAP/EEPROM区域-*/
               void IapProgramByte(WORD addr, BYTE dat)
               {
               IAP_CONTR=ENABLE_IAP;              //使能IAP
               IAP_CMD=CMD_PROGRAM;               //设置IAP命令
               IAP_ADDRL=addr;                    //设置IAP低地址
               IAP_ADDRH=addr >> 8;               //设置IAP高地址
               IAP_DATA=dat;                      //写ISP/IAP/EEPROM数据
               IAP_TRIG=0x5a;                     //写触发命令(0x5a)
               IAP_TRIG=0xa5;                     //写触发命令(0xa5)
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               _nop_();
               _nop_();
               _nop_();
               _nop_();
               IapIdle();
               }
 /*---扇区擦除---------------*/
               void IapEraseSector(WORD addr)
               {
               IAP_CONTR=ENABLE_IAP;              //使能IAP val=IapReadByte(IAP_ADDRESS+1);
               IAP_CMD=CMD_ERASE;                 //设置IAP命令
               IAP_ADDRL=addr;                    //设置IAP低地址
               IAP_ADDRH=addr>>8;                 //设置IAP高地址
               IAP_TRIG=0x5a;                     //写触发命令(0x5a)
               IAP_TRIG=0xa5;                     //写触发命令(0xa5)
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               _nop_();                        //等待ISP/IAP/EEPROM操作完成
               _nop_();
               _nop_();
               _nop_();
               _nop_();
               IapIdle();
               }
 /**************************************/
                void start()
                {
                SDA=1;
                SCL=1;
                SDA=0;
                SCL=0;
                }
 /***************************************/
                void stop()
                {
                SDA=0;
                SCL=1;
                SDA=1;
                }
 /***************************************/
                void ack()
                {
                SCL=1;
                SCL=0;
                }
 /***************************************/
                void shift8(char a)
                {
                data uchar i;
                com_data=a;
                 for(i=0;i<8;i++)
                 {
                 SDA=mos_bit;
                 SCL=1;
                 SCL=0;
                 com_data=com_data*2;
                 }
                }
 /***************************************/
                uchar rd_24C64(uint a)
                {
                uint addh,addl;
                data uint i,command;
                addl=a;
                addh=a>>8;
                SDA=1;
                SCL=0;
                start();
                command=160;
                shift8(command);                            /*****写入160*****/
                ack();                                        
                shift8(addh);                               /*****写高八位地址addh 高三位无效*****/
                ack();
                shift8(addl);                               /*****写入低八位地址 addl*****/
                ack();
                start();
                command=161;
                shift8(command);                            /*****写入161*****/
                ack();
                SDA=1;
                for(i=0;i<8;i++)
                 {
                  com_data=com_data*2;
                  SCL=1;
                  low_bit=SDA;
                  SCL=0;
                 }
                stop();
                return(com_data);
               }
 /**************数据串行输出到74HC595***********************/
               void serial_input(uchar dat)    
               {
               uint m;
                for(m=0;m<8;m++)
                {
                if(dat&0x80)
                SER=1;
                else
                SER=0;
                SRCK=0;    
                SRCK=1;             //数据移入移位寄存器             
                NOP;
                NOP;
                SRCK=0;
                NOP;
                NOP;
                dat=dat<<1;
                }
               }
 /*************并出****************************************/
               void serial_output()
               {
               RCK=1;            //上升沿移位寄存器数据存入8为锁存器     
               NOP;
               NOP;
               RCK=0;    
               }  
 /*************行显控制**********************************/
               void HC138_scan(uchar temp)
               {
                OE=1;
                A1=0x01&temp;
                B1=0x01&(temp>>1);
               }
 /**************数据移位合并**************/
                  void Data_Move()
               {
                a_data<<=1;                //左部数据先移动一步
                c_data=a_data;               //缓冲显示数据等于左移一位后的左部数据
                b_data<<=1;                //右部数据也移动一步
                if(CY==1)                    //如果右部数据移动后进位标志为1
                c_data|=0X01;                //缓冲显示数据等于最低位和1相与
                else                        //否则进位标志为0
                c_data|=0X00;                //缓冲显示数据等于最低位和0相与
                a_data=c_data;
               }
 /**************移动第0--7步数据处理函数**********************/
 /*i=0显示屏左部移出第一个字左部数据,移入第一个字右部数据****/
 /*i=1显示屏右部移出第一个字右部数据,移入第二个字的左部数据**/
               void    handledata1(uint total,uint i,uint j,uint k,uchar step)       //移动汉字的总数。
               {          //i==0写入左半部数据
                uchar tmove;
                if(i==0)//i=0  上一行     i=0下一行
                {      //
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+total+j)*32); //第一个字的左部数据起始为字符表24
                 b_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+total+j)*32+1);         //第一个字的右部数据起始为字符表25
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;   
                 a_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+total+j)*32);       //第一个字的左部数据起始为字符表16
                 b_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+total+j)*32+1);  //第一个字的右部数据起始为字符表17
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+total+j)*32);      //第一个字的左部数据起始为字符表8
                 b_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+total+j)*32+1); //第一个字的右部数据起始为字符表9
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+total+j)*32);     //第一个字的左部数据起始为字符表0
                 b_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+total+j)*32+1);//第一个字的右部数据起始为字符表1
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                }
                if(i==1)     //i=0  上一行     i=0下一行
                {
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+total+j)*32);    //第一个字的右部数据起始为字符表25
                 b_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+j+total+1)*32);    //第二个字的左部起始为第二个字的0
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+total+j)*32); //第一个字的右部起始为起始为17     
                 b_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+j+total+1)*32);    //第二个字的左部起始为第二个字的16
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+total+j)*32); //第一个字的右部起始为起始为9
                 b_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+j+total+1)*32);    //第二个字的左部起始为第二个字的8
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }  
                 serial_input(~c_data);  
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+total+j)*32);//第一个字的右部起始为1
                 b_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+j+total+1)*32);//第二个字的左部起始为第二个字的0
                 for(tmove=0;tmove<step;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                }
               }
 /***移动第8--15步数据处理函数**********************/
 /*i=0显示屏左部移出第一个字的右部数据,移入第二个字的左部数据*****/
 /*i=1显示屏左部移出第一个字的右部数据,移入第二个字的左部数据*****/
               void    handledata2(uint total,uint i,uint j,uint k,uchar step)       //移动汉字的总数。)
               {
               uchar tmove;
               if(i==0)//i=0  上一行     i=0下一行
                {      //(i+1)
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+total+j)*32+1);//第一个字的右部数据起始为25 J=0X*32  j*32
                 b_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+total+j+1)*32);//第二个字的左部数据起始为第二个字的24
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);  
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+total+j)*32+1);    //第一个字的右部数据起始为17
                 b_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+total+j+1)*32); //第二个字的左部数据起始为第二个字的16  
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+total+j)*32+1);//第一个字的右部数据起始为9
                 b_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+total+j+1)*32);//第二个字的左部数据起始为第二个字的8
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+total+j)*32+1);//第一个字的右部数据起始为1
                 b_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+total+j+1)*32);//第二个字的左部数据起始为第二个字的0
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                }
                if(i==1)    //i=0  上一行     i=0下一行
                {
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+3*8+2*k+(s*2+j+total+1)*32);  //第二个字的左部数据
                 b_data=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;   
                 a_data=IapReadByte(IAP_ADDA+2*8+2*k+(s*2+j+total+1)*32);//第二个字的左部数据  
                 b_data=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+1*8+2*k+(s*2+j+total+1)*32);  //第二个字的左部数据
                 b_data=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                 c_data=0X00;
                 a_data=IapReadByte(IAP_ADDA+0*8+2*k+(s*2+j+total+1)*32);//第二个字的左部数据
                 b_data=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+j+total+1)*32);//第二个字的右部数据
                 for(tmove=0;tmove<step-7;tmove++)
                 {
                 Data_Move();
                 }
                 serial_input(~c_data);
                }
               }
 /*************数据处理函数**********************/
 /***外部传递一个移动步数参数,内部设定共需移动汉
 字总数,判断运算汉字的左右部标识函数需修改***/
              void    disdata(uchar step)
              {
              uchar FontCode;
              if(step==0)            //移动步数等于0
               {                    //读当前汉字计数值文字。
                for(k=0;k<4;k++)     //4行同时扫描,共扫4次4X4=16    
                {    
                for(s=0;s<2;s++)    //左右两个屏
                {
                for(j=0;j<2;j++)    //变量j=0或=1为两个字的其中一个
                 {
                 for(i=0;i<2;i++)   //一个字的两行 i=0起始(24,25).(16,17)以此类推
                  {                  //j+total显示汉字的位置加当前汉字计数器地址
                  FontCode=IapReadByte(IAP_ADDA+3*8+2*k+i+(s*2+j+total)*32);
                  serial_input(~FontCode);//第一个起始为24 J=0X*32  j*32     
                  FontCode=IapReadByte(IAP_ADDA+2*8+2*k+i+(s*2+j+total)*32);    
                  serial_input(~FontCode);//第一个起始为16   
                  FontCode=IapReadByte(IAP_ADDA+1*8+2*k+i+(s*2+j+total)*32);          
                  serial_input(~FontCode);//第一个起始为8   
                  FontCode=IapReadByte(IAP_ADDA+0*8+2*k+i+(s*2+j+total)*32);     
                  serial_input(~FontCode);//第一个起始为0
                  }
                 }
                 }
                 serial_output();    // 左右两个屏同时扫描两行,4X2=8行一个区
                 HC138_scan(k);
                }
               }            //L483--L500开机显示第一个和第二个文字正确2015 7 23
               else if(step>0&step<9)         //移动1-7步处理函数
               {
               for(k=0;k<4;k++)               //4行同时扫描,共扫4次4X4=16    
                {   
                for(s=0;s<2;s++)              //左右两个屏
                {
                for(j=0;j<2;j++)              //两个字的其中一个
                 {
                  for(i=0;i<2;i++)            //一个字的两排 i=0为一个字的左半部i=1为一个字的右半部
                  {                           //j+total显示汉字的位置加当前汉字计数器地址
                  handledata1(total,i,j,k,step);  //左半部数据处理显示函数
                  }
                 }
                 }
                 serial_output();             //output
                 HC138_scan(k);
                }
               }
               else if(step>7&step<16)         //移动7-15步处理函数
               {
                for(k=0;k<4;k++)              //4行同时扫描,共扫4次4X4=16    
                {  
                for(s=0;s<2;s++)              //左右两个屏
                {  
                 for(j=0;j<2;j++)             //两个字的其中一个
                 {
                 for(i=0;i<2;i++)             //一个字的两排 i=0为一个字的左半部i=1为一个字的右半部
                  {                           //j+total显示汉字的位置加当前汉字计数器地址
                   handledata2(total,i,j,k,step);
                  }
                 }
                 }
                 serial_output();
                 HC138_scan(k);
                }
               }
              }
 /***定时器计数到检测刷新标志mflag对数据刷新一次***/
               void display1()
               {
                if(mflag==1)                 //如果移动显示标志为1。
                {                            //
                mflag=0;                     //移动标志复位归0,等待下次定时器中断激发。
                move++;                      //移动步数加1。
                 if(move>=16)                //如果移动步数大于等于16。
                 {                            //
                 move=0;                     //步数计数器归0。
                 total++;                    //文字计数器加1
                 if(total>Font_Counter+3)    //移动文字计数值大于Font_Counter+3 总数之后为空代码
                 total=0;                    //归0
                 }                           //每移动8位文字左右部标识取反一次
                }                            //1取文字左半部数据 0取右半部
               disdata(move);                //处理并显示数据
               }
 /*-------定时器中断子程序--中断aa次刷新一次显示-------------*/
                void exint0() interrupt 1       //INT0中断入口
                {                    
                aa=aa+1;
                TH0=0X53;
                TL0=0X32;
                if(aa==6)
                {
                 mflag=1;
                 aa=0;
                 }
                }
 /*------------延时子程序---------------------*/
               void delay(uint t)
               {  
               uint i;
               for(i=0;i<t;i++)
               {}
               }
 /**************Delay_50ms***************************/
               void Delay_50ms(uint ms)        //
               {
               uint m;
               for(;ms>0;ms--)
               for(m=62450;m>0;m--);
               }
 /****************按键计数器状态寄存器归零*************/
                void RstKey()
                {
                kcounter=0;                      //按键计数器归零
                kstatus=0;                       //状态寄存器归零
                }
 /*****************按键低电平检测函数*****************/
                void   LowVoltKey(void)              //按键计数器状态标志加一
                {
                kcounter++;                       
                kstatus++;     
                delay(10);                         //延时                  
                }
 /*****************按键高电平检测函数*****************/
                void    HighVoltKey(void)    //按键计数器加一 状态标志归零
                {
                kcounter++;                  //按键计数器加一
                kstatus=0;                   //按键状态标志归零
                delay(10);                   //延时
                }
 /****************读外部FM24C64到IAP中******************/
 /*************开始和结束写4个字各32字节空代码**********/
                void    Write_Code()
                {
                 uchar F_Counter;
                 uchar Data_Code;
                 uchar m;
                 IapEraseSector(IAP_ADDA);
                 IapEraseSector(IAP_ADDB);
                 IapEraseSector(IAP_ADDC);
                 IapEraseSector(IAP_ADDD);
                 IapEraseSector(IAP_ADDE);
                 IapEraseSector(IAP_ADDF);
                 IapEraseSector(IAP_ADDG);
                 Font_Counter=rd_24C64(3840);              //文字总数等于读EEPROM
 //写4个空字符
 ///
 /*******第一扇区*********/
                 for(F_Counter=0;F_Counter<4;F_Counter++)        //4个字,写第一扇区(包括空代码)
                 {
                  for(m=0;m<32;m++)
                  {
                   IapProgramByte(IAP_ADDA+F_Counter*32+m,0X00);    //内部存储单元
                  }
                 }
 //如果总数大于12 读12个字写到IAP_ADDA
 ///
                 if(Font_Counter>12)                                
                 {
                  for(F_Counter=0;F_Counter<12;F_Counter++)        //12个字,写第一扇区(包括空代码)
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64(F_Counter*32+m);            //外部EEPROM从第一个地址开始读
                    IapProgramByte(IAP_ADDA+(F_Counter+4)*32+m,Data_Code);
                   }
                  }
                 }
 //如果总数小于等于12个字写总数个数到IAP_ADDA
 ///
                 else if(Font_Counter<=12)                                //例总数10
                 {
                  for(F_Counter=0;F_Counter<Font_Counter;F_Counter++)    //总数个字,写第一扇区(包括空代码)
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64(F_Counter*32+m);                    //外部EEPROM从第一个地址开始读
                    IapProgramByte(IAP_ADDA+(F_Counter+4)*32+m,Data_Code); //加四个字空代码地址
                   }
                  }
 //文字总数小于12 12-总数 列 总数8 12-8=4个空代码                         //
                  for(F_Counter=0;F_Counter<(12-Font_Counter);F_Counter++)     //12个字,写第一扇区(包括空代码)
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDA+(Font_Counter+4)*32+m,0X00);        //总数8+4=12 字节开始写空代码
                   }
                  }
 //字节内容后一扇区空代码
                  for(F_Counter=0;F_Counter<16;F_Counter++)             //16个字下一扇区空代码
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDB+F_Counter*32+m,0X00);
                   }
                  }
                  return;
                 }
 //A扇区小于12个字结束
 //如果总数大于28 读16个字写到IAP_ADDB
 //总数大于28个字 写B扇区16个字
 /**************第二扇区*************/
                 if(Font_Counter>28)                              //12第一扇区 16第二扇区
                 {
                  for(F_Counter=0;F_Counter<16;F_Counter++)               //32个字,写第二扇区(包括空代码)
                  {
                   for(m=0;m<32;m++)
                   {
                   Data_Code=rd_24C64((F_Counter+12)*32+m);               //外部EEPROM 从第十二个地址开始读
                   IapProgramByte(IAP_ADDB+F_Counter*32+m,Data_Code);
                   }
                  }
                 }
 //如果总数小于等于28个字写总数个数减上一扇区12个字到IAP_ADDB
 ///
                 else if(Font_Counter<=28)      //例Font_Counter-12=26-12=14
                 {
                  for(F_Counter=0;F_Counter<Font_Counter-12;F_Counter++)//总数减第一扇区12字开始
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64((F_Counter+12)*32+m);               //外部EEPROM从第12个地址开始读
                    IapProgramByte(IAP_ADDB+F_Counter*32+m,Data_Code);  //4空代码 12有效文字
                   }
                  }
 //文字总数小于28 28-总数 例 总数26 28-26=IAP_ADDB余2个空代码
                  for(F_Counter=0;F_Counter<(28-Font_Counter);F_Counter++)//28-总数    例 总数26 28-26=2个空代码
                  {
                   for(m=0;m<32;m++)                              //例26-12=14 从14个字地址开始写两个空代码
                   {                             //例Font_Counter-12=26-12=14,本扇区已写入14个字代码空间剩余2个字代码空间
                    IapProgramByte(IAP_ADDB+(Font_Counter-12+F_Counter)*32+m,0X00); //总数减12后加变量
                   }
                  }
 //字节内容后一扇区空代码
                  for(F_Counter=0;F_Counter<16;F_Counter++)     //
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDC+F_Counter*32+m,0X00);
                   }
                  }
                  return;
                 }
 //B扇区小于28个字结束 A扇区12加B扇区16
 //如果总数大于44 读16个字写到IAP_ADDC
 /*******第三扇区******/
 //总数大于44个字 写C扇区16个字
                 if(Font_Counter>44)    //12第一扇区 16第二扇区    16第三扇区
                 {
                  for(F_Counter=0;F_Counter<16;F_Counter++)               //32个字,写第二扇区(包括空代码)
                  {
                   for(m=0;m<32;m++)
                   {                                                       //第一扇区12个字第二扇区16个字 第28个字位置开始
                   Data_Code=rd_24C64((F_Counter+28)*32+m);               //外部EEPROM 从第28个地址开始读
                   IapProgramByte(IAP_ADDC+F_Counter*32+m,Data_Code);
                   }
                  }
                 }
                 else  if(Font_Counter<=44)                                //总数不够写满第三扇区
                 {                                                        //例总数40个字 40-28=12 写12个字
                  for(F_Counter=0;F_Counter<Font_Counter-28;F_Counter++)//第一扇区12个字第二扇区16个字 第28个字位置开始
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64((F_Counter+28)*32+m);               //外部EEPROM从第28个地址开始读第一12个字第二扇区16个字
                    IapProgramByte(IAP_ADDC+F_Counter*32+m,Data_Code);  //4空代码 12有效文字
                   }
                  }
 //文字总数小于44 44-总数 例 总数40 44-40=IAP_ADDC余4个空代码             //第三扇区剩余空间
                  for(F_Counter=0;F_Counter<(44-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字    
                  {
                   for(m=0;m<32;m++)                              //例44-40==4 从40个字地址开始写4个空代码
                   {                            
                    IapProgramByte(IAP_ADDC+(Font_Counter-28+F_Counter)*32+m,0X00); //总数减28后加变量
                   }
                  }
 //字节内容后一扇区空代码
                  for(F_Counter=0;F_Counter<16;F_Counter++)     //
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDD+F_Counter*32+m,0X00);
                   }
                  }
                  return;
                 }
 //C扇区小于44个字结束 A扇区12加B扇区16 加C扇区16
 //如果总数大于60 读16个字写到IAP_ADDD
 /*******第四扇区*******/
                 if(Font_Counter>60)    //12第一扇区 16第二扇区    16第三扇区 16第四扇区
                 {
                  for(F_Counter=0;F_Counter<16;F_Counter++)               //
                  {
                   for(m=0;m<32;m++)
                   {                                                       //
                   Data_Code=rd_24C64((F_Counter+44)*32+m);               //外部EEPROM 从第44个地址开始读
                   IapProgramByte(IAP_ADDD+F_Counter*32+m,Data_Code);   //第四扇区首地址
                   }
                  }
                  }
                 else if(Font_Counter<=60)                               //总数不够写满第四扇区
                 {
                  for(F_Counter=0;F_Counter<Font_Counter-44;F_Counter++)//总数减44 范围60-44=16
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64((F_Counter+44)*32+m);               //外部EEPROM从第44个地址开始读12+16+16
                    IapProgramByte(IAP_ADDD+F_Counter*32+m,Data_Code);  //4空代码 12有效文字
                   }
                  }
 //文字总数小于60 60-总数 例 总数50 60-50=IAP_ADDD余10个空代码             //第四扇区剩余空间
                  for(F_Counter=0;F_Counter<(60-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字    
                  {
                   for(m=0;m<32;m++)                              //例44-40==4 从40个字地址开始写4个空代码
                   {                            
                    IapProgramByte(IAP_ADDD+(Font_Counter-44+F_Counter)*32+m,0X00); //总数减44后加变量
                   }
                  }
 //字节内容后一扇区空代码
                  for(F_Counter=0;F_Counter<16;F_Counter++)     //
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDE+F_Counter*32+m,0X00);
                   }
                  }
                  return;
                 }
 //C扇区小于60个字结束 A扇区12+B扇区16+C扇区16+D扇区16
 //如果总数大于76 读16个字写到IAP_ADDE
 /******第五扇区******/
                 if(Font_Counter>76)    //12第一扇区 16第二扇区    16第三扇区 16第四扇区  16第五扇区
                 {
                  for(F_Counter=0;F_Counter<16;F_Counter++)               //
                  {
                   for(m=0;m<32;m++)
                   {                                                       //
                   Data_Code=rd_24C64((F_Counter+60)*32+m);               //外部EEPROM 从第60个地址开始读
                   IapProgramByte(IAP_ADDE+F_Counter*32+m,Data_Code);   //第四扇区首地址
                   }
                  }
                  }
                 else if(Font_Counter<=76)                               //总数不够写满第四扇区
                 {
                  for(F_Counter=0;F_Counter<Font_Counter-60;F_Counter++)//总数减44 范围76-60=16
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64((F_Counter+60)*32+m);               //外部EEPROM从第60个地址开始读12+16+16+16
                    IapProgramByte(IAP_ADDE+F_Counter*32+m,Data_Code);  //4空代码 12有效文字
                   }
                  }
 //文字总数小于76 76-总数             
                  for(F_Counter=0;F_Counter<(76-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字    
                  {
                   for(m=0;m<32;m++)                              //例44-40==4 从40个字地址开始写4个空代码
                   {                            
                    IapProgramByte(IAP_ADDE+(Font_Counter-60+F_Counter)*32+m,0X00); //总数减44后加变量
                   }
                  }
 //字节内容后一扇区空代码
                  for(F_Counter=0;F_Counter<16;F_Counter++)     //
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDF+F_Counter*32+m,0X00);
                   }
                  }
                  return;
                 }
 //E扇区小于76个字结束 A扇区12+B扇区16+C扇区16+D扇区16+E扇区16
 //如果总数大于92 读16个字写到IAP_ADDF
 /******第六扇区******/
                 if(Font_Counter>92)    //12第一扇区 16第二扇区    16第三扇区 16第四扇区  16第五扇区
                 {
                  for(F_Counter=0;F_Counter<16;F_Counter++)               //
                  {
                   for(m=0;m<32;m++)
                   {                                                       //
                   Data_Code=rd_24C64((F_Counter+76)*32+m);               //外部EEPROM 从第60个地址开始读
                   IapProgramByte(IAP_ADDF+F_Counter*32+m,Data_Code);   //第四扇区首地址
                   }
                  }
                  }
                 else if(Font_Counter<=76)                               //总数不够写满第四扇区
                 {
                  for(F_Counter=0;F_Counter<Font_Counter-76;F_Counter++)//总数减44 范围76-60=16
                  {
                   for(m=0;m<32;m++)
                   {
                    Data_Code=rd_24C64((F_Counter+76)*32+m);               //外部EEPROM从第60个地址开始读12+16+16+16
                    IapProgramByte(IAP_ADDF+F_Counter*32+m,Data_Code);  //4空代码 12有效文字
                   }
                  }
 //文字总数小于92 92-总数             
                  for(F_Counter=0;F_Counter<(92-Font_Counter);F_Counter++)//44第一扇区12个字第二扇区16个字第三扇区16个字    
                  {
                   for(m=0;m<32;m++)                              //例44-40==4 从40个字地址开始写4个空代码
                   {                            
                    IapProgramByte(IAP_ADDF+(Font_Counter-76+F_Counter)*32+m,0X00); //总数减44后加变量
                   }
                  }
 //字节内容后一扇区空代码
                  for(F_Counter=0;F_Counter<16;F_Counter++)     //
                  {
                   for(m=0;m<32;m++)
                   {
                    IapProgramByte(IAP_ADDG+F_Counter*32+m,0X00);
                   }
                  }
                  return;
                 }
                }
 /***主程序运行启动定时器,首先清屏,定时器定时到刷新显示******/
 /***运行到最后一个文字连续写入0X00使发光管熄灭****************/
               void main()
               {
                AUXR=0X80;        //STC系列的1T 设置
                TMOD=0X01;
                TH0=0X53;
                TL0=0X32;
                EA=1;
                ET0=1;
                TR0=1;
                total=0;           //移动汉字总数计数器归0.
                Write_Code();
                Delay_50ms(50);
                while(1)             //
                 {
                 display1();        //开始移动显示
                 }
               }                  //L818 CODE5373    2019 7 9 10:20