STC15W408AS读FM24C64写内部IAP点阵显示

2024-05-25 20:28

本文主要是介绍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

这篇关于STC15W408AS读FM24C64写内部IAP点阵显示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1002539

相关文章

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

FreeRTOS内部机制学习03(事件组内部机制)

文章目录 事件组使用的场景事件组的核心以及Set事件API做的事情事件组的特殊之处事件组为什么不关闭中断xEventGroupSetBitsFromISR内部是怎么做的? 事件组使用的场景 学校组织秋游,组长在等待: 张三:我到了 李四:我到了 王五:我到了 组长说:好,大家都到齐了,出发! 秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的

C# dateTimePicker 显示年月日,时分秒

dateTimePicker默认只显示日期,如果需要显示年月日,时分秒,只需要以下两步: 1.dateTimePicker1.Format = DateTimePickerFormat.Time 2.dateTimePicker1.CustomFormat = yyyy-MM-dd HH:mm:ss Tips:  a. dateTimePicker1.ShowUpDown = t

java线程深度解析(一)——java new 接口?匿名内部类给你答案

http://blog.csdn.net/daybreak1209/article/details/51305477 一、内部类 1、内部类初识 一般,一个类里主要包含类的方法和属性,但在Java中还提出在类中继续定义类(内部类)的概念。 内部类的定义:类的内部定义类 先来看一个实例 [html]  view plain copy pu

小程序button控件上下边框的显示和隐藏

问题 想使用button自带的loading图标功能,但又不需要button显示边框线 button控件有一条淡灰色的边框,在控件上了样式 border:none; 无法让button边框隐藏 代码如下: <button class="btn">.btn{border:none; /*一般使用这个就是可以去掉边框了*/} 解决方案 发现button控件有一个伪元素(::after