返回列表 发新帖我要提问本帖赏金: 10.00元(功能说明)

[LPC] 基于S08P-Lite开发板的字库构建及使用

[复制链接]
 楼主| jinglixixi 发表于 2021-3-10 12:32 | 显示全部楼层 |阅读模式
<
本帖最后由 jinglixixi 于 2021-3-10 12:44 编辑

#申请原创#
在S08P-Lite开发板上,配置有一个4MB的W25Q32存储器,可作为字库或图库来使用,其接口电路如图1所示。
                              
图1 W25Q32接口电路


那该如何构建字库和图库呢?
方法主要有2个,一个是用数组做缓冲的中转存储;另一种是使用串行通讯来把文件中的传送给MCU来进行转存。
为了便于说明,这里以数组的形式来进行转储。
具体处理过程如下:
1. 首先将字库的内容存入数组,其形式为:
unsigned  charF8X16[]=
{         
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//sp0
         0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//!1
         0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//"2
         0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//#3
         0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$4
          ...  
          0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//|92
         0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//}93
         0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~94
}
即每个字符占用16个字节,共有95个字符。


2. 编组分批转存(原因说明: 使用OLED屏分页显示(按键控制或延时处理)16*2=32   96/32=3屏)
S08P-Lite开发板所使用的MCU为MC9S08PT60,其闪存容量为60KB。
若能把该数组的全部字库存下并进行编译下载,则可以一次性完成转储。
但本人所用的CW似乎有些问题,一旦代码得到16KB,就会在下载后无法运行,故只能分为3次将将字库的内容转存到W25Q32中,即每次数组中的字符数为32个。
分批转存的程序为:
  1. void FlashW25Q32_CREAT(void)
  2. {
  3.    uint8_ti,j,k;
  4.    uint8_t deviceID;
  5.    uint8_treturnResult;
  6.    uint16_ttestResult = 0;
  7.    printf("FlashW25Q32 CREAT: BEGINS\n");
  8.    deviceID = flash_read_deviceid();
  9.    printf("FlashW25Q32 CREAT: read device ID is 0x%x\n",deviceID);
  10.    printf("FlashW25Q32 CREAT: erase flash sector 0\n");  // 4KB=1sector
  11.    returnResult = flash_sector_erase(0);
  12.    for(j=0; j<32; j++)
  13.    {
  14. for (i=0; i<16; i++)
  15.      {
  16.          u8FlashReadBuffer = 0;
  17.          u8FlashWriteBuffer = F8X16[i+j*16];  // 数组转存
  18.      }
  19.      for (i=0; i<16; i++)
  20.      {
  21.         printf(" 0x%x", u8FlashWriteBuffer);  // 写入内容显示验证
  22.      }
  23.      printf("\n");
  24.    returnResult = flash_write_sector(512+j*16, u8FlashWriteBuffer, 16);
  25.    returnResult = flash_read_data(512+j*16, u8FlashReadBuffer, 16);
  26.    for(i=0; i<16; i++)
  27.    {
  28.         printf(" 0x%x", u8FlashReadBuffer);  // 读取内容显示验证
  29.    }
  30.    printf("\n");
  31. }
  32.    printf("FlashW25Q32 CREAT: PASSED\n");
  33.    printf("\n");
  34.    return;
  35. }

由于W25Q32的一个扇区为4KB,而字符库的大小为96*16=1536个字节,所以一个扇区完全可以存放下,因此除了第一次相应进行擦除外,其他2次需将擦除处理的引脚屏蔽。
编译下载后,其执行效果如图2和图3所示,其中单行数据为写入内容,双行数据为读取内容,经核实读写一致。

图2 执行效果1


图3 执行效果2


