[开源硬件] M453通过上位机下载GBK字库到AT45DB321成功

[复制链接]
208|5
 楼主 | 2018-6-21 13:42 | 显示全部楼层 |阅读模式
本帖最后由 springvirus 于 2018-6-21 14:09 编辑

为NUC505读取字库并显示到19264做准备,尝试将字库下载到Flash AT45DB321中,本次用了M453,很顺手
上位机用了之前的编程器应用软件,稍作修改





做修改后的上位机软件


做字库的相关东东
测试用字库ziku_test.bin,字数只有前面的32个字
ziku.bin是正式的GBK字库


本帖子中包含更多资源

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

x
 楼主 | 2018-6-21 13:43 | 显示全部楼层
#ifndef __AT45DB321_H__
#define __AT45DB321_H__

#include "M451Series.h"



#define AT45_PORT PD

#define AT45_CS_BIT  BIT2
#define AT45_SCK_BIT BIT3
#define AT45_SO_BIT  BIT4
#define AT45_SI_BIT  BIT5



#define AT45_CS  PD2

#define AT45_SCK PD3

#define AT45_SO  PD4
//从AT45读出数据

#define AT45_SI  PD5
//数据写入AT45



#define DATAFLASH_PAGESIZE        528
#define DATAFLASH_PAGE_MASK        0x1FFF
#define DATAFLASH_BASE_MASK        0x3FF

#define FLASH_ADDR(P, B)        (((P & DATAFLASH_PAGE_MASK) << 10) | (B & DATAFLASH_BASE_MASK))
#define FLASH_PAGE_BY_ADDR(A)        (((A) >> 10) & DATAFLASH_PAGE_MASK)
#define FLASH_BASE_BY_ADDR(A)        ((A) & DATAFLASH_BASE_MASK)




#define OPCODE_READ_ID 0x9F

#define OPCODE_READ_STATUS 0xD7


#define OPCODE_READ 0x03

#define OPCODE_WRITE 0x82
// Main Memory Page Program Through Buffer 1
// 注意一次写512字节


#define OPCODE_ERASE 0x81


//GBK区位码 第1字节基地址是0x81 第2字节基地址是0x40
//#define GBK_FIRST_BASE  0x81
//#define GBK_SECOND_BASE 0x40


#define PAGE_GROUP_BASE 0x81
#define PAGE_GROUP_INTERNAL_BASE 0x40
#define PAGE_INTERNAL_BASE 0x00


//每个区位码的首字节下有12行汉字 每行16个汉字
//每页正好存放16个汉字,32*16 = 512字节
//所以每个页组是12页
#define PAGE_GROUP_OFFSET 12

//页内的偏移量是32,即一个汉字的数据量
#define PAGE_INTERNAL_OFFSET 32



union sv_32 {

        unsigned int Val;

        unsigned char c[4];

};


union sv_16 {

        unsigned int Val;

        unsigned char c[2];

};




unsigned int AT45DB321_Read_ID(void);
unsigned char AT45DB321_Read_Status(void);

unsigned char AT45DB321_Page_Read(unsigned int page, unsigned int offset,
        unsigned char *rbuf, unsigned int rlen);

unsigned char AT45DB321_Page_Write(unsigned int page, unsigned int offset,
        unsigned char *wbuf, unsigned int wlen);


unsigned char AT45DB321_Page_Erase(unsigned int page);



void AT45DB321_Get_Zimo_With_GBK(unsigned char *gbk, unsigned char *zimo);




#endif

 楼主 | 2018-6-21 13:44 | 显示全部楼层
#include "M451Series.h"

#include "AT45DB321.h"


unsigned char DATA_BUF;

void delay(void)
{
        unsigned int i = 0;


        for(i=0;i<10;i++)
        {
                __nop();
               
        }

}


unsigned char SpiRead(void)
{

        unsigned char i;
       

        //先读到最高位,最后是最低位
        for(i=0;i<8;i++)
        {
                DATA_BUF = DATA_BUF << 1;

                AT45_SCK = 1;

                if(AT45_SO)
                {
                        DATA_BUF += 1;
                }
                else
                {
                        DATA_BUF += 0;
                }

                AT45_SCK = 0;

        }


        return DATA_BUF;
       

}


void SpiWrite(unsigned char wdata)
{

        unsigned char i;

        DATA_BUF = wdata;
       
        AT45_SCK = 0;


        for(i=0;i<8;i++)
        {
                //先写最高位,最后写最低位
                if(DATA_BUF >> 7)
                {
                        AT45_SI = 1;
                }
                else
                {
                        AT45_SI = 0;
                }
               
       
                AT45_SCK = 1;
       
                DATA_BUF = DATA_BUF << 1;

                AT45_SCK = 0;
       

        }



}






