sujingliang 发表于 2023-11-24 21:53:57

STC89C52RC 驱动16x64LED点阵模块驱动记录(四)SST29EE020 GB2312汉字库读取

本帖最后由 sujingliang 于 2023-11-24 22:09 编辑

一、前言

字库偏移计算方法 GB2312字库的读取偏移量计算方法:
offset= ((GBH-0xa1)*94+GBL-0xa1)*2*16
       GBK字库的读取偏移量计算方法:
当 GBKL<0X7F 时: offset=((GBKH-0x81)*190+GBKL-0X40)*(16*2);
当 GBKL>0X80 时: offset=((GBKH-0x81)*190+GBKL-0X41)*(16*2);
256k字库的特殊处理      还需要考虑SST29EE020 256k字库如何读取的问题,毕竟51单片机外部存储只能直接读取64k。把256k分成4部分,人为控制最高的2位(16、17),根据偏移量可得以下对应关系,这样就可以访问256k的外部地址了:

偏移量(为了比较没有乘32,乘32就超过16位了)对应的存储地址
0-0x7FF0-64k
0x800-0x100064k-128k
0x1000-0x17FF128k-192k
0x1800-0x2000192k-256k
temp=((GBH-0xa1)*94+GBL-0xa1);
if (temp<0x800){a17=0;a16=0;}
else if ((temp>=0x800)&&(temp<0x1000)){a17=0;a16=1;}
else if ((temp>=0x1000)&&(temp<0x1800)){a17=1;a16=0;}
else if ((temp>=0x1800)&&(temp<0x2000)){a17=1;a16=1;}

二、读取SST29EE020 GB2312字库源码

2.1 四字出现#include <STC89C5xRC.H>
#include <intrins.h>
#include <absacc.h>
#include <string.h>

#define FLASH_ADDR_BASE 0x0000

sbit SH_CP = P1^5;
sbit DS = P2^7;
sbit ST_CP = P1^6;


sbit SST29EE020_CE = P3^4;        //SST29EE020,0有效
//sbit SST29EE020_WE = P3^6;        //不用定义,系统自动控制
//sbit SST29EE020_OE = P3^7;        //不用定义,系统自动控制
sbit A17=P3^3;            //SST29EE020 的高2位
sbit A16=P3^2;            //SST29EE020 的高2位
bit a17,a16;                //漏定义了,加上

typedef unsigned int Uint16;
typedef unsigned char Uint8;

