日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

stm32【GT30L32S4W字库芯片】

發布時間:2023/12/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stm32【GT30L32S4W字库芯片】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

GT30L32S4W字庫芯片調試

測試平臺:STM32F103RFT6
庫版本:官方標準庫3.5.0版本

字庫芯片:GT30L32S4W
字庫標準:GB2312國標漢字,ASCII字符
點陣排列方式:字節橫置橫排
字庫套數:4套(12x12,16x16,24x24,32x32點陣)
驅動方式:SPI

在使用單片機+LCD屏幕進行顯示控制時,文字顯示是一個重要的內容,在比較小的屏幕使用中,例如0.96寸OLED的單色黑白屏幕等,通常是使用文字取模軟件進行取模,然后存儲在程序數組里,再拿去顯示,當只顯示一些特定的字符或文字時,這是一個不錯的方式
但是當需要顯示的字符比較多時,這種方法就不太適合了,這時候字庫芯片的作用就體現出來了

這是高通的芯片,GT官網,在官網下載到這款芯片的數據手冊,但是GT30L32S4W的數據手冊的版本號是【V 1.0I_B 】,不知道是處于商業目的還是啥原因,這個版本的數據手冊刪除了關于編程指導的章節
GT30L32S4W (V1.0I_A)這是在百度文庫找到的A版本,A版的第三章和第四章是B版本里缺少的,也是如何使用該芯片的關鍵內容,可惜下載不到這份數據手冊,只能在線看了

注: 文中首次出現的代碼塊會標注[xxx.c]或[xxx.h],表明該代碼是屬于對應的文件,未標注的即為重復出現的

目錄

  • GT30L32S4W字庫芯片調試
    • 1、電路設計
    • 2、程序設計
      • 2.1、SPI驅動
      • 2.1、GT30L32S4W配置
      • 2.3、操作指令
      • 2.4、ASCII字符獲取
      • 2.5、GB2312字符獲取
    • 3、總結

1、電路設計

電路設計方面沒有啥講究的,按照【datasheet_B版】里的來就行了,采用SPI通訊,注意不同封裝對應的管腳不同就是了,這個SOP8封裝

2、程序設計

2.1、SPI驅動

按照常規的SPI配置就行,注意時鐘極性CPOL和時鐘相位CPHA
【datasheet_B版】第2.2章節

數據在下降沿移出,實際測試中串行時鐘穩態設置成高電平或低電平似乎都是可以的,這就有點迷惑了,或許是我的理解有問題

[spi.c]SPI_InitStructure.SPI_BaudRatePrescaler = speed;SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //數據捕獲于第一個時鐘沿SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行時鐘穩態SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //每次收發數據大小SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //設置SPI單向/雙向SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //設置SPI模式,主/從模式SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定數據傳輸從MSB位還是LSB位開始SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號由硬件(NSS管腳)還是軟件(使用SSI位)控制SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值計算的多項式

由于是雙向是通訊,需要一個SPI的讀寫函數▼