unsigned int AT45DB321_Read_ID(void)
//返回4字节的ID
//see datasheet page 26
/*
byte 1: Manufacturer ID  1FH = ATMEL

byte 2:
Family Code     Density Code
   001                           00111
001 = DataFlash
00111 = 32M-bit = 4MB

byte 3:
MLC code        Product Version Code
  000                           00001

byte 4: Byte Count


读取ID已成功  2018.6.20

----------------------------------------

M453 AT45DB321 Programmer Lower V1.0

SVEBRS  2018.6.19

CPU @ 72000000 Hz

----------------------------------------

id[0] = 0x1f  -> ATMEL

id[1] = 0x27  -> DataFlash  32Mb = 4MB

id[2] = 0x01

id[3] = 0x01



*/
{

        unsigned int read_id = 0;

        union sv_32 temp_union_32;

        temp_union_32.Val = 0;
       
        AT45_CS = 0;
       

        SpiWrite(OPCODE_READ_ID);


        temp_union_32.c[0] = SpiRead();
        temp_union_32.c[1] = SpiRead();
        temp_union_32.c[2] = SpiRead();
        temp_union_32.c[3] = SpiRead();
       


        read_id = temp_union_32.Val;

        AT45_CS = 1;


        return read_id;

       

}






unsigned char AT45DB321_Read_Status(void)
//see datasheet page 23
/*
已读出状态


----------------------------------------

M453 AT45DB321 Programmer Lower V1.0

SVEBRS  2018.6.19

CPU @ 72000000 Hz

----------------------------------------

id[0] = 0x1f

id[1] = 0x27

id[2] = 0x01

id[3] = 0x01

status = 0xb4  1011 0100

bit7                 bit6 bit5 bit4  bit3 bit2   bit1    bit0
RDY/BUSY(/)  COMP  1    1      0   1    PROTECT  PAGE SIZE

bit7: 1-free  0-busy
bit1: 1-sector protection enabled   0-sector protection disabled
bit0: 1-page size is 512B   0-page size is 528B

*/
{

        unsigned char read_status = 0;
       
        AT45_CS = 0;


        SpiWrite(OPCODE_READ_STATUS);


        read_status = SpiRead();


        AT45_CS = 1;


        return read_status;

       

}




unsigned char AT45DB321_Is_Busy(void)
{       
        unsigned char status = 0;
       
        status = AT45DB321_Read_Status();

        if((status & (1<<7)) >> 7 == 0x01)
        //BUSY为低电平有效
        //not busy
        {
                return 0;
        }
        else
        //busy
        {
                return 1;
        }


}


void AT45DB321_Wait_Busy(void)
{
       
        while(AT45DB321_Is_Busy());
       
}


/*

page: 0-8191
页编码

offset: 0-527
页内偏移


rbuf: 读出的数据

rlen: 读出的数据长度


*/
unsigned char AT45DB321_Page_Read(unsigned int page, unsigned int offset,
        unsigned char *rbuf, unsigned int rlen)
//注意规划字库存储时,每页就用512,容易计算
//读取页成功 2018.6.20
//读取页内偏移成功 2018.6.20 15:43
{
       
        unsigned int i;
       
        unsigned int addr = FLASH_ADDR(page, offset);

        unsigned char status = 0;


        AT45DB321_Wait_Busy();
       

        AT45_CS = 0;


        SpiWrite(OPCODE_READ);
       
        SpiWrite(addr >> 16);
        SpiWrite(addr >> 8);
        SpiWrite(addr >> 0);

        for(i=0;i<rlen;i++)
        {
                rbuf = SpiRead();
        }


        AT45_CS = 1;


        return 0;


}


unsigned char AT45DB321_Page_Write(unsigned int page, unsigned int offset,
        unsigned char *wbuf, unsigned int wlen)
//注意规划字库存储时,每页就用512,容易计算
{
       
        unsigned int i;
       
        unsigned int addr = FLASH_ADDR(page, offset);


        AT45DB321_Wait_Busy();

        AT45_CS = 0;

        SpiWrite(OPCODE_WRITE);
       
        SpiWrite(addr >> 16);
        SpiWrite(addr >> 8);
        SpiWrite(addr >> 0);

        for(i=0;i<wlen;i++)
        {
                SpiWrite(wbuf);
        }


        AT45_CS = 1;


        return 0;


}


