STM32制作FLASH字库
⾃⼰做了⼀块板⼦,FLASH(W25Qxx)都是空的,⾃⼰写了段简洁的代码⽤FAT从SD卡写到FLASH中。
呢?FATFS太⼤了!你要是每次显⽰⼏个汉字就去移植,再去编译下载,那可真慢。。所以后者直接移植⼀个FLASH驱动就可以了。代码不多,⽤到什么写什么嘛,实现⼩功能就⼩代码呗。
下⾯贴代码了,⼤概讲⼀下
地址定义
//W25Q128! -> 总空间:16M
#define SPI_FONT_START 12 //从12M开始写⼊,其余是⽂件系统
#define FONT16x16_SPI_ADDR (SPI_FONT_START*1024/16 * 4096) //16x16字库
#define FONT16x16_SPI_SIZE 282752 //使⽤空间Byte
#define FONT16x16_SPI_TOTAL_SIZE (280*1024) //占⽤空间
#define FONT24x24_SPI_ADDR (FONT16x16_SPI_ADDR+FONT16x16_SPI_TOTAL_SIZE)
#define FONT24x24_SPI_SIZE 636192 //使⽤空间Byte
#define FONT24x24_SPI_TOTAL_SIZE (624*1024) //占⽤空间
#define FONT32x32_SPI_ADDR (FONT24x24_SPI_ADDR+FONT24x24_SPI_TOTAL_SIZE)
#define FONT32x32_SPI_SIZE 1131008 //使⽤空间Byte
#define FONT32x32_SPI_TOTAL_SIZE (1108*1024) //占⽤空间
特别注意⼀点,⽂件空间和占⽤空间不⼀样,和Window⼀样,⼀个扇区4KB,哪怕超了1bit也要占⽤⼀个扇区。
这⾥根据⾃⼰需要定义要存的位置。但是⾃⼰要计算好空间够不够。
实现代码
代码由于是我⾃⼰写的,所以我从简,我也挺烦⼀⼤串复杂冗余的代码。
u8 exchangeBuf[4096]__attribute__((at(0XC0000000)));
FRESULT f_res;
FIL fil;
UINT spi_btr;
//ph: 16x16字库⽂件路径绝对路径!
void Update_SPI_FONT16x16(const TCHAR* ph)
{
u16 NumtoRead =0;
u16 ByteCnt =0;
u16 spi_offset =0;
u16 Data_Reserve =0;
f_res =f_open(&fil,ph,FA_OPEN_EXISTING|FA_READ);
NumtoRead = FONT16x16_SPI_TOTAL_SIZE/4096-1;//完整扇区读写
Data_Reserve = FONT16x16_SPI_SIZE -(FONT16x16_SPI_TOTAL_SIZE -4096);//剩余扇区读写if(f_res == FR_OK)
{
printf("\r\n打开⽂件成功");
printf("\r\n开始写⼊SPI FLASH");
while(NumtoRead !=0)
{
f_res =f_lseek(&fil,4096*spi_offset);
f_res =f_read(&fil,exchangeBuf,4096,&spi_btr);
if(f_res == FR_OK)
{
SPI_FLASH_BufferWrite(exchangeBuf,FONT16x16_SPI_ADDR+4096*spi_offset,4096);
ByteCnt+=4;
spi_offset++;
printf("\r\n已写⼊ %d 个字节",ByteCnt);
if(f_res == FR_OK)
NumtoRead--;
else
{
printf("\r\nSD卡⽂件偏移失败!!");
return;
}
}
else
{
printf("\r\n读取失败退出写⼊!!");
return;
}
}
f_res =f_read(&fil,exchangeBuf,Data_Reserve,&spi_btr);//剩余数据写⼊
if(f_res == FR_OK)
{
SPI_FLASH_BufferWrite(exchangeBuf,FONT16x16_SPI_ADDR+4096*spi_offset,Data_Reserve); printf("\r\n已经完成SPI FLASH 16x16的读写!");
f_res =f_close(&fil);
if(f_res == FR_OK)printf("\r\n"),printf("\r\n成功完成读写过程!");
}
else
{
printf("\r\n写⼊数据不完整!!需要重新写⼊");
}
}
else
{
printf("\r\n打开⽂件失败");
}
}
我从SDRAM开了⽚4KB空间给缓冲区(因为FLASH⼀个扇区4KB)
制作flash什么?要SDRAM?
慢着!别⾛这是我图快。。不⽤SDRAM完全可以的。
你只要从STM32内存⾥分配256个也可以。只是需要多写⼏次罢了,记得地址每次要偏移256B!但是有SRAM/SDRAM的朋友就不会觉得那么⿇烦了(也就是代码⿇烦)。。
这是16x16的字库,⽂件⽐较⼩。对于24x24、32x32⼀样的代码,把宏改⼀下。
字库使⽤
对于没接触过字库⽂件的的确很懵,我也是总觉得那玩意前⾯有个⽂件头、信息头啥的,还要加偏移。。但是字库这玩意的确没有,按GBK 编码寻址就⾏了,这⾥⼤概说⼀下,毕竟不是主题
u32 Get_GBK_OffSet_Addr(const u16 Hz)
{
u8 CodeH =0,CodeL=0;
u32 Addr;
CodeH =(u8)(Hz >>8);
CodeL =(u8)(Hz &0x00FF);
Addr =(((CodeH -0xA0-1)*94)+(CodeL-0xA0-1))*(Font_Size * Font_Size /8);
return Addr;
}
这是按GB2312的编码来的,0XA0就是ASCII最后⼀个码,其他算法没去具体了解。按这个计算公式
你要调⽤?
Get_GBK_OffSet_Addr('汉');
得到偏移地址代⼊SPIFLASH字库基地址就可以显⽰了
本⼈学习笔记,热爱分享
<;完>
发布评论