unsigned char xdata Table_BUFF;
unsigned char code *str="\xBE\xFD\xB2\xBB\xBC\xFB\xA3\xAC\xBB\xC6\xBA\xD3\xD6\xAE\xCB\xAE\xCC\xEC\xC9\xCF\xC0\xB4\xA3\xAC\xB1\xBC\xC1\xF7\xB5\xBD\xBA\xA3\xB2\xBB\xB8\xB4\xBB\xD8\xA1\xA3\xBE\xFD\xB2\xBB\xBC\xFB\xA3\xAC\xB8\xDF\xCC\xC3\xC3\xF7\xBE\xB5\xB1\xAF\xB0\xD7\xB7\xA2\xA3\xAC\xB3\xAF\xC8\xE7\xC7\xE0\xCB\xBF\xC4\xBA\xB3\xC9\xD1\xA9\xA1\xA3\xC8\xCB\xC9\xFA\xB5\xC3\xD2\xE2\xD0\xEB\xBE\xA1\xBB\xB6\xA3\xAC\xC4\xAA\xCA\xB9\xBD\xF0\xE9\xD7\xBF\xD5\xB6\xD4\xD4\xC2\xA1\xA3\xCC\xEC\xC9\xFA\xCE\xD2\xB2\xC4\xB1\xD8\xD3\xD0\xD3\xC3\xA3\xAC\xC7\xA7\xBD\xF0\xC9\xA2\xBE\xA1\xBB\xB9\xB8\xB4\xC0\xB4\xA1\xA3\xC5\xEB\xD1\xF2\xD4\xD7\xC5\xA3\xC7\xD2\xCE\xAA\xC0\xD6\xA3\xAC\xBB\xE1\xD0\xEB\xD2\xBB\xD2\xFB\xC8\xFD\xB0\xD9\xB1\xAD\xA1\xA3\xE1\xAF\xB7\xF2\xD7\xD3\xA3\xAC\xB5\xA4\xC7\xF0\xC9\xFA\xA3\xAC\xBD\xAB\xBD\xF8\xBE\xC6\xA3\xAC\xB1\xAD\xC4\xAA\xCD\xA3\xA1\xA3\xD3\xEB\xBE\xFD\xB8\xE8\xD2\xBB\xC7\xFA\xA3\xAC\xC7\xEB\xBE\xFD\xCE\xAA\xCE\xD2\xC7\xE3\xB6\xFA\xCC\xFD\xA1\xA3\xD6\xD3\xB9\xC4\xE2\xCD\xD3\xF1\xB2\xBB\xD7\xE3\xB9\xF3\xA3\xAC\xB5\xAB\xD4\xB8\xB3\xA4\xD7\xED\xB2\xBB\xD4\xB8\xD0\xD1\xA1\xA3\xB9\xC5\xC0\xB4\xCA\xA5\xCF\xCD\xBD\xD4\xBC\xC5\xC4\xAF\xA3\xAC\xCE\xA9\xD3\xD0\xD2\xFB\xD5\xDF\xC1\xF4\xC6\xE4\xC3\xFB\xA1\xA3\xB3\xC2\xCD\xF5\xCE\xF4\xCA\xB1\xD1\xE7\xC6\xBD\xC0\xD6\xA3\xAC\xB6\xB7\xBE\xC6\xCA\xAE\xC7\xA7\xED\xA7\xBB\xB6\xDA\xCA\xA1\xA3\xD6\xF7\xC8\xCB\xBA\xCE\xCE\xAA\xD1\xD4\xC9\xD9\xC7\xAE\xA3\xAC\xBE\xB6\xD0\xEB\xB9\xC1\xC8\xA1\xB6\xD4\xBE\xFD\xD7\xC3\xA1\xA3\xCE\xE5\xBB\xA8\xC2\xED\xA3\xAC\xC7\xA7\xBD\xF0\xF4\xC3\xA3\xAC\xBA\xF4\xB6\xF9\xBD\xAB\xB3\xF6\xBB\xBB\xC3\xC0\xBE\xC6\xA3\xAC\xD3\xEB\xB6\xFB\xCD\xAC\xCF\xFA\xCD\xF2\xB9\xC5\xB3\xEE\xA1\xA3\0";
unsigned int pStr=0;

int GetGBCode_from_EEPROM(unsigned char* pBuffer,const unsigned char * c);
void prepareBuff();
Uint8 FlashRead(Uint16 offset);


void delayms(unsigned int m)
{
        int i,j;
        for(i=0; i<m; i++)
                for(j=0; j<120; j++);
}

//595就是串行输入,凑足8个并行输出,SH_CP上升沿管串行输入
void HC595(unsigned char dat)
{
        unsigned char j;
        for(j=0;j<8;j++)
        {
                SH_CP = 0;        //为移位准备
                DS = dat & 0x01;        //先低位
                dat=dat>>1;
                SH_CP =1;        //上升沿,移位
        }
}

//在16x64LED屏上显示4个汉字,下面函数名没改
void Matrix16x16(unsigned char num)
{
        unsigned char k,i;
        unsigned int m,n;
        unsigned char Char_num=num;
        //Char_num=4;//m是用来做移字用的,因为目前字是静止的,所以人为设成4,减少循环
        for(m=0;m<Char_num;m++)
        {
                for(n=0;n<32;n++)    //为了字不闪
                {
                       
                        for(k=0;k<16;k++)    //行扫描
                        {
                                for(i=0;i<num;i++)    //一行中的左右半部分显示
                                {
                                    HC595(~Table_BUFF);                //左或右半部分
                                        HC595(~Table_BUFF);                //左或右半部分
                                               
                                }
                               
                                ST_CP = 0;
                                ST_CP = 1; //板上8个595一起,SC_CP上升沿并行输出,凑足8个串行一起并行输入
                                P1=k;    //74HC154(4-16译码器),控制行,只用到P1口低4位,决定74HC154的16输出引脚中哪个是低电平有效
                                _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                                _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                                P1=0xff;    //74HC154输出完
                        }
                }
        }
}