unsigned char AT45DB321_Page_Erase(unsigned int page)
//注意规划字库存储时,每页就用512,容易计算
//页擦除成功 2018.6.20
/*


----------------------------------------

AT45DB321 read id :

id[0] = 0x1f

id[1] = 0x27

id[2] = 0x01

id[3] = 0x01

----------------------------------------

AT45DB321 read status :

status = 0xb4

before erase.

page: 0



read page->[0]aa [1]aa [2]aa [3]aa [4]aa [5]aa [6]aa [7]aa [8]aa [9]aa [10]45 [11]e2 [12]2b [13]02 [14]16 [15]03 [16]1b [17]4b [18]10 [19]9a [20]80 [21]c2 [22]69 [23]d1 [24]88 [25]a0 [26]88 [27]d7 [28]20 [29]58 [30]01 [31]2e [32]62 [33]46 [34]77 [35]02 [36]32 [37]ac [38]95 [39]15 [40]01 [41]a0 [42]60 [43]98 [44]c1 [45]52 [46]41 [47]40 [48]22 [49]59 [50]01 [51]02 [52]6a [53]fd [54]b0 [55]21 [56]dc [57]01 [58]3e [59]e8 [60]06 [61]8c [62]d5 [63]89 [64]a2 [65]f8 [66]c0 [67]87 [68]11 [69]50 [70]00 [71]6e [72]98 [73]82 [74]10 [75]22 [76]55 [77]8a [78]b3 [79]01 [80]6a [81]09 [82]2e [83]cc [84]2a [85]11 [86]2c [87]18 [88]35 [89]28 [90]bf [91]74 [92]a1 [93]88 [94]11 [95]25 [96]c7 [97]d4 [98]88 [99]ea [100]4c [101]d7 [102]81 [103]82 [104]5c [105]7b [106]35 [107]25 [108]a2 [109]ac [110]00 [111]e7 [112]d0 [113]90 [114]52 [115]1b [116]19 [117]73 [118]3f [119]3a [120]21 [121]7a [122]a1 [123]64 [124]00 [125]2a [126]c4 [127]4d [128]d9 [129]21 [130]4c [131]9a [132]6c [133]75 [134]43 [135]82 [136]1a [137]1b [138]03 [139]70 [140]db [141]08 [142]a5 [143]50 [144]d0 [145]8c [146]d0 [147]8d [148]82 [149]f0 [150]20 [151]bb [152]0d [153]e0 [154]29 [155]76 [156]71 [157]03 [158]90 [159]85 [160]39 [161]91 [162]04 [163]88 [164]8d [165]c2 [166]65 [167]58 [168]e6 [169]4f [170]8a [171]5f [172]14 [173]3a [174]1b [175]20 [176]d9 [177]b0 [178]be [179]b8 [180]24 [181]84 [182]08 [183]c1 [184]13 [185]05 [186]e8 [187]8f [188]ee [189]ec [190]83 [191]26 [192]f0 [193]58 [194]15 [195]61 [196]11 [197]17 [198]f4 [199]b9



after erase.

page: 0



read page->[0]ff [1]ff [2]ff [3]ff [4]ff [5]ff [6]ff [7]ff [8]ff [9]ff [10]ff [11]ff [12]ff [13]ff [14]ff [15]ff [16]ff [17]ff [18]ff [19]ff [20]ff [21]ff [22]ff [23]ff [24]ff [25]ff [26]ff [27]ff [28]ff [29]ff [30]ff [31]ff [32]ff [33]ff [34]ff [35]ff [36]ff [37]ff [38]ff [39]ff [40]ff [41]ff [42]ff [43]ff [44]ff [45]ff [46]ff [47]ff [48]ff [49]ff [50]ff [51]ff [52]ff [53]ff [54]ff [55]ff [56]ff [57]ff [58]ff [59]ff [60]ff [61]ff [62]ff [63]ff [64]ff [65]ff [66]ff [67]ff [68]ff [69]ff [70]ff [71]ff [72]ff [73]ff [74]ff [75]ff [76]ff [77]ff [78]ff [79]ff [80]ff [81]ff [82]ff [83]ff [84]ff [85]ff [86]ff [87]ff [88]ff [89]ff [90]ff [91]ff [92]ff [93]ff [94]ff [95]ff [96]ff [97]ff [98]ff [99]ff [100]ff [101]ff [102]ff [103]ff [104]ff [105]ff [106]ff [107]ff [108]ff [109]ff [110]ff [111]ff [112]ff [113]ff [114]ff [115]ff [116]ff [117]ff [118]ff [119]ff [120]ff [121]ff [122]ff [123]ff [124]ff [125]ff [126]ff [127]ff [128]ff [129]ff [130]ff [131]ff [132]ff [133]ff [134]ff [135]ff [136]ff [137]ff [138]ff [139]ff [140]ff [141]ff [142]ff [143]ff [144]ff [145]ff [146]ff [147]ff [148]ff [149]ff [150]ff [151]ff [152]ff [153]ff [154]ff [155]ff [156]ff [157]ff [158]ff [159]ff [160]ff [161]ff [162]ff [163]ff [164]ff [165]ff [166]ff [167]ff [168]ff [169]ff [170]ff [171]ff [172]ff [173]ff [174]ff [175]ff [176]ff [177]ff [178]ff [179]ff [180]ff [181]ff [182]ff [183]ff [184]ff [185]ff [186]ff [187]ff [188]ff [189]ff [190]ff [191]ff [192]ff [193]ff [194]ff [195]ff [196]ff [197]ff [198]ff [199]ff



*/
{
       
        unsigned int i;
       
        unsigned int addr = (page & DATAFLASH_PAGE_MASK);



        AT45DB321_Wait_Busy();


        AT45_CS = 0;
       

        SpiWrite(OPCODE_ERASE);
       
        SpiWrite(addr >> 6);
        SpiWrite(addr << 2);
        SpiWrite(0x00);


        AT45_CS = 1;


        return 0;


}