[spi.c] u8 SPI2_ReadWriteByte(u8 data) {u8 temp = 0;//等待發送數據寄存器清空,temp防止程序卡死while(!(SPI2->SR & SPI_I2S_FLAG_TXE)){temp++;if (temp > 200){return 0xFF;}}//發送數據SPI2->DR = data;temp = 0;//等待接收數據寄存器非空,temp防止程序卡死while(!(SPI2->SR & SPI_I2S_FLAG_RXNE)){temp++;if (temp > 200){return 0xFF;}}return SPI2->DR; }

2.1、GT30L32S4W配置

芯片配置只有片選IO口配置+SPI

[GT30L32S4W.c] /********************************************************************************* @brief 配置GT30L32S4W的SPI以及片選端口* @param 無* @retval 無*******************************************************************************/ void GT30L32S4W_Config(void) { GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); GT_CS_1;//配置SPI2SPI2_Config(SPI_BaudRatePrescaler_2); }

2.3、操作指令

從這里開始,編程就需要參考【datasheet_A版】了
第二章【指令操作】里提供了兩種數據讀取方式
【一般讀取】
【快速讀取點陣數據】

但是數據手冊里的描述很迷惑,【一般讀取】讀取指定地址的數據后,如果片選CS不拉高,可以繼續讀取往后的地址上的數據,那么實際上和【快速讀取點陣數據】實現是功能是一致的,而且使用【快速讀取點陣數據】的話,前期需要發送5byte數據,【一般讀取】則只需要發送4byte數據,詳見datasheet
所以這里只介紹【一般讀取】

看回上邊2.2章節的【一般讀取】的三個步驟
【1】片選置低 -> 發送0x03命令字+3字節地址(4byte)
【2】讀取1byte數據
【3】片選置高,結束讀取,片選保存,可以繼續讀取下一地址數據

由于【1】在各種規格的點陣讀取里都會用到,這里單獨編寫一個發送字符地址函數▼

[GT30L32S4W.c] /********************************************************************************* @brief 發送字符地址* @param Address 地址* @retval none*******************************************************************************/ void GenitopZk_Address(u32 Address) {u8 AddH, AddM, AddL;AddH = Address >> 16;AddM = Address >> 8;AddL = Address;SPI2_ReadWriteByte(0x03); //一般讀取SPI2_ReadWriteByte(AddH);SPI2_ReadWriteByte(AddM);SPI2_ReadWriteByte(AddL);// SPI2_ReadWriteByte(0x0B); //快速讀取 // SPI2_ReadWriteByte(AddH); // SPI2_ReadWriteByte(AddM); // SPI2_ReadWriteByte(AddL); // SPI2_ReadWriteByte(0xff); }

2.4、ASCII字符獲取

在字庫芯片中,每一個文字或數字都存放在一個地址里邊,需要找到這一個字符,就需要獲取其首地址,通過上邊的發送地址函數發送給字庫芯片,再讀取一定數量的點陣數據

【datasheet_A】里邊的第三章給出了每套字庫的起始地址▼

通過起始地址加上參考算法算出來的地址,就可以知道所需的字符的首地址

這里先對一些常用的基地址進行一個宏定義▼

[GT30L32S4W.c] /************** GB2312字庫字符基地址 *****************/ #define BaseAdd_12X12 0x00000 #define BaseAdd_16X16 0x2C9D0 #define BaseAdd_24X24 0x68190 #define BaseAdd_32X32 0xEDF00 /************** ASCII字符基地址 *****************/ #define ASCIIAdd_5X7 0x1DDF80 #define ASCIIAdd_7X8 0x1DE280 #define ASCIIAdd_6X12 0x1DBE00 #define ASCIIAdd_8X16 0x1DD780 #define ASCIIAdd_12X24 0x1DFF00 #define ASCIIAdd_16X32 0x1E5A50

在【datasheet_B】的第七章給出了8x16的字母“A”(橫置橫排)點陣數據▼

7 點陣數據驗證(客戶參考用) 客戶將芯片內“A”的數據調出與以下進行對比。若一致,表示 SPI 驅動正常工作;若不一致,請重 新編寫驅動。 排置:Y(豎置橫排)點陣大小 8X16 字母"A" 點陣數據:00 E0 9C 82 9C E0 00 00 0F 00 00 00 00 00 0F 00 排置:W(橫置橫排)點陣大小 8X16 字母"A" 點陣數據:00 10 28 28 28 44 44 7C 82 82 82 82 00 00 00 00

那么先編寫一個8x16點陣數據的看看數據是否能對應上▼

[GT30L32S4W.c] /********************************************************************************* @brief ASCII_8X16 ASCII字符讀取* @param *ASCIICode ASCII字符碼* @param *BUF 緩存數組* @retval none*******************************************************************************/ void ASCII_8X16(char *ASCIICode, u8 *BUF) {u8 i;u32 BaseAdd;u32 Address;BaseAdd = ASCIIAdd_8X16;if(*ASCIICode >= 0x20 && *ASCIICode <= 0x7E){Address = (*ASCIICode - 0x20) * 16 + BaseAdd;}GT_CS_0;GenitopZk_Address(Address);for(i = 0; i < 16 ; i++){BUF[i] = SPI2_ReadWriteByte(0xFF); // printf("%c", BUF[i]);}GT_CS_1;}

Address就是字符的首地址,該算法是【datasheet_A】里給出的▼

Address = (*ASCIICode - 0x20) * 16 + BaseAdd;

這里的【16】是每兩個字符之間的偏置地址
1bit的0/1對應一個像素點的滅/亮,8x16的點陣就需要【(8x16)/8bit = 16byte】的數據大小來存儲,對于其他大小的點陣也是同理推算

計算出字符地址后,就可以發送出去,然后讀取相應數量(這里是16byte)的數據,使用數組存儲起來就可以了

在main函數寫個數組傳遞進去即可檢驗該函數是否可行▼

[main.c]u8 BUF[16];ASCII_8X16("A", BUF);

通過仿真可以查看各個變量的數值▼

"A"實際上是把其對應的ASCII碼(0x41)傳遞進去計算,仿真里可以看見指針【*ASCIICode】指向的值正是【0x41】
而且BUF數組能對應上參考數據▼

排置:W(橫置橫排)點陣大小 8X16 字母"A" 點陣數據:00 10 28 28 28 44 44 7C 82 82 82 82 00 00 00 00

這就說明這個點陣讀取函數是正確有效的,其他大小的ASCII點陣參考其寫法就行

這里給一個16x32點陣的寫法,可以看看如何改寫,其中的【64】是根據上邊給的公式算出來的▼

[GT30L32S4W.c] /********************************************************************************* @brief ASCII_16X32 ASCII字符讀取* @param *ASCIICode ASCII字符碼* @param *BUF 緩存數組* @retval none*******************************************************************************/ void ASCII_16X32(char *ASCIICode, u8 *BUF) {u8 i;u32 BaseAdd;u32 Address;BaseAdd = ASCIIAdd_16X32;if(*ASCIICode >= 0x20 && *ASCIICode <= 0x7E){Address = (*ASCIICode - 0x20) * 64 + BaseAdd;}GT_CS_0;GenitopZk_Address(Address);for(i = 0; i < 64 ; i++){BUF[i] = SPI2_ReadWriteByte(0xFF); // printf("%c", BUF[i]);}GT_CS_1;}

2.5、GB2312字符獲取

ASCII碼有數字,字母,英文字符等對應編碼號,對于中文,則是由漢字國標碼(GB2312)來表示的,同樣是把編碼(漢字機內碼)傳遞進去,再獲取點陣數據即可

由于漢字數量眾多,漢字的機器內碼不再是1byte,而是2byte,內碼高八位和低八位都需要判斷
【datasheet_A】里給出12x12的算法如下▼

根據這個算法就可以編寫函數▼

[GT30L32S4W.c] /********************************************************************************* @brief GB2312_12X12漢字字符讀取* @param *GBCode 漢字內碼* @param *BUF 緩存數組* @retval none*******************************************************************************/ void GB2312_12X12(char *GBCode, u8 *BUF) {u8 i;u8 MSB; //漢字內碼高八位u8 LSB; //漢字內碼低八位u32 BaseAdd; //字庫基地址u32 Address; //字符在芯片中的地址BaseAdd = BaseAdd_12X12;MSB = *GBCode;LSB = *(++GBCode);//計算字符地址值if(MSB >= 0xA1 && MSB <= 0xA9 && LSB >= 0xA1){Address = ((MSB - 0xA1) * 94 + (LSB - 0xA1)) * 24 + BaseAdd;}else if(MSB >= 0xB0 && MSB <= 0xF7 && LSB >= 0xA1){Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1) + 846) * 24 + BaseAdd;}//獲取字符點陣數據GT_CS_0;GenitopZk_Address(Address);for(i = 0; i < 24; i++){BUF[i] = SPI2_ReadWriteByte(0xff); // printf("%c", BUF[i]);}GT_CS_1;}

這里最關鍵的是正確獲取MSB和LSB的值,指針的操作要注意

還有就是【24】這個值
如果按照ASCII里邊的計算是【(12x12) / 8bit = 18byte】
但這里并不是這樣的,為了數據對齊,每兩個字符之間的偏置地址是【(12x16) / 8bit = 24byte】

注意: 在ASCII碼里也有這種數據對齊的現象
ASCII_5X7,實際地址偏置是【(8x8) / 8bit = 8byte】
ASCII_7X8,實際地址偏置是【(8x8) / 8bit = 8byte】
ASCII_6X12,實際地址偏置是【(6x16) / 8bit = 12byte】
因此在屏幕顯示時框選的顯示區域就得是對應的比例

算出地址之后的操作和ASCII是一樣的

同樣,在main函數測試下

[main.c]u8 BUF[24]GB2312_12X12("中", BUF);

這里需要了解下如何獲取漢字機內碼,一些【在線網站】可以輸入文字查詢機器內碼
對于單片機,“中”通過編譯器編譯,就會編譯成機器內碼,大小2byte,可以仿真查看▼

在網站里查詢的“中”字內碼▼

可見內碼是正確獲取到了,至于BUF[24]里存儲的數據是否正確,這里沒法對比
可以自行手動對數據進行描點確認,注意點陣是【12x16】(寬度x高度)

其他大小的漢字點陣參考其寫法就行,這里給一個32x32點陣的改寫
其中的【128】是根據上邊給的公式算出來的【(32x32) / 8bit = 128byte】▼

[GT30L32S4W.c] /********************************************************************************* @brief GB2312_32X32漢字字符讀取* @param *GBCode 漢字內碼* @param *BUF 緩存數組* @retval none*******************************************************************************/ void GB2312_32X32(char *GBCode, u8 *BUF) {u8 i;u8 MSB; //漢字內碼高八位u8 LSB; //漢字內碼低八位u32 BaseAdd; //字庫基地址u32 Address; //字符在芯片中的地址BaseAdd = BaseAdd_32X32;MSB = *GBCode;LSB = *(++GBCode);//計算字符地址值if(MSB >= 0xA1 && MSB <= 0xA9 && LSB >= 0xA1){Address = ((MSB - 0xA1) * 94 + (LSB - 0xA1)) * 128 + BaseAdd;}else if(MSB >= 0xB0 && MSB <= 0xF7 && LSB >= 0xA1){Address = ((MSB - 0xB0) * 94 + (LSB - 0xA1) + 846) * 128 + BaseAdd;}//獲取字符點陣數據GT_CS_0;GenitopZk_Address(Address);for(i = 0; i < 128; i++){BUF[i] = SPI2_ReadWriteByte(0xff); // printf("%c", BUF[i]);}GT_CS_1;}

3、總結

GT30L32S4W字庫芯片調試大概就是這些了,關鍵點是:
【1】芯片內每套字庫的基地址
【2】漢字機內碼 / ASCII碼
【3】每套字庫的字符地址算法
【4】字庫的點陣數據對齊
對于其他的字庫芯片,這四點也是需要注意的
高通官方的數據手冊不同版本內容大幅修改的問題不知道在其他型號的字庫芯片上會不會是同樣的情況,如果也是這樣的話就得找找早期的版本了

這里分享一個結合LCD屏幕(240x240彩色)顯示漢字的函數和調試照片【關于LCD屏幕見往期文章】

[gui.c] /********************************************************************************* @brief LCD顯示32x32漢字字符* @param *string 漢字字符串* @param (x,y) 顯示位置* @param color_1 字體主體顏色* @param color_2 字體背景顏色* @retval none*******************************************************************************/ void LCD_Chinese_32X32(char *string, u32 x, u32 y, u16 f_color, u16 b_color) {u32 i, j;u8 BUF[128];while(*string != 0){ //判斷MSBGB2312_32X32(string, BUF); //讀取一個字符點陣數據LCD_SetRegion_Image(x, y, 32, 32); //設定顯示區域LCD_DC_1;for(i = 0; i < 128; i++){ //分解一幀點陣數據for(j = 0; j < 8; j++){ //1byte分解成8byteif(BUF[i] & 0x80){LCD_WR_Data16(f_color);}else{LCD_WR_Data16(b_color);}BUF[i] <<= 1;}}x += 32;string += 2;} }

調試結果▼

總結

以上是生活随笔為你收集整理的stm32【GT30L32S4W字库芯片】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。