3.整体读取验证
对于分批转存来说,需要进行一次整体读取验证,若是能一次性完成转存则无需该处理。
整体读取验证的函数为:
  1. void FlashW25Q32_Test(void)
  2. {
  3.    uint8_ti,j,k;
  4.    uint8_tdeviceID;
  5.    uint8_treturnResult;
  6.    uint16_ttestResult = 0;
  7.    printf("FlashW25Q32 test: BEGINS\n");
  8.    for(k=0;k<3; k++)
  9.    {
  10.    for(j=0; j<32; j++)
  11.    {
  12.    for(i=0; i<16; i++)
  13.    {
  14.         printf(" 0x%x", u8FlashReadBuffer);
  15.    }
  16.    printf("\n");
  17.    }
  18.    printf("FlashW25Q32 test: PASSED\n");
  19.    printf("\n");
  20.    return;
  21. }

在执行后,其运行效果如图4和图5所示。

图4 执行效果3


图5 执行效果4
(注:为了便于处理,最后一行数据为无效数据)

4.以OLED屏来显示验证
我们建立字库的目的是为了OLED屏的显示,为此需要把读取数组字库的程序转换为读取硬字库的函数。
以OLED屏来进行显示验证的函数为:
  1. void FlashW25Q32_oled(void)
  2. {
  3.     uint8_t i,j,k,x,y;
  4.    uint8_treturnResult;
  5.    for(k=0;k<3; k++)
  6.    {
  7.          x=0;
  8.          y=0;
  9.        for (j=0; j<32; j++)
  10.          {
  11.        returnResult =flash_read_data(k*512+j*16, FlashReadBuffer, 16);
  12.        OLED_ShowCharp(x,y,FlashReadBuffer,16);
  13.         if(j==15)
  14.         {
  15.          y=2;
  16.          x=0;
  17.         }
  18.         else
  19.          x=x+8;  
  20.         }
  21.        DelayMS(2000);
  22.    }
  23. }

该函数的功能是从字库中依次读取字模,然后在分屏显示在OLED屏上。
(注:OLED屏每屏可显示的字符数为32,96/32=3,故字符库的内容需用3屏来显示出来。)
读取字库来显示的函数为:
  1. void OLED_ShowCharp(uint8_t x,uint8_ty,uint8_t* chr,uint8_tChar_Size)
  2. {
  3.     unsignedchari=0;
  4.     unsignedchar*c;
  5.     c=chr;
  6.     if(x>Max_Column-1)
  7.     {
  8.      x=0;
  9.      y=y+2;
  10.     }
  11.     if(Char_Size==16)
  12.     {
  13.             OLED_Set_Pos(x,y);
  14.             for(i=0;i<8;i++)
  15.            OLED_WR_Byte(FlashReadBuffer,OLED_DATA);
  16.             OLED_Set_Pos(x,y+1);
  17.             for(i=0;i<8;i++)
  18.            OLED_WR_Byte(FlashReadBuffer[i+8],OLED_DATA);
  19.      }
  20. }

分屏显示的验证效果如图6至图8所示,经审核处理正确。

图6 分屏显示效果1


图7 分屏显示效果2


图8 分屏显示效果3

5. 读字库进行显示
在分屏显示的基础上,我们再将程序改造成符合字符串显示的函数。
字符显示函数为:
  1. void OLED_ShowCharv(uint8_t x,uint8_ty,uint8_tchr,uint8_tChar_Size)
  2. {
  3.     unsignedchari=0,c;
  4.     unsignedintp;
  5.     c=chr-' ';
  6.     p=c*16;
  7.      flash_read_data(p, FlashReadBuffer, 16);
  8.      if(x>Max_Column-1)
  9.     {
  10.      x=0;
  11.      y=y+2;
  12.      }
  13.     if(Char_Size==16)
  14.     {
  15.             OLED_Set_Pos(x,y);
  16.             for(i=0;i<8;i++)
  17.            OLED_WR_Byte(FlashReadBuffer,OLED_DATA);
  18.             OLED_Set_Pos(x,y+1);
  19.             for(i=0;i<8;i++)
  20.             OLED_WR_Byte(FlashReadBuffer[i+8],OLED_DATA);
  21.      }
  22. }

字符串显示函数为:
  1. void OLED_ShowStringV(uint8_t x,uint8_ty,uint8_t*chr,uint8_tChar_Size)
  2. {
  3.    unsignedcharj=0;
  4.    while(chr[j]!='\0')
  5.    {      
  6.             OLED_ShowCharv(x,y,chr[j],Char_Size);
  7.             x+=8;
  8.             if(x>120)
  9.             {
  10.              x=0;
  11.                 y+=2;
  12.             }
  13.             j++;
  14.    }
  15. }


实现演示效果的主程序为:
  1. void main(void)
  2. {
  3.    Sys_Init();
  4.    EnableInterrupts;
  5.    MTIM1_Init();
  6.    LED_Init();
  7.    LED_Test();
  8.     PORT_PTAOE_PTAOE2= 1;     //PTA2
  9.     PORT_PTAOE_PTAOE3= 1;     //PTA3
  10.     FlashW25Q32_Init();
  11.    OLED_Init();
  12.    OLED_Clear();
  13.     OLED_ShowStringV(0,0,"MC9S08PT60",16);
  14.     OLED_ShowStringV(0,2,"0.91' OLED",16);
  15.    while(1);
  16. }


经编译下载,其运行效果如图9所示。

图9 读取字库的演示效果

有了以上的基础,我们还可以构建中文字库及图库等。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

打赏榜单

21小跑堂 打赏了 10.00 元 2021-03-10
理由:恭喜通过原创文章审核!请多多加油哦!

gyh974 发表于 2021-3-12 10:46 | 显示全部楼层
s
有完整项目文件就好了,不用看得那么辛苦
 楼主| jinglixixi 发表于 2021-3-12 11:28 | 显示全部楼层
s
本帖最后由 jinglixixi 于 2021-3-12 11:30 编辑
gyh974 发表于 2021-3-12 10:46
有完整项目文件就好了,不用看得那么辛苦

涉及的中间过程比较多,就发一个最后面的吧。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

518

主题

2935

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部