/*
gbk是入口参数,最少为2个
zimo是出口参数,最少为32个

已测试 "瑞" GBK码

u8 gbk[10] = {"瑞"};


gbk->[0]c8 [1]f0 [2]00 [3]00 [4]00 [5]00 [6]00 [7]00 [8]00 [9]00


zimo->[0]00 [1]00 [2]00 [3]00 [4]00 [5]00 [6]00 [7]00 [8]00 [9]00 [10]00 [11]00 [12]00 [13]00 [14]00 [15]00 [16]00 [17]00 [18]00 [19]00 [20]00 [21]00 [22]00 [23]00 [24]00 [25]00 [26]00 [27]00 [28]00 [29]00 [30]00 [31]00


test[0] = 71  -> page_group

test[1] = 11  -> page_group_internal_offset

test[2] = 863 -> which_page

test[3] = 0   ->         page_internal_offset


*/
void AT45DB321_Get_Zimo_With_GBK(unsigned char *gbk, unsigned char *zimo)
{

        unsigned int page_group, page_group_internal_offset, which_page;
        unsigned int page_internal_offset;
       

        if((gbk[0] >= PAGE_GROUP_BASE) && (gbk[1] >= PAGE_GROUP_INTERNAL_BASE))
        //区位码合法再读取
        {

                page_group = (gbk[0] - PAGE_GROUP_BASE);
                //页组号 0-125
                //0xFE - 0x81 + 1 = 126
               
                page_group_internal_offset = ((gbk[1] & 0xF0) -  PAGE_GROUP_INTERNAL_BASE) >> 4;
                //页组内的偏移
               

                which_page = (page_group * PAGE_GROUP_OFFSET) + page_group_internal_offset;
                //具体的页号


                page_internal_offset = ((gbk[1] & 0x0F) - PAGE_INTERNAL_BASE) * PAGE_INTERNAL_OFFSET;
                //页内的字节偏移处


                AT45DB321_Page_Read(which_page, page_internal_offset, zimo, PAGE_INTERNAL_OFFSET);


       
        }

       
       

}

 楼主 | 2018-6-21 14:12 | 显示全部楼层
只给出底层部分,上层应用根据协议灵活制定
 楼主 | 2018-6-22 11:33 | 显示全部楼层
本帖最后由 springvirus 于 2018-6-22 11:38 编辑

对上位机的接收区和发送区进行了精简,超过200行进行清理,下载速度明显快了很多,对正式字库进行了下载,耗时90分钟左右
BIN文件总字节数744144,每包发送16个数据字节,共下发48384个数据包  总包数 0xBD 0x00  包索引 0x00 0x00 ~ 0xBC 0xFF

并进行了抽样检查,字库存储正常,为NUC505的字库读取打下了基础



本帖子中包含更多资源

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

x
| 2018-6-28 08:07 | 显示全部楼层
烧录字库厉害了,学习下。
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

关闭

热门推荐上一条 /6 下一条

分享 快速回复 返回顶部 返回列表