//从FLASH(EEPROM)中读一个汉字的字模32个字节
int GetGBCode_from_EEPROM(unsigned char* pBuffer,const unsigned char * c)
{
    unsigned char GBH,GBL,i;
    unsigned int pos,temp;
    GBH=*c;   /* 取高8位数据 */
    GBL=*(c+1);/* 取低8位数据 */
       
        temp=((GBH-0xa1)*94+GBL-0xa1);
               
        pos = temp*32 ;
       
    //判断偏移在哪个64k中,决定a17,a16取值。
        if (temp<0x800){a17=0;a16=0;}
        else if ((temp>=0x800)&&(temp<0x1000)){a17=0;a16=1;}
        else if ((temp>=0x1000)&&(temp<0x1800)){a17=1;a16=0;}
        else if ((temp>=0x1800)&&(temp<0x2000)){a17=1;a16=1;}
           
        for(i=0;i<32;i++)
        {
                *pBuffer++=FlashRead(pos++);      //循环读32个字节,一个中文字模
        }
    return 0;
}

//按地址从FLASH(EEPROM)中读一个字节
Uint8 FlashRead(Uint16 offset)
{
        Uint16 dat;
        A17=a17;
        A16=a16;
        dat=XBYTE;
        return dat;
}

//准备显示的buff,4个字的字模
void prepareBuff()
{
        unsigned char i;

        for(i=0;i<4;i++)
        {
                        GetGBCode_from_EEPROM(Table_BUFF+i*32,str+pStr);
                        pStr=pStr+2;    //pStr指向str中下一个要字符的位置,中文占2个字节,所以加2.
        }
        if(pStr>=strlen(str)) pStr=0;
}


void main(){
    SST29EE020_CE=0;        //SST29EE020一直有效
        while(1){
                prepareBuff();
                Matrix16x16(4);
                delayms(100);
        }
}

2.2 向右移动

#include <STC89C5xRC.H>
#include <intrins.h>
#include <absacc.h>
#include <string.h>

#define FLASH_ADDR_BASE 0x0000

sbit SH_CP = P1^5;
sbit DS = P2^7;
sbit ST_CP = P1^6;


sbit SST29EE020_CE = P3^4;      //SST29EE020,0有效
//sbit SST29EE020_WE = P3^6;      //不用定义,系统自动控制
//sbit SST29EE020_OE = P3^7;      //不用定义,系统自动控制
sbit A17=P3^3;            //SST29EE020 的高2位
sbit A16=P3^2;            //SST29EE020 的高2位
bit a17,a16;                //漏定义了,加上

typedef unsigned int Uint16;
typedef unsigned char Uint8;

unsigned char xdata Table_BUFF;

