字库芯片GT20L16S1Y 读取字体数据
【本文發布地址https://blog.csdn.net/Stack_/article/details/120432945,未經許可不得轉載,轉載須注明出處】
這個字庫芯片的廠家叫高通,但不是美國那個高通。它在新版本的手冊中刪除了詳細的讀取方法,以下程序按照舊版手冊編寫。
【字庫芯片GT20L16S1Y和GT30L32S4W帶地址運算版手冊】
[GT20L16S1Y所有字體數據都是豎置橫排]
排置: Y(豎置橫排)
點陣大小為 8X16的字母"A"的
點陣數據: 00 E0 9C 82 9C E0 00 00 0F 00 00 00 00 00 0F 00
[GT30L32S4W所有字體數據都是橫置橫排]
排置: W(橫置橫排)
點陣大小為 8X16的字母"A"的
點陣數據: 00 10 28 28 28 44 44 7C 82 82 82 82 00 00 00 00
[一、SPI配置]
/*** @brief * @note SPI1NSS - PA4CLK - PA5MI - PA6MO - PA7* @param * @retval * @author PWH* @ CSDN Tyrion.Mon* @date */ void Spi1_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //NSSGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //CLKGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //MIGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //MOGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //2線全雙工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI模式 0SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //SPI1由APB2分頻而來,最高18M, SPI2由APB1分頻而來,最高18MSPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE); }/*** @brief * @note SPI1NSS - PA4CLK - PA5MI - PA6MO - PA7* @param * @retval * @author PWH* @date */ uint8_t Spi1_SendByte(uint8_t data) {while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, data);while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);return SPI_I2S_ReceiveData(SPI1); }[二、各類型字體的起時地址]
@ CSDN Tyrion.Mon #define GT20L16S1Y_GB2312_15x16_BASE_ADDR 0x00000 // 15x16點GB2312標準點陣字庫 #define GT20L16S1Y_ASCII_7x8_BASE_ADDR 0x66C0 // 7x8點ascii字符 #define GT20L16S1Y_GB2312_EXTEND_8x16_BASE_ADDR 0x3B7D0 // 8x16點國標擴展字符 #define GT20L16S1Y_ASCII_8x16_BASE_ADDR 0x3B7C0 // 8x16點ASCII字符 #define GT20L16S1Y_ASCII_5x7_BASE_ADDR 0x3BFC0 // 5x7點ASCII字符 #define GT20L16S1Y_ASCII_ARIAL_16_BASE_ADDR 0x3C2C0 // 16點陣不等寬ASCII方頭(Arial)字符 #define GT20L16S1Y_ASCII_BOLD_8x16_BASE_ADDR 0x3CF80 // 8x16點ASCII粗體字符 #define GT20L16S1Y_ASCII_TIMESNEWROMEAN_16_BASE_ADDR 0x3D580 // 16點陣不等寬ASCII白正(TimesNewRomean)字符[三、計算某個字符的起始地址]
@ CSDN Tyrion.Mon /*** @brief 獲取該ascii字符在5x7庫中的起始位置* @note 該庫每個字符占8字節* @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/1*/ static int32_t GT20L16S1Y_Get_Addr_Ascii_5x7(char *asciiCode) {/* 0x20 - 0x7E ascii中可顯示的字符 */if (*asciiCode >= ' ' && *asciiCode <= '~'){return GT20L16S1Y_ASCII_5x7_BASE_ADDR + (*asciiCode - ' ') * 8;}return -1; }/*** @brief 獲取該ascii字符在7x8庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_Ascii_7x8(char *asciiCode) {if (*asciiCode >= ' ' && *asciiCode <= '~'){return GT20L16S1Y_ASCII_7x8_BASE_ADDR + (*asciiCode - ' ') * 8;}return -1; } /*** @brief 獲取該ascii字符在8x16庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_Ascii_8x16(char *asciiCode) {if (*asciiCode >= ' ' && *asciiCode <= '~'){return GT20L16S1Y_ASCII_8x16_BASE_ADDR + (*asciiCode - ' ') * 16;}return -1; } /*** @brief 獲取該ascii字符在16點陣不等寬ASCII方頭(Arial)庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_Ascii_Arial_16(char *asciiCode) {if (*asciiCode >= ' ' && *asciiCode <= '~'){return GT20L16S1Y_ASCII_ARIAL_16_BASE_ADDR + (*asciiCode - ' ') * 34;}return -1; } /*** @brief 獲取該ascii字符在8x16粗體庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_Ascii_Bold_8x16(char *asciiCode) {if (*asciiCode >= ' ' && *asciiCode <= '~'){return GT20L16S1Y_ASCII_BOLD_8x16_BASE_ADDR + (*asciiCode - ' ') * 16;}return -1; } /*** @brief 獲取該ascii字符在16點陣不等寬ASCII白正(TimesNewRoman)庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_Ascii_TimesNewRoman_16(char *asciiCode) {if (*asciiCode >= ' ' && *asciiCode <= '~'){return GT20L16S1Y_ASCII_TIMESNEWROMEAN_16_BASE_ADDR + (*asciiCode - ' ') * 34;}return -1; } /*** @brief 獲取該漢字字符在15x16點GB2312標準庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_GB2312_15x16(uint8_t *GB2312Code) {uint8_t MSB = *GB2312Code;uint8_t LSB = *(GB2312Code + 1);if (MSB == 0xA9 && LSB >= 0xA1) {return GT20L16S1Y_GB2312_15x16_BASE_ADDR + (282 + (LSB - 0xA1)) * 32;}else if (MSB >= 0xA1 && MSB <= 0xA3 && LSB >= 0xA1) {return GT20L16S1Y_GB2312_15x16_BASE_ADDR + ((MSB - 0xA1) * 94 + (LSB - 0xA1)) * 32;}else if (MSB >= 0xB0 && MSB <= 0xF7 && LSB >= 0xA1) {return GT20L16S1Y_GB2312_15x16_BASE_ADDR + ((MSB - 0xB0) * 94 + (LSB - 0xA1) + 846) * 32;}return -1; } /*** @brief 獲取該漢字字符在8x16點GB2312標準庫中的起始位置* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ static int32_t GT20L16S1Y_Get_Addr_GB2312_Extend_8x16(uint8_t *GB2312Code) {uint16_t FontCode = *(GB2312Code + 1);FontCode = (FontCode << 8) | *GB2312Code;if (FontCode >= 0xAAA1 && FontCode <= 0xAAFE) {return GT20L16S1Y_GB2312_EXTEND_8x16_BASE_ADDR + (FontCode - 0xAAA1) * 16;}else if (FontCode >= 0xABA1 && FontCode <= 0xABC0) {return GT20L16S1Y_GB2312_EXTEND_8x16_BASE_ADDR + (FontCode - 0xABA1 + 95) * 16;}return -1; }[四、獲取字符數據]
/*** @brief 發送三字節地址* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/1*/ static void GT20L16S1Y_Send_Address(uint32_t addr) {Spi1_SendByte(0x03); //一般讀取Spi1_SendByte(addr >> 16);Spi1_SendByte(addr >> 8);Spi1_SendByte(addr); }/*** @brief 接收字符數據* @note * @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/1*/ static void GT20L16S1Y_Read_FontBytes(int32_t addr, uint8_t *bytesArray, uint8_t numOfBytes) {uint8_t i;SPI1_CS_RESET;GT20L16S1Y_Send_Address(addr);for (i = 0; i < numOfBytes; i++){*bytesArray++ = Spi1_SendByte(0xff);}SPI1_CS_SET; }/*** @brief 獲取該漢字字符在15x16點GB2312* @note 一個字符占32字節* @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GT20L16S1Y_Get_Bytes_GB2312_15x16(uint8_t *GB2312Code, uint8_t *bytesArray) {int32_t addr;addr = GT20L16S1Y_Get_Addr_GB2312_15x16(GB2312Code);if (addr == -1) return;GT20L16S1Y_Read_FontBytes(addr, bytesArray, 32); }/*** @brief 獲取該ASCII字符在7x8點* @note 一個字符占8字節* @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GT20L16S1Y_Get_Bytes_ASCII_5x7(uint8_t *ASCIICode, uint8_t *bytesArray) {int32_t addr;addr = GT20L16S1Y_Get_Addr_Ascii_5x7(ASCIICode);if (addr == -1) return;GT20L16S1Y_Read_FontBytes(addr, bytesArray, 8); }/*** @brief 獲取該ASCII字符在7x8點* @note 一個字符占8字節* @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GT20L16S1Y_Get_Bytes_ASCII_7x8(uint8_t *ASCIICode, uint8_t *bytesArray) {int32_t addr;addr = GT20L16S1Y_Get_Addr_Ascii_7x8(ASCIICode);if (addr == -1) return;GT20L16S1Y_Read_FontBytes(addr, bytesArray, 8); }/*** @brief * @note 一個字符占16字節* @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GT20L16S1Y_Get_Bytes_ASCII_8x16(uint8_t *ASCIICode, uint8_t *bytesArray) {int32_t addr;addr = GT20L16S1Y_Get_Addr_Ascii_8x16(ASCIICode);if (addr == -1) return;GT20L16S1Y_Read_FontBytes(addr, bytesArray, 16); }/*** @brief * @note 一個字符占16字節* @param None* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GT20L16S1Y_Get_Bytes_ASCII_Bold_8x16(uint8_t *ASCIICode, uint8_t *bytesArray) {int32_t addr;addr = GT20L16S1Y_Get_Addr_Ascii_Bold_8x16(ASCIICode);if (addr == -1) return;GT20L16S1Y_Read_FontBytes(addr, bytesArray, 16); }[五、當LCD需要橫排橫置的數據,需要做一下轉換。從手冊中研究一下各字體豎置橫排和橫置橫排的區別,得到下面的算法]
@ CSDN Tyrion.Mon void GB2312_15x16_ShuZhiHengPai_to_HengZhiHengPai(uint8_t *szhp, uint8_t *hzhp) {uint8_t i, j;for (j = 0; j <= 14; j += 2) //掃描豎置橫排的byte0-byte7到橫置橫排的byte0 byte2 byte4 ... byte14{for (i = 0; i <= 7; i++){if (*(szhp + i) & (0x01 << (j / 2))) //*(hzhp + j) |= (0x01 << (7 - i));else*(hzhp + j) &= ~(0x01 << (7 - i));}}for (j = 1; j <= 15; j += 2) //掃描豎置橫排的byte8-byte15到橫置橫排的byte1 byte3 byte5 ... byte15{for (i = 8; i <= 15; i++){if (*(szhp + i) & (0x01 << ((j - 1) / 2))) //*(hzhp + j) |= (0x01 << (7 - (i - 8)));else*(hzhp + j) &= ~(0x01 << (7 - (i - 8)));}}for (j = 16; j <= 30; j += 2) //掃描豎置橫排的byte16-byte23到橫置橫排的byte16 byte18 byte20 ... byte30{for (i = 16; i <= 23; i++){if (*(szhp + i) & (0x01 << ((j - 16) / 2))) //*(hzhp + j) |= (0x01 << (7 - (i - 16)));else*(hzhp + j) &= ~(0x01 << (7 - (i - 16)));}}for (j = 17; j <= 31; j += 2) //掃描豎置橫排的byte24-byte31到橫置橫排的byte17 byte19 byte21 ... byte31{for (i = 24; i <= 31; i++){if (*(szhp + i) & (0x01 << ((j - 17) / 2))) //*(hzhp + j) |= (0x01 << (7 - (i - 24)));else*(hzhp + j) &= ~(0x01 << (7 - (i - 24)));}} }void ASCII_8x16_ShuZhiHengPai_to_HengZhiHengPai(uint8_t *szhp, uint8_t *hzhp) {uint8_t i, j;for (j = 0; j <= 7; j += 1) //掃描豎置橫排的byte0-byte7到橫置橫排的byte0-byte7{for (i = 0; i <= 7; i++){if (*(szhp + i) & (0x01 << j)) //*(hzhp + j) |= (0x01 << (7 - i));else*(hzhp + j) &= ~(0x01 << (7 - i));}} for (j = 8; j <= 15; j += 1) //掃描豎置橫排的byte8-byte15到橫置橫排的byte8-byte15{for (i = 8; i <= 15; i++){if (*(szhp + i) & (0x01 << (j - 8))) //*(hzhp + j) |= (0x01 << (7 - (i - 8)));else*(hzhp + j) &= ~(0x01 << (7 - (i - 8)));}} }[六、向LCD寫入字符串數據。向LCD寫數據的部分僅適用于我的屏,請按自己的屏提供的接口去修改]
/*** @brief * @note LCD顯示漢字字符串* @param x:顯示起始X坐標y:顯示起始Y坐標*text:要顯示的字符串wordColor:字體的顏色backColor:該字體背景顏色* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GUI_Display_GB2312_15x16(uint16_t x, uint16_t y, uint8_t *text, uint16_t wordColor, uint16_t backColor) { uint8_t szhpArray[32];uint8_t hzhpArray[32];uint8_t i, j, m;while (*text != '\0'){GT20L16S1Y_Get_Bytes_GB2312_15x16(text, szhpArray);GB2312_15x16_ShuZhiHengPai_to_HengZhiHengPai(szhpArray, hzhpArray);TFT_SetWindow(x, y, x + 15, y + 15); //設置字符描點起始位置for(i = 0; i < 32; i++) //一個漢字32字節{for(j=0;j<8;j++) //每字節的8位數據{if(hzhpArray[i] & (0x80 >> j)) //為1時著前景色,前景色的點將顯現出字符{TFT_WriteData(wordColor);} else //為0時著后景色{TFT_WriteData(backColor);} }}text += 2; //下一個字x += 16; //下一個字偏移16點} } /*** @brief * @note LCD顯示英文字符串* @param x:顯示起始X坐標y:顯示起始Y坐標*text:要顯示的字符串wordColor:字體的顏色backColor:該字體背景顏色* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GUI_Display_ASCII_Bold_8x16(uint16_t x, uint16_t y, uint8_t *text, uint16_t wordColor, uint16_t backColor) { uint8_t szhpArray[16];uint8_t hzhpArray[16];uint8_t i, j, m;while (*text != '\0'){GT20L16S1Y_Get_Bytes_ASCII_Bold_8x16(text, szhpArray);ASCII_8x16_ShuZhiHengPai_to_HengZhiHengPai(szhpArray, hzhpArray);TFT_SetWindow(x, y, x + 7, y + 15);for(i = 0; i < 16; i++) {for(j=0;j<8;j++) {if(hzhpArray[i] & (0x80 >> j)){TFT_WriteData(wordColor);} else{TFT_WriteData(backColor);} }}text += 1; //下一個字x += 8;} }[七、當字符串有漢字也有英文]
/*** @brief * @note LCD顯示一個漢字字符* @param x:顯示起始X坐標y:顯示起始Y坐標*text:要顯示的字符串wordColor:字體的顏色backColor:該字體背景顏色* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GUI_Display_One_GB2312_15x16(uint16_t x, uint16_t y, uint8_t *text, uint16_t wordColor, uint16_t backColor) { uint8_t szhpArray[32];uint8_t hzhpArray[32];uint8_t i, j;GT20L16S1Y_Get_Bytes_GB2312_15x16(text, szhpArray);GB2312_15x16_ShuZhiHengPai_to_HengZhiHengPai(szhpArray, hzhpArray);TFT_SetWindow(x, y, x + 15, y + 15);for(i = 0; i < 32; i++) {for(j=0;j<8;j++) {if(hzhpArray[i] & (0x80 >> j)){TFT_WriteData(wordColor);} else{TFT_WriteData(backColor);} }} } /*** @brief * @note LCD顯示一個英文字符* @param x:顯示起始X坐標y:顯示起始Y坐標*text:要顯示的字符串wordColor:字體的顏色backColor:該字體背景顏色* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GUI_Display_One_ASCII_Bold_8x16(uint16_t x, uint16_t y, uint8_t *text, uint16_t wordColor, uint16_t backColor) { uint8_t szhpArray[16];uint8_t hzhpArray[16];uint8_t i, j, m;GT20L16S1Y_Get_Bytes_ASCII_Bold_8x16(text, szhpArray);ASCII_8x16_ShuZhiHengPai_to_HengZhiHengPai(szhpArray, hzhpArray);TFT_SetWindow(x, y, x + 7, y + 15);for(i = 0; i < 16; i++) {for(j=0;j<8;j++) {if(hzhpArray[i] & (0x80 >> j)){TFT_WriteData(wordColor);} else{TFT_WriteData(backColor);} }} }/*** @brief * @note LCD漢字和英文混合輸出* @param x:顯示起始X坐標y:顯示起始Y坐標*text:要顯示的字符串wordColor:字體的顏色backColor:該字體背景顏色* @retval None* @author PWH @ CSDN Tyrion.Mon* @date 2021/4*/ void GUI_Display_AutoSelect_GB2312_ASCII(uint16_t x, uint16_t y, uint8_t *text, uint16_t wordColor, uint16_t backColor) {while (*text != '\0'){if (*text & 0x80){GUI_Display_One_GB2312_15x16(x, y, text, wordColor, backColor);text += 2;x += 16;}else{GUI_Display_One_ASCII_Bold_8x16(x, y, text, wordColor, backColor);text += 1;x += 8;}} }[不知何原因,讀出的第一個字符是亂碼,需要在初始化后讀出一個字符數據丟棄]
[效果圖]
總結
以上是生活随笔為你收集整理的字库芯片GT20L16S1Y 读取字体数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 曼昆经济学原理_第五版[1].txt.d
- 下一篇: (转) Csrss进程剖析