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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

高通字库芯片GT20L16S1Y驱动 0.96寸 OLED 任意显示中文

發布時間:2023/12/14 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高通字库芯片GT20L16S1Y驱动 0.96寸 OLED 任意显示中文 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

連續兩個月的加班,給ODM客戶生產溫控器訂單,今天終于順利發貨,對于工程師出身的我,終于可以對著電腦,消停幾天,研究技術,分享技術了,閑話少說,直接進入正題:

半年前有個老客戶介紹個中央某院的項目,我主業是做各種溫控器的,老客戶介紹的新客戶,沒法推脫,就干吧,項目需求具體細節不方便公開,說說本次要分享的部分,要實現的功能是一個OLED任意顯示一段中文句子

項目的硬件組成比較簡單:STM8L051+ KEY + OLED + GT20L16S1Y

軟件平臺:IAR

整個項目沒什么難點,但沒做過這個的,也需要一番折騰,在這里,我把項目的主要代碼貼出來供電友們參考,也感謝之前版本的電友。做個靠譜的電友,除了分享單獨的.c.h驅動文件,最后還會有調用偽代碼,也就是整個代碼的調用過程。

一:高通字庫芯片驅動程序:

// .c文件#include "stm8l15x.h"//STM8L051/151等系列共用庫函數 #include "GT20L16S1Y.h"#define S1Y_CLK_L (GPIO_ResetBits(GPIOB,GPIO_Pin_4)) #define S1Y_CLK_H (GPIO_SetBits(GPIOB,GPIO_Pin_4)) #define S1Y_CS_L (GPIO_ResetBits(GPIOB,GPIO_Pin_5)) #define S1Y_CS_H (GPIO_SetBits(GPIOB,GPIO_Pin_5))#define S1Y_SI_L (GPIO_ResetBits(GPIOB,GPIO_Pin_6)) #define S1Y_SI_H (GPIO_SetBits(GPIOB,GPIO_Pin_6))#define S1Y_SO GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)void GT20L16_init(void) {/* GT20L16S1Y 引腳配置 */GPIO_Init(GPIOB, GPIO_Pin_4, GPIO_Mode_Out_PP_Low_Fast); //高速推挽輸出低電平[SCLK]GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_Low_Fast); //高速推挽輸出低電平[CS]GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_Low_Fast); //高速推挽輸出低電平[SI]GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT); //上拉輸入[SO] }/*************************************** ASCII 調用 ASCIICode:表示ASCII 碼(8bits) BaseAdd:說明該套字庫在芯片中的起始地址。 r_dat_bat: 是讀點陣數據函數。 DZ_Data:是保存讀出的點陣數據的數組。 ****************************************/ u8 S1Y_ASCII_GetData( u8 ASCIICode, u32 BaseAdd, u8* S1YDZ_Data ) {if( ( ASCIICode >= 0x20 ) && ( ASCIICode <= 0x7e ) ){switch( BaseAdd ){case 0x3bfc0:S1Y_rdat_bat( ( ASCIICode - 0x20 ) * 8 + BaseAdd, 8, S1YDZ_Data ); //5X7break ;case 0x66c0:S1Y_rdat_bat( ( ASCIICode - 0x20 ) * 8 + BaseAdd, 8, S1YDZ_Data ); //7X8break ;case 0x3b7c0:S1Y_rdat_bat( ( ASCIICode - 0x20 ) * 16 + BaseAdd, 16, S1YDZ_Data ); //8X16 Abreak ;case 0x3cf80:S1Y_rdat_bat( ( ASCIICode - 0x20 ) * 26 + BaseAdd, 16, S1YDZ_Data ); //8X16 Fbreak ;case 0x3c2c0:S1Y_rdat_bat( ( ASCIICode - 0x20 ) * 34 + BaseAdd + 2, 32, S1YDZ_Data ); //16X16 Arialbreak ;case 0x3d580:S1Y_rdat_bat( ( ASCIICode - 0x20 ) * 34 + BaseAdd + 2, 32, S1YDZ_Data ); //16X16 Tbreak ;default:break;}return 1;}else{return 0;} }/*************************************************** 16 點GB2312 標準點陣字庫 參數說明: GBCode表示漢字內碼。 MSB 表示漢字內碼GBCode 的高8bits。 LSB 表示漢字內碼GBCode 的低8bits。 Address 表示漢字或ASCII字符點陣在芯片中的字節地址。 BaseAdd:說明點陣數據在字庫芯片中的起始地址。 r_dat_bat 是讀點陣數據函數。 DZ_Data是保存讀出的點陣數據的數組。 *****************************************************/ void S1Y_gt16_GetData( u8 MSB, u8 LSB, u8* S1YDZ_Data ) {u32 temp = ( MSB - 0xB0 ) * 94 + LSB - 0xA1;u32 BaseAdd = 0, Address;if( MSB == 0xA9 && LSB >= 0xA1 ){Address = ( 282 + ( LSB - 0xA1 ) ) * 32 + BaseAdd;}else if( MSB >= 0xA1 && MSB <= 0xA3 && LSB >= 0xA1 ){Address = ( ( MSB - 0xA1 ) * 94 + ( LSB - 0xA1 ) ) * 32 + BaseAdd;}else if( MSB >= 0xB0 && MSB <= 0xF7 && LSB >= 0xA1 ){Address = ( 846 + temp ) * 32 + BaseAdd;}S1Y_rdat_bat( Address, 32, S1YDZ_Data ); } //Address=((MSB-0xB0)*94+(LSB-0xA1)+846)*32+BaseAdd;/**************************************************** 8X16 點國標擴展字符 說明: BaseAdd:說明本套字庫在字庫芯片中的起始字節地址。 FontCode:表示字符內碼(16bits). Address:表示字符點陣在芯片中的字節地址。 r_dat_bat 是讀點陣數據函數。 DZ_Data是保存讀出的點陣數據的數組。 *****************************************************/ void S1Y_GB_EXT_816( u16 FontCode, u8* S1YDZ_Data ) {u32 BaseAdd = 0x3b7d0, Address;u32 temp1 = ( FontCode - 0xAAA1 );u32 temp2 = ( FontCode - 0xABA1 + 95 );if( FontCode >= 0xAAA1 && FontCode <= 0xAAFE ){Address = temp1 * 16 + BaseAdd;}else if( FontCode >= 0xABA1 && FontCode <= 0xABC0 ){Address = temp2 * 16 + BaseAdd;}S1Y_rdat_bat( Address, 16, S1YDZ_Data ); }/**************************************************** 從字庫中讀數據函數 說明: Address : 表示字符點陣在芯片中的字節地址。 byte_long: 是讀點陣數據字節數。 *p_arr : 是保存讀出的點陣數據的數組。 *****************************************************/ u8 S1Y_rdat_bat( u32 address, u8 byte_long, u8* p_arr ) {unsigned int j = 0;S1Y_CS_L;S1Y_SendByte( address );for( j = 0; j < byte_long; j++ ){p_arr[j] = S1Y_ReadByte();}S1Y_CS_H;return p_arr[0]; }void S1Y_SendByte( u32 cmd ) {u8 i;cmd = cmd | 0x03000000;for( i = 0; i < 32; i++ ){S1Y_CLK_L;if( cmd & 0x80000000 ){S1Y_SI_H;}else{S1Y_SI_L;}S1Y_CLK_H;cmd = cmd << 1;} } u8 S1Y_ReadByte( void ) {u8 i;u8 dat = 0;S1Y_CLK_H;for( i = 0; i < 8; i++ ){S1Y_CLK_L;dat = dat << 1;if( S1Y_SO ){dat = dat | 0x01;}else{dat &= 0xfe;}S1Y_CLK_H ;}return dat; } //-------------------------------------分割線--------------------------------- //.h 文件#ifndef _GT20L16S1Y_H_ #define _GT20L16S1Y_H_void S1Y_SendByte(u32 cmd); u8 S1Y_ReadByte(void); u8 S1Y_rdat_bat(u32 address,u8 byte_long,u8 *p_arr);u8 S1Y_ASCII_GetData(u8 ASCIICode,u32 BaseAdd,u8 *S1YDZ_Data); void S1Y_gt16_GetData (u8 MSB,u8 LSB,u8 *S1YDZ_Data); void S1Y_GB_EXT_816(u16 FontCode,u8 *S1YDZ_Data);void GT20L16_init(void);#endif