//坎坎伐檀兮置之河之干兮河水清且涟猗不稼不穑胡取禾三百廛兮不狩不猎胡瞻尔庭有县貆兮彼君子兮不素餐兮坎坎伐辐兮置之河之侧兮河水清且直猗不稼不穑胡取禾三百亿兮不狩不猎胡瞻尔庭有县特兮彼君子兮不素食兮坎坎伐轮兮置之河之漘兮河水清且沦猗稼不穑胡取禾三百廛兮不狩不猎胡瞻尔庭有县鹑兮彼君子兮不素飧兮
unsigned char code *str="\xBF\xB2\xBF\xB2\xB7\xA5\xCC\xB4\xD9\xE2\xD6\xC3\xD6\xAE\xBA\xD3\xD6\xAE\xB8\xC9\xD9\xE2\xBA\xD3\xCB\xAE\xC7\xE5\xC7\xD2\xC1\xB0\xE2\xA2\xB2\xBB\xBC\xDA\xB2\xBB\xF0\xA3\xBA\xFA\xC8\xA1\xBA\xCC\xC8\xFD\xB0\xD9\xE2\xDC\xD9\xE2\xB2\xBB\xE1\xF7\xB2\xBB\xC1\xD4\xBA\xFA\xD5\xB0\xB6\xFB\xCD\xA5\xD3\xD0\xCF\xD8\xD8\x7D\xD9\xE2\xB1\xCB\xBE\xFD\xD7\xD3\xD9\xE2\xB2\xBB\xCB\xD8\xB2\xCD\xD9\xE2\xBF\xB2\xBF\xB2\xB7\xA5\xB7\xF8\xD9\xE2\xD6\xC3\xD6\xAE\xBA\xD3\xD6\xAE\xB2\xE0\xD9\xE2\xBA\xD3\xCB\xAE\xC7\xE5\xC7\xD2\xD6\xB1\xE2\xA2\xB2\xBB\xBC\xDA\xB2\xBB\xF0\xA3\xBA\xFA\xC8\xA1\xBA\xCC\xC8\xFD\xB0\xD9\xD2\xDA\xD9\xE2\xB2\xBB\xE1\xF7\xB2\xBB\xC1\xD4\xBA\xFA\xD5\xB0\xB6\xFB\xCD\xA5\xD3\xD0\xCF\xD8\xCC\xD8\xD9\xE2\xB1\xCB\xBE\xFD\xD7\xD3\xD9\xE2\xB2\xBB\xCB\xD8\xCA\xB3\xD9\xE2\xBF\xB2\xBF\xB2\xB7\xA5\xC2\xD6\xD9\xE2\xD6\xC3\xD6\xAE\xBA\xD3\xD6\xAE\x9D\x5F\xD9\xE2\xBA\xD3\xCB\xAE\xC7\xE5\xC7\xD2\xC2\xD9\xE2\xA2\xBC\xDA\xB2\xBB\xF0\xA3\xBA\xFA\xC8\xA1\xBA\xCC\xC8\xFD\xB0\xD9\xE2\xDC\xD9\xE2\xB2\xBB\xE1\xF7\xB2\xBB\xC1\xD4\xBA\xFA\xD5\xB0\xB6\xFB\xCD\xA5\xD3\xD0\xCF\xD8\xF0\xC8\xD9\xE2\xB1\xCB\xBE\xFD\xD7\xD3\xD9\xE2\xB2\xBB\xCB\xD8\xE2\xB8\xD9\xE2\0";
unsigned int pStr=0;

int GetGBCode_from_EEPROM(unsigned char* pBuffer,const unsigned char * c);
void prepareBuff();
Uint8 FlashRead(Uint16 offset);


void delayms(unsigned int m)
{
      int i,j;
      for(i=0; i<m; i++)
                for(j=0; j<120; j++);
}

//595就是串行输入,凑足8个并行输出,SH_CP上升沿管串行输入
void HC595(unsigned char dat)
{
      unsigned char j;
      for(j=0;j<8;j++)
      {
                SH_CP = 0;      //为移位准备
                DS = dat & 0x01;      //先低位
                dat=dat>>1;
                SH_CP =1;          //上升沿,移位
      }
}

//在16x64LED屏上显示4个汉字,下面函数名没改
void Matrix16x16(unsigned char num)
{
      unsigned char k,i;
      unsigned int m,n;
      unsigned char Char_num=1;
      //Char_num=4;//m是用来做移字用的,因为目前字是静止的,所以人为设成4,减少循环
      for(m=0;m<Char_num;m++)
      {
                for(n=0;n<32;n++)    //为了字不闪
                {
                        
                        for(k=0;k<16;k++)    //行扫描
                        {
                              for(i=0;i<num;i++)    //一行中的左右半部分显示
                              {
                                    HC595(~Table_BUFF);                //左或右半部分
                                                HC595(~Table_BUFF);                //左或右半部分
                                                //HC595(~Table_BUFF[(32*i+2*k+1-m*32)%128]);                //左半部分
                                                //HC595(~Table_BUFF[(32*i+2*k+0-m*32)%128]);                //右半部分
                              }
                              
                              ST_CP = 0;
                              ST_CP = 1; //板上8个595一起,SC_CP上升沿并行输出,凑足8个串行一起并行输入
                              P1=k;    //74HC154(4-16译码器),控制行,只用到P1口低4位,决定74HC154的16输出引脚中哪个是低电平有效
                              _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                              _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                              P1=0xff;    //74HC154输出完,马上关
                        }
                }
      }
}


