STC15W408AS读FM24C64写内部IAP点阵显示

              #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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pygame raycasting纹理

插值原理 原理 color&#xff08;x&#xff09;(x-x1)/(x2-x1)(color2-color1)color1 x1<x<x2 假如说x伪3 那么color&#xff08;3-x1&#xff09;/(x2-x1)(color2-color1)color 可是图片纹理 这里不需要两种颜色&#xff0c;只需要获得碰撞点坐标后&#xff0c;如果…

安卓玩机搞机技巧综合资源----自己手机制作证件照的几种方法 免费制作证件照

接上篇 安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】 安卓玩机搞机技巧综合资源------开机英文提示解决dm-verity corruption your device is corrupt. 设备内部报错 AB分区等等【二】 安卓玩机搞机技巧综合资源------EROFS分区格式 小米红…

ES基础概念

本文不介绍如何使用ES&#xff08;使用ES见&#xff1a;&#xff09; 1.ES生态圈 ES&#xff1a; Logstash&#xff1a;数据处理服务程序&#xff0c;解析转换加工数据&#xff1b; Kibana&#xff1a;数据展示、集群管理&#xff0c;数据可视化、ES管理与监控、报表等&#xf…

Nature期刊的等级和分类

Nature期刊不用过多介绍&#xff0c;学术界人员都对其有所了解&#xff0c;可以和Science&#xff0c;Cell比肩&#xff0c;Nature旗下创办了很多子刊&#xff0c;系列期刊有一百多种&#xff0c;当然其含金量各有不同&#xff0c;nature旗下的期刊等级你是否都了解了。 Nature…

设计模式——概述

1.设计模式定义 ​ 设计模式是软件设计中常见问题的典型解决方案,可用于解决代码中反复出现的设计问题。设计模式的出现可以让我们站在前人的肩膀上&#xff0c;通过一些成熟的设计方案来指导新项目的开发和设计&#xff0c;以便于我们开发出具有更好的灵活性和可扩展性&#…

探索SPI单线传输模式中时钟线与数据传输的简化

探索SPI单线传输模式&#xff1a;时钟线与数据传输的简化之道 在当今的嵌入式系统和微控制器通信中&#xff0c;串行外设接口&#xff08;SPI&#xff09;因其高速、全双工和同步的特点而广受欢迎。然而&#xff0c;随着设备尺寸和复杂性的不断减少&#xff0c;对SPI通信的简化…

JAVAEE之线程(10)_线程池、线程池的创建、实现线程池

一 线程池 1.1为什么要有线程池&#xff1f; 线程池顾名思义是由多个线程所组成&#xff0c;作用就是减少线程的建立与销毁&#xff0c;与数据库连接池相同概念&#xff0c;为了减少连接与释放&#xff0c;从而降低消耗提升效率。 1.2 线程池的优势 总体来说&#xff0c;线程…

【数据分析面试】53.推送消息的分布情况(SQL)

题目 我们有两个表&#xff0c;一个是 notification_deliveries 表&#xff0c;另一个是包含 created 和购买 conversion dates 的 users 表。如果用户没有购买&#xff0c;那么 conversion_date 列为 NULL。 编写一个查询&#xff0c;以获取用户转换前的推送通知总数的分布情…

Java反射角度简单理解spring IOC容器

概述 Java反射&#xff08;Reflection&#xff09;是Java编程语言的一个特性&#xff0c;它允许在运行时对类、接口、字段和方法进行动态查询和操作。反射提供了一种在运行时查看和修改程序行为的能力&#xff0c;这通常用于实现一些高级功能&#xff0c;如框架(Spring)、ORM&…

算法:树状数组

文章目录 面试题 10.10. 数字流的秩327. 区间和的个数315. 计算右侧小于当前元素的个数 树状数组可以理解一种数的存储格式。 面试题 10.10. 数字流的秩 假设你正在读取一串整数。每隔一段时间&#xff0c;你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。 请实现数据结构…

网络信息安全

目录 引言 网络信息安全的基本概念 定义 主要目标 网络信息安全的范围 主要威胁 恶意软件 黑客攻击 拒绝服务攻击 社交工程 内部威胁 常用技术和防护措施 加密技术 防火墙 入侵检测和防御系统 访问控制 多因素认证 安全审计和监控 安全培训和意识提升 未来发…

无人机支持下的自然灾害风险评估技术应用

张老师&#xff08;副教授&#xff09;&#xff0c;长期从事无人机遥感技术与应用&#xff0c;主持多项国家级科研项目&#xff0c;编写著作2部&#xff0c;第一作者发表科研论文20余篇。对无人机遥感的多平台、多传感应用现状以及涉及的核心技术具有很深的理解&#xff0c;精通…

失业潮中如何突围?优秀PPT案例助你职场逆袭

在这个变幻莫测的时代&#xff0c;失业潮像一场突如其来的暴风雨&#xff0c;许多人在职场的大海中迷失方向。但别担心&#xff0c;即使风浪再大&#xff0c;总有勇敢的航海者能够乘风破浪&#xff0c;找到属于自己的那片新大陆。 今天&#xff0c;我们就来聊聊&#xff0c;在…

MyBatis 学习笔记(一)

MyBatis 封装 JDBC :连接、访问、操作数据库中的数据 MyBatis 是一个持久层框架。 MyBatis 提供的持久层框架包括 SQLMaps 和 Data Access Objects&#xff08;DAO&#xff09; SQLMaps&#xff1a;数据库中的数据和 Java数据的一个映射关系 封装 JDBC 的过程Data Access Ob…

C++入门:从C语言到C++的过渡(3)

目录 1.内联函数 1.1内联函数的定义 1.2特性 2.auto关键字 2.1auto的简介 2.2注意事项 3.范围for 4.nullptr空指针 1.内联函数 在C语言中&#xff0c;无论使用宏常量还是宏函数都容易出错&#xff0c;而且无法调试。而C为了弥补这一缺陷&#xff0c;引入了内联函数的概…

为了“降本增效”,我用AI 5天将SpringBoot迁移到了Nodejs

背景 大环境不好&#xff0c;各行各业都在流行“降本增效”&#xff0c;IT行业大肆执行“开猿节流”&#xff0c;一顿操作效果如何&#xff1f;普通搬砖人谁会在乎呢。 为了收紧我的口袋&#xff0c;决定从头学习NodejsTypeScript&#xff0c;来重写我的Java后端服务。 其实这…

安装 ganache

要注意 node.js 和 npm 的版本 npm install ganache -g 若因为网络问题装不上可以使用镜像 npm config set registry https://mirrors.huaweicloud.com/repository/npm/ 再次尝试安装 启动 ganache

浅谈面向对象--知识补充

This关键字 this 内存图 this关键字表示当前对象本身&#xff0c;一般用于类的内部&#xff0c;其内部存在一个地址&#xff0c;指向当前初始化的对象本身。 当new一个对象时&#xff0c;实际上产生了两个引用&#xff0c;一个是供类Dog内部调用其成员变量和成员方法的this关键…

kotlinx.coroutines.debug.AgentPremain

大家好 我是苏麟 . 项目引入AI大模型 debug 出现报错 设置 勾选

MySql超大Sql文件导入效率优化

对于MySQL中超大SQL文件的导入&#xff0c;效率优化是至关重要的&#xff0c;因为不当的操作可能导致导入过程耗时过长&#xff0c;甚至失败。以下是一些建议来优化MySQL超大SQL文件的导入效率&#xff1a; 调整max_allowed_packet参数&#xff1a; 这个参数定义了MySQL服务器和…