OLED顯示就比較簡單了,顯示任意漢字字符串,也折騰了我幾根頭發,下面也貼出來分享一下:

// .c文件 #include "oled.h" #include "oledfont.h" #include "GT20L16S1Y.h"//OLED的顯存 //存放格式如下. //[0]0 1 2 3 ... 127 //[1]0 1 2 3 ... 127 //[2]0 1 2 3 ... 127 //[3]0 1 2 3 ... 127 //[4]0 1 2 3 ... 127 //[5]0 1 2 3 ... 127 //[6]0 1 2 3 ... 127 //[7]0 1 2 3 ... 127 void delay_ms( unsigned int ms ) {unsigned int a;while( ms ){a = 1800;while( a-- );ms--;}return; }//反顯函數 void OLED_ColorTurn( u8 i ) {if( i == 0 ){OLED_WR_Byte( 0xA6, OLED_CMD ); //正常顯示}if( i == 1 ){OLED_WR_Byte( 0xA7, OLED_CMD ); //反色顯示} }//屏幕旋轉180度 void OLED_DisplayTurn( u8 i ) {if( i == 0 ){OLED_WR_Byte( 0xC8, OLED_CMD ); //正常顯示OLED_WR_Byte( 0xA1, OLED_CMD );}if( i == 1 ){OLED_WR_Byte( 0xC0, OLED_CMD ); //反轉顯示OLED_WR_Byte( 0xA0, OLED_CMD );} }//延時 void IIC_delay( void ) {u8 t = 1;while( t-- ); }//起始信號 void I2C_Start( void ) {OLED_SDA_Set();OLED_SCL_Set();IIC_delay();OLED_SDA_Clr();IIC_delay();OLED_SCL_Clr(); }//結束信號 void I2C_Stop( void ) {OLED_SDA_Clr();OLED_SCL_Set();IIC_delay();OLED_SDA_Set(); }//等待信號響應 void I2C_WaitAck( void ) //測數據信號的電平 {OLED_SDA_Set();IIC_delay();OLED_SCL_Set();IIC_delay();OLED_SCL_Clr();IIC_delay(); }//寫入一個字節 void Send_Byte( u8 dat ) {u8 i;for( i = 0; i < 8; i++ ){OLED_SCL_Clr();//將時鐘信號設置為低電平if( dat & 0x80 ) //將dat的8位從最高位依次寫入{OLED_SDA_Set();}else{OLED_SDA_Clr();}IIC_delay();OLED_SCL_Set();IIC_delay();OLED_SCL_Clr();dat <<= 1;} }//發送一個字節 //向SSD1306寫入一個字節。 //mode:數據/命令標志 0,表示命令;1,表示數據; void OLED_WR_Byte( u8 dat, u8 mode ) {I2C_Start();Send_Byte( 0x78 );I2C_WaitAck();if( mode ){Send_Byte( 0x40 );}else{Send_Byte( 0x00 );}I2C_WaitAck();Send_Byte( dat );I2C_WaitAck();I2C_Stop(); }//坐標設置void OLED_Set_Pos( u8 x, u8 y ) {OLED_WR_Byte( 0xb0 + y, OLED_CMD );OLED_WR_Byte( ( ( x & 0xf0 ) >> 4 ) | 0x10, OLED_CMD );OLED_WR_Byte( ( x & 0x0f ), OLED_CMD ); } //開啟OLED顯示 void OLED_Display_On( void ) {OLED_WR_Byte( 0X8D, OLED_CMD ); //SET DCDC命令OLED_WR_Byte( 0X14, OLED_CMD ); //DCDC ONOLED_WR_Byte( 0XAF, OLED_CMD ); //DISPLAY ON } //關閉OLED顯示 void OLED_Display_Off( void ) {OLED_WR_Byte( 0X8D, OLED_CMD ); //SET DCDC命令OLED_WR_Byte( 0X10, OLED_CMD ); //DCDC OFFOLED_WR_Byte( 0XAE, OLED_CMD ); //DISPLAY OFF } //清屏函數,清完屏,整個屏幕是黑色的!和沒點亮一樣!!! void OLED_Clear( void ) {u8 i, n;for( i = 0; i < 4; i++ ){OLED_WR_Byte( 0xb0 + i, OLED_CMD ); //設置頁地址(0~7)OLED_WR_Byte( 0x00, OLED_CMD ); //設置顯示位置—列低地址OLED_WR_Byte( 0x10, OLED_CMD ); //設置顯示位置—列高地址for( n = 0; n < 128; n++ ){OLED_WR_Byte( 0, OLED_DATA );}} //更新顯示 }//在指定位置顯示一個字符,包括部分字符 //x:0~127 //y:0~63 //sizey:選擇字體 6x8 8x16 void OLED_ShowChar( u8 x, u8 y, u8 chr, u8 sizey ) {u8 c = 0, sizex = sizey / 2;u16 i = 0, size1;if( sizey == 8 ){size1 = 6;}else{size1 = ( sizey / 8 + ( ( sizey % 8 ) ? 1 : 0 ) ) * ( sizey / 2 );}c = chr - ' '; //得到偏移后的值OLED_Set_Pos( x, y );for( i = 0; i < size1; i++ ){if( i % sizex == 0 && sizey != 8 ){OLED_Set_Pos( x, y++ );}if( sizey == 8 ){OLED_WR_Byte( asc2_0806[c][i], OLED_DATA ); //6X8字號}else if( sizey == 16 ){OLED_WR_Byte( asc2_1608[c][i], OLED_DATA ); //8x16字號}// else if(sizey==xx) OLED_WR_Byte(asc2_xxxx[c][i],OLED_DATA);//用戶添加字號else{return;}} } //m^n函數 u32 oled_pow( u8 m, u8 n ) {u32 result = 1;while( n-- ){result *= m;}return result; } //顯示數字 //x,y :起點坐標 //num:要顯示的數字 //len :數字的位數 //sizey:字體大小 void OLED_ShowNum( u8 x, u8 y, u32 num, u8 len, u8 sizey ) {u8 t, temp, m = 0;u8 enshow = 0;if( sizey == 8 ){m = 2;}for( t = 0; t < len; t++ ){temp = ( num / oled_pow( 10, len - t - 1 ) ) % 10;if( enshow == 0 && t < ( len - 1 ) ){if( temp == 0 ){OLED_ShowChar( x + ( sizey / 2 + m )*t, y, ' ', sizey );continue;}else{enshow = 1;}}OLED_ShowChar( x + ( sizey / 2 + m )*t, y, temp + '0', sizey );} } //顯示一個字符號串 void OLED_ShowString( u8 x, u8 y, u8* chr, u8 sizey ) {u8 j = 0;while( chr[j] != '\0' ){OLED_ShowChar( x, y, chr[j++], sizey );if( sizey == 8 ){x += 6;}else{x += sizey / 2;}} } //顯示漢字 void OLED_ShowChinese( u8 x, u8 y, u8 *temp, u8 sizey ) {u16 i, size1 = ( sizey / 8 + ( ( sizey % 8 ) ? 1 : 0 ) ) * sizey;for( i = 0; i < size1; i++ ){if( i % sizey == 0 ){OLED_Set_Pos( x, y++ );}if( sizey == 16 ){OLED_WR_Byte( temp[i], OLED_DATA ); //16x16字號}// else if(sizey==xx) OLED_WR_Byte(xxx[c][i],OLED_DATA);//用戶添加字號else{return;}} } //---------------------------------------------------------- //顯示一個gb2312漢字(從字庫讀數據) void OLED_ShowGB2312(unsigned char x,unsigned char y,unsigned char textH,unsigned char textL) {unsigned char fontbuf[32];S1Y_gt16_GetData(textH,textL,fontbuf);OLED_ShowChinese( x, y, fontbuf, 16 ); // OLED_Set_Pos(x,y); // for(t=0;t<16;t++) // OLED_WR_Byte(fontbuf[t],OLED_DATA); // OLED_Set_Pos(x,y+1); // for(t=0;t<16;t++) // OLED_WR_Byte(fontbuf[t+16],OLED_DATA); } void OLED_ShowStr(unsigned char x,unsigned char y,unsigned char* text) {unsigned char i=0;while((text[i]>0x00)){if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1)){OLED_ShowGB2312(x,y,text[i],text[i+1]);i+=2;x+=16;}else if((text[i]>=0x20) && (text[i]<=0x7e)) {//OLED_ShowASCII(x,y,text[i]);i+=1;x+=8;}elsei++; } } //-------------------------------------------------------------------- //顯示圖片 //x,y顯示坐標 //sizex,sizey,圖片長寬 //BMP:要顯示的圖片 void OLED_DrawBMP( u8 x, u8 y, u8 sizex, u8 sizey, u8 BMP[] ) {u16 j = 0;u8 i, m;sizey = sizey / 8 + ( ( sizey % 8 ) ? 1 : 0 );for( i = 0; i < sizey; i++ ){OLED_Set_Pos( x, i + y );for( m = 0; m < sizex; m++ ){OLED_WR_Byte( BMP[j++], OLED_DATA );}} }//初始化 void OLED_Init( void ) {GPIO_Init( OLED_PORT,OLED_SCL,GPIO_Mode_Out_PP_High_Fast );GPIO_Init( OLED_PORT,OLED_SDA,GPIO_Mode_Out_PP_High_Fast );OLED_WR_Byte( 0xAE, OLED_CMD ); /*display off*/OLED_WR_Byte( 0x00, OLED_CMD ); /*set lower column address*/OLED_WR_Byte( 0x10, OLED_CMD ); /*set higher column address*/OLED_WR_Byte( 0x00, OLED_CMD ); /*set display start line*/OLED_WR_Byte( 0xB0, OLED_CMD ); /*set page address*/OLED_WR_Byte( 0x81, OLED_CMD ); /*contract control*/OLED_WR_Byte( 0xff, OLED_CMD ); /*128*/OLED_WR_Byte( 0xA1, OLED_CMD ); /*set segment remap*/OLED_WR_Byte( 0xA6, OLED_CMD ); /*normal / reverse*/OLED_WR_Byte( 0xA8, OLED_CMD ); /*multiplex ratio*/OLED_WR_Byte( 0x1F, OLED_CMD ); /*duty = 1/32*/OLED_WR_Byte( 0xC8, OLED_CMD ); /*Com scan direction*/OLED_WR_Byte( 0xD3, OLED_CMD ); /*set display offset*/OLED_WR_Byte( 0x00, OLED_CMD );OLED_WR_Byte( 0xD5, OLED_CMD ); /*set osc division*/OLED_WR_Byte( 0x80, OLED_CMD );OLED_WR_Byte( 0xD9, OLED_CMD ); /*set pre-charge period*/OLED_WR_Byte( 0x1f, OLED_CMD );OLED_WR_Byte( 0xDA, OLED_CMD ); /*set COM pins*/OLED_WR_Byte( 0x00, OLED_CMD );OLED_WR_Byte( 0xdb, OLED_CMD ); /*set vcomh*/OLED_WR_Byte( 0x40, OLED_CMD );OLED_WR_Byte( 0x8d, OLED_CMD ); /*set charge pump enable*/OLED_WR_Byte( 0x14, OLED_CMD );OLED_Clear();OLED_WR_Byte( 0xAF, OLED_CMD ); /*display ON*/ }//-----------------------------------分割線------------------------------------------// .h文件 #ifndef __OLED_H #define __OLED_H#include "stm8l15x.h"//STM8L051/151等系列共用庫函數 #define u8 unsigned char #define u16 unsigned int #define u32 unsigned int#define OLED_CMD 0 //寫命令 #define OLED_DATA 1 //寫數據#define OLED_PORT GPIOC//SCL老板子線: //#define OLED_SCL GPIO_Pin_1//SCL //#define OLED_SDA GPIO_Pin_0//SDA// 新板子線: #define OLED_SCL GPIO_Pin_0//SCL #define OLED_SDA GPIO_Pin_1//SDA//-----------------OLED端口定義----------------#define OLED_SCL_Clr() GPIO_ResetBits(OLED_PORT, OLED_SCL)//SCL IIC接口的數據信號 #define OLED_SCL_Set() GPIO_SetBits(OLED_PORT, OLED_SCL)#define OLED_SDA_Clr() GPIO_ResetBits(OLED_PORT, OLED_SDA )//SDA IIC接口的時鐘信號 #define OLED_SDA_Set() GPIO_SetBits(OLED_PORT, OLED_SDA )//--------------------------------------------------//OLED控制用函數 void delay_ms(unsigned int ms); void OLED_ColorTurn(u8 i); void OLED_DisplayTurn(u8 i); void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Set_Pos(u8 x, u8 y); void OLED_Display_On(void); void OLED_Display_Off(void); void OLED_Clear(void); void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey); u32 oled_pow(u8 m,u8 n); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 sizey); void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 sizey); //void OLED_ShowChinese(u8 x,u8 y,u8 no,u8 sizey); void OLED_ShowChinese( u8 x, u8 y, u8 *temp, u8 sizey ); void OLED_DrawBMP(u8 x,u8 y,u8 sizex, u8 sizey,u8 BMP[]); void OLED_Init(void);void OLED_ShowStr(unsigned char x,unsigned char y,unsigned char* text);#endif

最后是調用過程偽代碼:

// 調用顯示任意漢字字符串偽代碼段 void main(void) {if(key.code == true){OLED_Clear();OLED_ShowStr( 0, 0, tab[HZ] );// tab[]里面存放的是漢字字符串,例如:"華溫冷鏈巴拉巴拉"Delay( 100 );} }

最后的最后,剛忙完,寫博客的時候有點累,有任何不明白的地方,歡迎一起探討 QQ741684134。PS:遇到很多網友找我聊很基礎的單片機應用問題,請自行百度,因為實在很忙。

總結

以上是生活随笔為你收集整理的高通字库芯片GT20L16S1Y驱动 0.96寸 OLED 任意显示中文的全部內容,希望文章能夠幫你解決所遇到的問題。

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