//从FLASH(EEPROM)中读一个汉字的字模32个字节
int GetGBCode_from_EEPROM(unsigned char* pBuffer,const unsigned char * c)
{
    unsigned char GBH,GBL,i;
    unsigned int pos,temp;
    GBH=*c;   /* 取高8位数据 */
    GBL=*(c+1);/* 取低8位数据 */


      temp=((GBH-0xa1)*94+GBL-0xa1);
               

      pos = temp*32 ;
      
    //判断偏移在哪个64k中,决定a17,a16取值。
      if (temp<0x800){a17=0;a16=0;}
      else if ((temp>=0x800)&&(temp<0x1000)){a17=0;a16=1;}
      else if ((temp>=0x1000)&&(temp<0x1800)){a17=1;a16=0;}
      else if ((temp>=0x1800)&&(temp<0x2000)){a17=1;a16=1;}

            
      for(i=0;i<32;i++)
      {
                *pBuffer++=FlashRead(pos++);      //循环读32个字节,一个中文字模
      }
   return 0;
}

//按地址从FLASH(EEPROM)中读一个字节
Uint8 FlashRead(Uint16 offset)
{
      Uint8 dat;
      A17=a17;
      A16=a16;
      dat=XBYTE;
      return dat;
}


//连续移位
void shiftBuff()
{
      unsigned char i;
      for(i=0;i<96;i++)
      {
                Table_BUFF=Table_BUFF;
                //Table_BUFF=Table_BUFF;
      }
      GetGBCode_from_EEPROM(Table_BUFF+96,str+pStr);
      pStr=pStr+2;
      if(pStr>=strlen(str)) pStr=0;
}


//准备显示的buff,4个字的字模
void prepareBuff()
{
      unsigned char i;

      for(i=0;i<4;i++)
      {
                        GetGBCode_from_EEPROM(Table_BUFF+i*32,str+pStr);
                        pStr=pStr+2;    //pStr指向str中下一个要字符的位置,中文占2个字节,所以加2.
      }
      if(pStr>=strlen(str)) pStr=0;
}


void main(){
SST29EE020_CE=0;      //SST29EE020一直有效
      prepareBuff();
      while(1){
               
                //prepareBuff();
               
                Matrix16x16(4);
                shiftBuff();
                //delayms(100);
      }
}

2.3 向上移动

#include <STC89C5xRC.H>
#include <intrins.h>
#include <absacc.h>
#include <string.h>

#define FLASH_ADDR_BASE 0x0000

sbit SH_CP = P1^5;
sbit DS = P2^7;
sbit ST_CP = P1^6;


sbit SST29EE020_CE = P3^4;      //SST29EE020,0有效
//sbit SST29EE020_WE = P3^6;      //不用定义,系统自动控制
//sbit SST29EE020_OE = P3^7;      //不用定义,系统自动控制
sbit A17=P3^3;            //SST29EE020 的高2位
sbit A16=P3^2;            //SST29EE020 的高2位
bit a17,a16;                //漏定义了,加上

typedef unsigned int Uint16;
typedef unsigned char Uint8;

