本帖最后由 DebugLab 于 2024-8-19 12:38 编辑
用32G12K128 读取字库芯片GT30L32S4W
一、字库信息: 1、字库标准:GB2312国标汉字,ASCII字符。 2、点阵排列方式:字节横置横排 3、驱动方式:SPI 二、OLED信息 1、SSD1326 0.96寸12864 2、IIC驱动 三、字库电路图: 四、SPI驱动 5、程序: 程序分三部分:1、SPI驱动 2、字库数据处理 3、oled显示 1、SPI驱动部分: 1、 SPI驱动部分: voidSPI_Init(void) { P_SW3 &= 0xCF; //1100 1111 P_SW3 |= 0x30; //0011 0000 //功能引脚切换 S2CON = 0x10; //00010000 允许串口接收数据 USART2CR1 = 0x10; USART2CR4 = 0x00; USART2CR1 |= 0x08; } /************************************************************************/ voidSPI_WriteByte(unsigned char Byte) { S2TI=0; S2BUF = Byte; while(!S2TI) ;
}
/************************************************************************/ unsigned charSPI_ReadByte(void) { S2TI=0; S2BUF = 0xFF; while(!S2TI) ; return (S2BUF);
} 2、 字库数据处理
/******************************************************************************** *@brief 发送字符地址 *@param Addr 地址 *@retval none *******************************************************************************/ void GT30L32S4W_Address_2(long Addr) { SPI_WriteByte(0x03); //一般读取 /*发送擦除扇区地址的高位*/ SPI_WriteByte((unsignedchar)((Addr & 0xFF0000) >> 16)); /*发送擦除扇区地址的中位 */ SPI_WriteByte((unsignedchar)((Addr & 0xFF00) >> 8)); /*发送擦除扇区地址的低位 */ SPI_WriteByte((unsignedchar)(Addr & 0xFF)); } /** *@brief 获取该汉字字符在15x16点GB2312标准库中的起始位置 *@note *@param GB2312Code *@retval None *@date 2021/4 */ static long GT30L32S4W_Get_Addr_GB2312_15x16(unsignedchar *GB2312Code) { unsignedchar MSB,LSB ; // unsignedlong Base_Add ; // Base_Add= GT30L32S4W_BaseADD_15x16 ; MSB= *GB2312Code; LSB= *(GB2312Code + 1); if((MSB>= 0xA1) && (MSB <= 0xA9) && (LSB >= 0xA1)) { return ((MSB - 0xA1) * 94 + (LSB - 0xA1)) * 32 +Base_Add ;
} elseif((MSB >= 0xB0) && (MSB <= 0xF7) && (LSB >= 0xA1)) { return ((MSB - 0xB0) * 94 + ((LSB-0xA1) + 846)) * 32+ Base_Add ; } return-1; } /** *@brief 接收字符数据 *@note *@param addr bytesArray接收到的字符 numOfBytes接受字符的长度 *@retval None *@date 2021/1 */ void GT30L32S4W_Read_FontBytes(long addr,unsigned char *bytesArray, unsigned char numOfBytes) { unsignedchar i;
SPI_CS= 0; GT30L32S4W_Address_2(addr); for(i = 0; i < numOfBytes; i++) { bytesArray= SPI_ReadByte(); } SPI_CS= 1; }
3、oled显示 此处显示重点是:字库芯片读取方式是:点阵排列方式:字节横置横排 0101 0101 0202 0202 而OLED显示方式是竖置横排。0 0 1 2 这就需要将获得的字库数据进行处理。 处理程序简陋,水平不够 /** * @brief ASCII_15x16 将横置横排转换为竖置竖排。 * @param *szhp 竖置横排字符数据。 * @param *hzhp 横置横排字符数据。 * @retval None. */ void GB2312_15x16_HengZhiHengPai_to_ShuZhiHengPai(unsigned char *szhp, unsigned char *hzhp) { unsigned char i, j; //扫描横置横排的byte0-byte7到竖置横排的byte0-byte14 //i:表示,横置横排 i组 //j:表示,竖置横排 j组 for (j = 0; j <= 7; j ++ ) //竖置横排第j组 { for ( i = 0; i <= 14; i += 2 ) //将横置横排的(byte0、2、4、6、8、10、12、14)的第j位取出放置到竖置横排的Byte0-7 { if (*(hzhp + i) & (0x01 << (7-j))) //取 横置横排第i行的第j位,如果为1执行此句,否则执行else { *(szhp + j) |= (0x01 << i/2); //将横置横排的第i行的第j位放到竖置竖排的第(7-i)位 }
else *(szhp + j) &= ~(0x01 << i/2);//取横置横排第i行的第j位,如果为0执行此句
} } for (j = 8; j <= 15; j += 1) //扫描竖置横排的byte8-byte15到横置横排的byte8-byte15 { for (i = 1; i <= 15; i += 2 ) { if (*(hzhp + i) & (0x01 << (7-(j - 8)))) // { *(szhp + j) |= (0x01 << ((i - 1)/2)); } else *(szhp + j) &= ~(0x01 << ((i - 1)/2));
} }
for (j = 16; j <= 23; j ++ ) //竖置横排第j组 { for ( i = 16; i <= 30; i += 2 ) // { if (*(hzhp + i) & (0x01 << (7-(j - 16)))) //取 横置横排第i行的第j位,如果为1执行此句,否则执行else { *(szhp + j) |= (0x01 << ((i - 16) / 2)); //将横置横排的第i行的第j位放到竖置竖排的第(7-i)位 } else *(szhp + j) &= ~(0x01 << ((i - 16) / 2));//取横置横排第i行的第j位,如果为0执行此句
} }
for (j = 24; j <= 31; j += 1) //扫描竖置横排的byte8-byte15到横置横排的byte8-byte15 { for (i = 17; i <= 31; i += 2 ) { if (*(hzhp + i) & (0x01 << (7-(j - 24)))) // { *(szhp + j) |= (0x01 << ((i - 17)/2)); } else *(szhp + j) &= ~(0x01 << ((i - 17)/2));
} }
} /********************************************************* ********汉字******* ***********************************************************/ /** *@brief 获取该汉字字符在15x16点GB2312 *@note 一个字符占32字节 *@param None *@retval None *@date 2021/4 */ voidGT30L32S4W_Get_Bytes_GB2312_15x16(unsigned char *GB2312Code, unsigned char*bytesArray) { longaddr;
addr= GT30L32S4W_Get_Addr_GB2312_15x16(GB2312Code);
if(addr == -1) return;
GT30L32S4W_Read_FontBytes(addr,bytesArray, 32); }
/**
* @brief OLED显示汉字
* @param Line 行位置,范围:1~4
* @param Column 列位置,范围:1~16
* @param text 要显示的一个字符,范围:字库芯片
* @retval 无
*/
void OLED_GB2312_15x16_ShowChar(unsigned char Line, unsigned char Column, unsigned char *text)
{
unsigned char i,j;
unsigned char SZHPArray[32];
unsigned char HZHPArray[32];
while(*text != 0)
{
GT30L32S4W_Get_Bytes_GB2312_15x16(text,HZHPArray);
GB2312_15x16_HengZhiHengPai_to_ShuZhiHengPai(SZHPArray,HZHPArray);
for(j = 0; j < 32; j ++)
{
OLED_SetCursor((unsigned char)((Line - 1) * 2), (unsigned char)((Column - 1) * 8)); //设置光标位置在上半部分
for (i = 0; i < 16; i++)
{
oled_data(SZHPArray); //显示上半部分内容
}
OLED_SetCursor((unsigned char)((Line - 1) * 2 + 1), (unsigned char)((Column - 1) * 8)); //设置光标位置在下半部分
for (i = 0; i < 16; i++)
{
oled_data(SZHPArray[i + 16]); //显示下半部分内容
}
}
text += 2; //下个字
Column += 2;
}
}
|