unsigned char xdata Table_BUFF;
unsigned char code *str="\xBF\xB2\xBF\xB2\xB7\xA5\xCC\xB4\xD9\xE2\xD6\xC3\xD6\xAE\xBA\xD3\xD6\xAE\xB8\xC9\xD9\xE2\xBA\xD3\xCB\xAE\xC7\xE5\xC7\xD2\xC1\xB0\xE2\xA2\xB2\xBB\xBC\xDA\xB2\xBB\xF0\xA3\xBA\xFA\xC8\xA1\xBA\xCC\xC8\xFD\xB0\xD9\xE2\xDC\xD9\xE2\xB2\xBB\xE1\xF7\xB2\xBB\xC1\xD4\xBA\xFA\xD5\xB0\xB6\xFB\xCD\xA5\xD3\xD0\xCF\xD8\xD8\x7D\xD9\xE2\xB1\xCB\xBE\xFD\xD7\xD3\xD9\xE2\xB2\xBB\xCB\xD8\xB2\xCD\xD9\xE2\xBF\xB2\xBF\xB2\xB7\xA5\xB7\xF8\xD9\xE2\xD6\xC3\xD6\xAE\xBA\xD3\xD6\xAE\xB2\xE0\xD9\xE2\xBA\xD3\xCB\xAE\xC7\xE5\xC7\xD2\xD6\xB1\xE2\xA2\xB2\xBB\xBC\xDA\xB2\xBB\xF0\xA3\xBA\xFA\xC8\xA1\xBA\xCC\xC8\xFD\xB0\xD9\xD2\xDA\xD9\xE2\xB2\xBB\xE1\xF7\xB2\xBB\xC1\xD4\xBA\xFA\xD5\xB0\xB6\xFB\xCD\xA5\xD3\xD0\xCF\xD8\xCC\xD8\xD9\xE2\xB1\xCB\xBE\xFD\xD7\xD3\xD9\xE2\xB2\xBB\xCB\xD8\xCA\xB3\xD9\xE2\xBF\xB2\xBF\xB2\xB7\xA5\xC2\xD6\xD9\xE2\xD6\xC3\xD6\xAE\xBA\xD3\xD6\xAE\x9D\x5F\xD9\xE2\xBA\xD3\xCB\xAE\xC7\xE5\xC7\xD2\xC2\xD9\xE2\xA2\xBC\xDA\xB2\xBB\xF0\xA3\xBA\xFA\xC8\xA1\xBA\xCC\xC8\xFD\xB0\xD9\xE2\xDC\xD9\xE2\xB2\xBB\xE1\xF7\xB2\xBB\xC1\xD4\xBA\xFA\xD5\xB0\xB6\xFB\xCD\xA5\xD3\xD0\xCF\xD8\xF0\xC8\xD9\xE2\xB1\xCB\xBE\xFD\xD7\xD3\xD9\xE2\xB2\xBB\xCB\xD8\xE2\xB8\xD9\xE2\0";
unsigned int pStr=0,shiftTime;

int GetGBCode_from_EEPROM(unsigned char* pBuffer,const unsigned char * c);
void prepareBuff();
Uint8 FlashRead(Uint16 offset);


void delayms(unsigned int m)
{
      int i,j;
      for(i=0; i<m; i++)
                for(j=0; j<120; j++);
}

//595就是串行输入,凑足8个并行输出,SH_CP上升沿管串行输入
void HC595(unsigned char dat)
{
      unsigned char j;
      for(j=0;j<8;j++)
      {
                SH_CP = 0;      //为移位准备
                DS = dat & 0x01;      //先低位
                dat=dat>>1;
                SH_CP =1;          //上升沿,移位
      }
}

//在16x64LED屏上显示4个汉字,下面函数名没改
void Matrix16x16(unsigned char num)
{
      unsigned char k,i;
      unsigned int m,n;
      unsigned char Char_num=1;
      //Char_num=4;//m是用来做移字用的,因为目前字是静止的,所以人为设成4,减少循环
      for(m=0;m<Char_num;m++)
      {
                for(n=0;n<32;n++)    //为了字不闪
                {
                        
                        for(k=0;k<16;k++)    //行扫描
                        {
                              for(i=0;i<num;i++)    //一行中的左右半部分显示
                              {
                                    HC595(~Table_BUFF);                //左或右半部分
                                                HC595(~Table_BUFF);                //左或右半部分
                                                //HC595(~Table_BUFF[(32*i+2*k+1-m*32)%128]);                //左半部分
                                                //HC595(~Table_BUFF[(32*i+2*k+0-m*32)%128]);                //右半部分
                              }
                              
                              ST_CP = 0;
                              ST_CP = 1; //板上8个595一起,SC_CP上升沿并行输出,凑足8个串行一起并行输入
                              P1=k;    //74HC154(4-16译码器),控制行,只用到P1口低4位,决定74HC154的16输出引脚中哪个是低电平有效
                              _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                              _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                              P1=0xff;    //74HC154输出完,马上关
                        }
                }
      }
}


//从FLASH(EEPROM)中读一个汉字的字模32个字节
int GetGBCode_from_EEPROM(unsigned char* pBuffer,const unsigned char * c)
{
    unsigned char GBH,GBL,i;
    unsigned int pos,temp;
    GBH=*c;   /* 取高8位数据 */
    GBL=*(c+1);/* 取低8位数据 */


      temp=((GBH-0xa1)*94+GBL-0xa1);
               

      pos = temp*32 ;
      
    //判断偏移在哪个64k中,决定a17,a16取值。
      if (temp<0x800){a17=0;a16=0;}
      else if ((temp>=0x800)&&(temp<0x1000)){a17=0;a16=1;}
      else if ((temp>=0x1000)&&(temp<0x1800)){a17=1;a16=0;}
      else if ((temp>=0x1800)&&(temp<0x2000)){a17=1;a16=1;}

            
      for(i=0;i<32;i++)
      {
                *pBuffer++=FlashRead(pos++);      //循环读32个字节,一个中文字模
      }
   return 0;
}

//按地址从FLASH(EEPROM)中读一个字节
Uint8 FlashRead(Uint16 offset)
{
      Uint8 dat;
      A17=a17;
      A16=a16;
      dat=XBYTE;
      return dat;
}


//连续移位
void shiftBuff()
{
      unsigned char i;
      for(i=0;i<96;i++)
      {
                Table_BUFF=Table_BUFF;
                //Table_BUFF=Table_BUFF;
      }
      GetGBCode_from_EEPROM(Table_BUFF+96,str+pStr);
      pStr=pStr+2;
      if(pStr>=strlen(str)) pStr=0;
}


//向上移动
void shiftUpBuff()
{
      unsigned char i,j;
      
      shiftTime++;
      for(i=0;i<4;i++)
      for(j=0;j<16-shiftTime;j++)
      {
                Table_BUFF=Table_BUFF;
                Table_BUFF=Table_BUFF;
      }
      for(i=0;i<4;i++)
      for(j=16-shiftTime;j<16;j++)
      {
                        Table_BUFF=0x00;
                        Table_BUFF=0x00;
      }

      if(shiftTime>=16){
                shiftTime=0;
                prepareBuff();
      }
      
      
}




//准备显示的buff,4个字的字模
void prepareBuff()
{
      unsigned char i;

      for(i=0;i<4;i++)
      {
                        GetGBCode_from_EEPROM(Table_BUFF+i*32,str+pStr);
                        pStr=pStr+2;    //pStr指向str中下一个要字符的位置,中文占2个字节,所以加2.
      }
      if(pStr>=strlen(str)) pStr=0;
}


void main(){
SST29EE020_CE=0;      //SST29EE020一直有效
      prepareBuff();
      while(1){
               
                //prepareBuff();
               
                Matrix16x16(4);
                //shiftBuff();
                shiftUpBuff();
                //delayms(100);
      }
}

三、总结


加了很多_nop()_,可以使屏亮一些,不加直接关74HC154,会非常暗。(因为我都是下班晚上调的,所以调暗点还看得清)
      如果str中出现字库中没有的字会导致连续几个字都显示乱码(不一定是字库没有,比如“三”,会显示为“热”,反正就是不对,之前出现的问题又以新的形式出现)。现在直接用内码基本可以避免这个问题。但现在用的函数好像还有算法问题,部分字会重复。还怀疑字库是不是GB2312,因为虽然读取字库的offset用的是GB2312,但是内码用的是GBK,当然不排除生成内码的网站把这两种编码搞混了。
      str中不要出现“。”,出现句号就会重复前面的字,所以我把所有的标点符号都去掉了。
      增加了一个shitBuff(),函数可以1个字1个字向右移。是向右移不是向左移,因为字模595、点阵屏在物理上决定了右移更容易实现。而且所有的字都是从右向左读。



页: [1]
查看完整版本: STC89C52RC 驱动16x64LED点阵模块驱动记录(四)SST29EE020 GB2312汉字库读取