STM32+字库

“高通”字库芯片的使用方法


“高通”字库芯片的使用方法

  • STM32+字库
  • 前言
  • 一、电路设计
  • 二、程序设计
    • 代码如下:
  • 整体代码部分
    • 1.字库初始化
    • 2.字库头文件
    • 3.主函数

前言

本文应用了这位大神的指导链接:https://blog.csdn.net/qq_40102829/article/details/105622434 再通过自己实践来的结果

测试平台:STM32F103C8T6
字库芯片型号:GT21L16S2W SPI协议
显示方式:0.96寸的OLED SPI协议

通常在小显示屏上显示中文字体需要一个专用的软件对其汉字进行取模,而且需要大量的工作一个一个取出对应汉字的数据,如果是大量的汉字要显示实在不方便,不如直接买一个别人已经将字库弄好的直接调用爽快多了。本次第一次购买掉进了一个坑,在此提醒下,注意购买的时候你要根据你的显示屏扫描的方式 如0.96寸的OLED扫描方式是从先从 下到上 后 左到右 的顺序规律扫描出来的,那些汉字取模软件也有类似的选项给你选择,所以购买时选择好点阵排列方式是竖置横排的还是横

在高通官网站查找不到芯片手册,只能通过百度文库中查找或在立创商城中找到。手册中也坑,在最新版本中要么不给出字体的地址或者是指定的汉字详细计算方法。所以只能在百度文库中找最早出现的A版本查询信息

说实话,我最终还是跟现实低下头,直接买别人现成的,真香。程序部分别人已经写好了有SPI和IIC注释也好看,而我合并了SPI和IIC的功能下次调用直接使能哪一个通讯方式就行。

改为:
测试平台:STM32F407系列
字库芯片型号:GT30L32S4W SPI协议
显示方式:2.08寸的OLED SPI协议

链接: “高通”字库芯片的使用方法


一、电路设计

电路设计:字库芯片跟SPI FLASH 存储器连接方式一样,注意MOSI和MISO与单片机连接对调就行了,没啥好说的

二、程序设计

先看看手册中的指令有哪些

这款芯片比较简单只有两个指令 Read Data Bytes(一般读取)和 Read Data Bytes at Higher Speed(快速读取点阵数据)

以最简单的方式 Read Data Bytes(一般读取) 来讲解


1个字节的命令字(03H)和 3个字节的地址(通过给出的公式计算出来传递给其)
1个字节 = 8位 —> 0000 0000 一共要发送24位数据给到字库芯片中去
从图象中可以看出高位先进去(MSB),发送完24位数据后 字库芯片会发送数据出来 (Data Out1)

代码如下:

//******************************************************************************
//    函数说明:向字库芯片发送指令
//    入口数据:AddrHigh 写地址高字节
//              AddrMid  写地址中字节
//              AddrLow  写地址低字节
//              *pBuff   读到的数据
//              DataLen  读取的长度
//    返回值:  无
//******************************************************************************
void get_n_bytes_data_from_ROM(u8 AddrHigh,u8 AddrMid,u8 AddrLow,u8 *pBuff,u8 DataLen )
{u8  i;ZK_CS_Clr(); //字库片选ZK_command(0x03);//写指令ZK_command(AddrHigh);//写地址高字节ZK_command(AddrMid);//写地址中字节ZK_command(AddrLow);//写地址低字节for(i = 0; i < DataLen; i++ ){*(pBuff+i) =get_data_from_ROM();//读一个字节数据}ZK_CS_Set();//取消字库片选
}

整体代码部分

1.字库初始化

OLED_IIC_MODE 和 LED_SPI_MODE 该定义即可更改为SPI模式或IIC模式通讯
代码如下(示例):

#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "delay.h"
#include "stm32f4xx_spi.h"
//************************************硬件连接线********************************
//              GND    电源地
//              VCC  3.3v电源
//              D0   PB3(SCL)
//              D1   PB5(SDA)
//              RES  PD6
//              DC   PD7
//              CS1  PF9
//              FS0  PB4
//              CS2  PF10
//******************************************************************************void OLED_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;RCC_AHB1PeriphClockCmd(OLED_GPIO_ClockCmd, ENABLE);//使能GPIO时钟#if OLED_IIC_MODE //RES、DCGPIO_InitStructure.GPIO_Pin = OLED_GPIO_RES_PIN|OLED_GPIO_DC_PIN;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;         //普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;          //上拉GPIO_Init(OLED_GPIO_RES_PORT, &GPIO_InitStructure);                     //初始化GPIO_Init(OLED_GPIO_DC_PORT, &GPIO_InitStructure);                     //初始化//CS1、CS2GPIO_InitStructure.GPIO_Pin = OLED_GPIO_CS_PIN|ZK_GPIO_CS_PIN;    GPIO_Init(OLED_GPIO_CS_PORT, &GPIO_InitStructure);                     //初始化GPIO_Init(ZK_GPIO_CS_PORT, &GPIO_InitStructure);                       //初始化   //SCL、SDAGPIO_InitStructure.GPIO_Pin = OLED_GPIO_SCL_PIN|OLED_GPIO_SDA_PIN;     GPIO_Init(OLED_GPIO_SCL_PORT, &GPIO_InitStructure);                        //初始化   GPIO_Init(OLED_GPIO_SDA_PORT, &GPIO_InitStructure);                     //初始化   //FS0GPIO_InitStructure.GPIO_Pin = ZK_GPIO_FS0_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;           //普通输入模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;     //下拉输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_Init(GPIOA, &GPIO_InitStructure);                 //初始化GPIOE8GPIO_SetBits(ZK_GPIO_FS0_PORT,ZK_GPIO_CS_PIN);#endif#if OLED_SPI_MODERCC_APB2PeriphClockCmd(ZK_SPI_CLK, ENABLE); //使能SPI1时钟//RES、DCGPIO_InitStructure.GPIO_Pin = OLED_GPIO_RES_PIN|OLED_GPIO_DC_PIN;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;         //普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;          //上拉GPIO_Init(OLED_GPIO_RES_PORT, &GPIO_InitStructure);                     //初始化GPIO_Init(OLED_GPIO_DC_PORT, &GPIO_InitStructure);                     //初始化//CS1、CS2GPIO_InitStructure.GPIO_Pin = OLED_GPIO_CS_PIN|ZK_GPIO_CS_PIN;    GPIO_Init(OLED_GPIO_CS_PORT, &GPIO_InitStructure);                     //初始化GPIO_Init(ZK_GPIO_CS_PORT, &GPIO_InitStructure);                       //初始化   //MOSI、MISO、SCKGPIO_InitStructure.GPIO_Pin = OLED_GPIO_SCL_PIN|OLED_GPIO_SDA_PIN|ZK_GPIO_FS0_PIN;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(ZK_GPIO_FS0_PORT, &GPIO_InitStructure);      GPIO_Init(OLED_GPIO_SCL_PORT, &GPIO_InitStructure);     GPIO_Init(OLED_GPIO_SDA_PORT, &GPIO_InitStructure);     GPIO_PinAFConfig(ZK_GPIO_FS0_PORT,ZK_GPIO_PinSource_SCL,ZK_SPI_GPIO_AF); //PB3复用为 SPI1GPIO_PinAFConfig(ZK_GPIO_FS0_PORT,ZK_GPIO_PinSource_FS0,ZK_SPI_GPIO_AF); //PB4复用为 SPI1GPIO_PinAFConfig(ZK_GPIO_FS0_PORT,ZK_GPIO_PinSource_SDA,ZK_SPI_GPIO_AF); //PB5复用为 SPI1//这里只针对SPI口初始化RCC_APB2PeriphResetCmd(ZK_SPI_CLK,ENABLE);                                  //复位SPI1RCC_APB2PeriphResetCmd(ZK_SPI_CLK,DISABLE);                                 //停止复位SPI1SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                                               //设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                                       //设置SPI的数据大小:SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                                                   //串行同步时钟的空闲状态为高电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                                              //串行同步时钟的第二个跳变沿(上升或下降)数据被采样SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                                     //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;   //定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                                 //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7;                                                      //CRC值计算的多项式SPI_Init(ZK_SPIx, &SPI_InitStructure);                                                                  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器SPI_Cmd(ZK_SPIx, ENABLE); //使能SPI外设SPI1_ReadWriteByte(0xff);//启动传输      #endifOLED_RES_Clr();       //复位delay_ms(10);OLED_RES_Set();OLED_WR_REG(0xAE);//Set display offOLED_WR_REG(0xB0); //Row address Mode SettingOLED_WR_REG(0x00);OLED_WR_REG(0x10); //Set Higher Column Address of display RAMOLED_WR_REG(0x00); //Set Lower Column Address of display RAMOLED_WR_REG(0xD5); //Set Display Clock Divide Ratio/Oscillator FrequencyOLED_WR_REG(0x50); //50 125hzOLED_WR_REG(0xD9); //Set Discharge/Precharge PeriodOLED_WR_REG(0x22);OLED_WR_REG(0x40); //Set Display Start LineOLED_WR_REG(0x81); //The Contrast Control Mode SetOLED_WR_REG(0xFF);if(USE_HORIZONTAL){OLED_WR_REG(0xA1); //Set Segment Re-mapOLED_WR_REG(0xC8); //Set Common Output Scan DirectionOLED_WR_REG(0xD3); //Set Display OffsetOLED_WR_REG(0x20);}else{OLED_WR_REG(0xA0); //Set Segment Re-mapOLED_WR_REG(0xC0); //Set Common Output Scan DirectionOLED_WR_REG(0xD3); //Set Display OffsetOLED_WR_REG(0x00);}OLED_WR_REG(0xA4); //Set Entire Display OFF/ONOLED_WR_REG(0xA6); //Set Normal/Reverse DisplayOLED_WR_REG(0xA8); //Set Multiplex RationOLED_WR_REG(0x3F);OLED_WR_REG(0xAD); //DC-DC SettingOLED_WR_REG(0x80); //DC-DC is disableOLED_WR_REG(0xDB); //Set VCOM Deselect LevelOLED_WR_REG(0x30);OLED_WR_REG(0xDC); //Set VSEGM LevelOLED_WR_REG(0x30);OLED_WR_REG(0x33); //Set Discharge VSL Level 1.8VOLED_Clear();OLED_WR_REG(0xAF); //Set Display On
}
//******************************************************************************
//    函数说明:硬件SPI读写一个字节
//    入口数据:要写入的字节
//    返回值:  读取到的字节
//******************************************************************************#if OLED_SPI_MODE
u8 SPI1_ReadWriteByte(u8 TxData)
{                    while (SPI_I2S_GetFlagStatus(ZK_SPIx, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空  SPI_I2S_SendData(ZK_SPIx, TxData); //通过外设SPIx发送一个byte  数据while (SPI_I2S_GetFlagStatus(ZK_SPIx, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte  return SPI_I2S_ReceiveData(ZK_SPIx); //返回通过SPIx最近接收的数据
}#endif//******************************************************************************
//    函数说明:OLED写入一个指令
//    入口数据:dat 数据
//    返回值:  无
//******************************************************************************
void OLED_WR_Bus(u8 dat)
{u8 i;OLED_CS_Clr();#if OLED_IIC_MODEfor(i=0;i<8;i++){              OLED_SCL_Clr();if(dat&0x80){OLED_SDA_Set();}else {OLED_SDA_Clr();}OLED_SCL_Set();dat<<=1;   }
//  printf("IIC\r");#endif#if OLED_SPI_MODESPI1_ReadWriteByte(dat);
//      printf("SPI\r");#endifOLED_CS_Set();
}//******************************************************************************
//    函数说明:OLED写入一个指令
//    入口数据:reg 指令
//    返回值:  无
//******************************************************************************
void OLED_WR_REG(u8 reg)
{     OLED_DC_Clr();          OLED_WR_Bus(reg);OLED_DC_Set();
}//******************************************************************************
//    函数说明:OLED写入一个数据
//    入口数据:dat 数据
//    返回值:  无
//******************************************************************************
void OLED_WR_Byte(u8 dat)
{     OLED_WR_Bus(dat);
}//******************************************************************************
//    函数说明:OLED显示列的起始终止地址
//    入口数据:a  列的起始地址
//              b  列的终止地址
//    返回值:  无
//******************************************************************************
void OLED_AddressSet(u8 x,u8 y)
{OLED_WR_REG(0xB0);OLED_WR_REG(y);OLED_WR_REG(((x&0xf0)>>4)|0x10);OLED_WR_REG((x&0x0f));
}//******************************************************************************
//    函数说明:OLED清屏显示
//    入口数据:无
//    返回值:  无
//******************************************************************************
void OLED_Clear(void)
{u16 j,i;OLED_AddressSet(0,0);OLED_CS_Clr();for(i=0;i<64;i++){#if OLED_IIC_MODEOLED_AddressSet(0,i);#endif    for(j=0;j<128;j++){#if OLED_IIC_MODEOLED_WR_Byte(0x00);#endif #if OLED_SPI_MODESPI1_ReadWriteByte(0x00);  #endif          }}OLED_CS_Set();
}//******************************************************************************
//    函数说明:OLED清屏显示
//    入口数据:x1,y1 起点坐标
//              x2,y2 结束坐标
//              color 填充的颜色值
//    返回值:  无
//******************************************************************************
void OLED_Fill(u16 x1,u8 y1,u16 x2,u8 y2,u8 color)
{u16 j,i;x1/=2;x2/=2;for(i=y1;i<y2;i++){OLED_AddressSet(x1,i);for(j=x1;j<x2;j++){OLED_WR_Byte(color);}}
}//******************************************************************************
//    函数说明:OLED显示汉字
//    入口数据:x,y :起点坐标
//              *s  :要显示的汉字串
//              sizey 字符高度
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_ShowChinese(u8 x,u8 y,u8 *s,u8 sizey,u8 mode)
{while(*s!=0){if(sizey==16) OLED_ShowChinese16x16(x,y,s,sizey,mode);else if(sizey==24) OLED_ShowChinese24x24(x,y,s,sizey,mode);else if(sizey==32) OLED_ShowChinese32x32(x,y,s,sizey,mode);else return;s+=2;x+=sizey;}
}//******************************************************************************
//    函数说明:OLED显示汉字
//    入口数据:x,y :起点坐标
//              *s  :要显示的汉字
//              sizey 字符高度
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_ShowChinese16x16(u8 x,u8 y,u8 *s,u8 sizey,u8 mode)
{u8 i,j,k,t,DATA=0,HZnum;u16 TypefaceNum;x/=2;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;//字符所占字节数HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);  //统计汉字库数目t=sizey/8;for(k=0;k<HZnum;k++){if ((tfont16[k].Index[0]==*(s))&&(tfont16[k].Index[1]==*(s+1))){    for(i=0;i<TypefaceNum;i++){if(i%t==0){OLED_AddressSet(x,y);y++;}for(j=0;j<4;j++){if(tfont16[k].Msk[i]&(0x01<<(j*2+0))){DATA=0xf0;}if(tfont16[k].Msk[i]&(0x01<<(j*2+1))){DATA|=0x0f;}if(mode){OLED_WR_Byte(~DATA);}else{OLED_WR_Byte(DATA);}DATA=0;}}}                  continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
}//******************************************************************************
//    函数说明:OLED显示汉字
//    入口数据:x,y :起点坐标
//              *s  :要显示的汉字
//              sizey 字符高度
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_ShowChinese24x24(u8 x,u8 y,u8 *s,u8 sizey,u8 mode)
{u8 i,j,k,t,DATA=0,HZnum;u16 TypefaceNum;x/=2;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;//字符所占字节数HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);  //统计汉字库数目t=sizey/8;for(k=0;k<HZnum;k++){if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1))){    for(i=0;i<TypefaceNum;i++){if(i%t==0){OLED_AddressSet(x,y);y++;}for(j=0;j<4;j++){if(tfont24[k].Msk[i]&(0x01<<(j*2+0))){DATA=0xf0;}if(tfont24[k].Msk[i]&(0x01<<(j*2+1))){DATA|=0x0f;}if(mode){OLED_WR_Byte(~DATA);}else{OLED_WR_Byte(DATA);}DATA=0;}}}                  continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
}//******************************************************************************
//    函数说明:OLED显示汉字
//    入口数据:x,y :起点坐标
//              *s  :要显示的汉字
//              sizey 字符高度
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_ShowChinese32x32(u8 x,u8 y,u8 *s,u8 sizey,u8 mode)
{u8 i,j,k,t,DATA=0,HZnum;u16 TypefaceNum;x/=2;TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;//字符所占字节数HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);  //统计汉字库数目t=sizey/8;for(k=0;k<HZnum;k++){if ((tfont32[k].Index[0]==*(s))&&(tfont32[k].Index[1]==*(s+1))){    for(i=0;i<TypefaceNum;i++){if(i%t==0){OLED_AddressSet(x,y);y++;}for(j=0;j<4;j++){if(tfont32[k].Msk[i]&(0x01<<(j*2+0))){DATA=0xf0;}if(tfont32[k].Msk[i]&(0x01<<(j*2+1))){DATA|=0x0f;}if(mode){OLED_WR_Byte(~DATA);}else{OLED_WR_Byte(DATA);}DATA=0;}}}                  continue;  //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响}
}//******************************************************************************
//    函数说明:OLED显示字符函数
//    此函数适用范围:字符宽度是2的倍数  字符高度是宽度的2倍
//    入口数据:x,y   起始坐标
//              chr   要写入的字符
//              sizey 字符高度
//    返回值:  无
//******************************************************************************
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey,u8 mode)
{u8 i,j,c,k,t=4,temp,DATA=0;u16 num;x/=2;c=chr-' ';num=(sizey/16+((sizey%16)?1:0))*sizey;k=sizey/16;for(i=0;i<num;i++){if(sizey==16)temp=ascii_1608[c][i];//调用8x16字符else if(sizey==24)temp=ascii_2412[c][i];//调用12x24字符else if(sizey==32)temp=ascii_3216[c][i];//调用16x32字符
//      else if(sizey==48)temp=ascii_4824[c][i];//调用24x48字符else return;if(sizey%16){k=sizey/16+1;if(i%k) t=2;else t=4;}if(i%k==0){OLED_AddressSet(x,y);y++;}for(j=0;j<t;j++){if(temp&(0x01<<(j*2+0))){DATA=0xf0;}if(temp&(0x01<<(j*2+1))){DATA|=0x0f;}if(mode){OLED_WR_Byte(~DATA);}else{OLED_WR_Byte(DATA);}DATA=0;}}
}//******************************************************************************
//    函数说明:OLED显示字符串
//    入口数据:x,y  起始坐标
//              *dp   要写入的字符
//              sizey 字符高度
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_ShowString(u8 x,u8 y,u8 *dp,u8 sizey,u8 mode)
{while(*dp!='\0'){OLED_ShowChar(x,y,*dp,sizey,mode);dp++;x+=sizey/2;}
}//******************************************************************************
//    函数说明:m^n
//    入口数据:m:底数 n:指数
//    返回值:  result
//******************************************************************************
u32 oled_pow(u16 m,u16 n)
{u32 result=1;while(n--)result*=m;    return result;
}//******************************************************************************
//    函数说明:OLED显示变量
//    入口数据:x,y :起点坐标
//              num :要显示的变量
//              len :数字的位数
//              sizey 字符高度
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_ShowNum(u8 x,u8 y,u32 num,u16 len,u8 sizey,u8 mode)
{           u8 t,temp;u8 enshow=0;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)*t,y,' ',sizey,mode);continue;}else enshow=1; }OLED_ShowChar(x+(sizey/2)*t,y,temp+'0',sizey,mode); }
}//******************************************************************************
//    函数说明:显示灰度图片
//    入口数据:x,y :起点坐标
//              length 图片长度
//              width  图片宽度
//              BMP[] :要显示图片
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_DrawBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode)
{u8 i,j;u16 k=0;x/=2;length=length/2+((length%2)?1:0);for(i=0;i<width;i++){OLED_AddressSet(x,y+i);for(j=0;j<length;j++){if(mode){OLED_WR_Byte(~BMP[k++]);}else{OLED_WR_Byte(BMP[k++]);}}}
}//******************************************************************************
//    函数说明:显示灰度图片
//    入口数据:x,y :起点坐标
//              length 图片长度
//              width  图片宽度
//              BMP[] :要显示图片
//              mode  0:正常显示;1:反色显示
//    返回值:  无
//******************************************************************************
void OLED_DrawSingleBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode)
{u8 i,j,k,DATA=0;u16 m=0;length=length/8+((length%8)?1:0);x/=2;for(i=0;i<width;i++){OLED_AddressSet(x,y+i);for(j=0;j<length;j++){for(k=0;k<4;k++){if(BMP[m]&(0x01<<(k*2+0))){DATA=0xf0;}if(BMP[m]&(0x01<<(k*2+1))){DATA|=0x0f;}if(mode){OLED_WR_Byte(~DATA);}else{OLED_WR_Byte(DATA);}DATA=0;}m++;}}
}

以上SPI用到的是STM32的SPI2当中,时钟挂接在36M的PCLK1分频得到,预分频设置为最大值256(36M/256 = 0.14M)
SCLK的频率为140KHz,Tsclk:14.0us

2.字库头文件

代码如下(示例):

#ifndef __OLED_H
#define __OLED_H #include "sys.h"#define USE_HORIZONTAL 0                      //设置显示方向 0:正向显示;1:旋转180度显示#define OLED_SPI_MODE   0                                   //设置硬件SPI或软件IIC  0:硬件SPI; 1:软件IIC
#define OLED_IIC_MODE   1                                   //设置硬件SPI或软件IIC  0:硬件SPI; 1:软件IIC//SCL=SCLK
//SDA=MOSI
//RES=RES
//DC=DC
//CS=CS1
//FS0=MOSI
//CS2=CS2
//-----------------OLED端口定义---------------- #define OLED_GPIO_ClockCmd                                   RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB
#define OLED_GPIO_SCL_PORT                                   GPIOA
#define OLED_GPIO_SCL_PIN                                    GPIO_Pin_8
#define OLED_GPIO_SCL_CLK                                    RCC_AHB1Periph_GPIOA #define OLED_GPIO_SDA_PORT                                 GPIOA
#define OLED_GPIO_SDA_PIN                                    GPIO_Pin_5
#define OLED_GPIO_SDA_CLK                                    RCC_AHB1Periph_GPIOA #define OLED_GPIO_RES_PORT                                 GPIOA
#define OLED_GPIO_RES_PIN                                    GPIO_Pin_15
#define OLED_GPIO_RES_CLK                                    RCC_APB1Periph_GPIOA #define OLED_GPIO_DC_PORT                                  GPIOB
#define OLED_GPIO_DC_PIN                                     GPIO_Pin_6
#define OLED_GPIO_DC_CLK                                     RCC_APB1Periph_GPIOB #define OLED_GPIO_CS_PORT                                  GPIOB
#define OLED_GPIO_CS_PIN                                     GPIO_Pin_7
#define OLED_GPIO_CS_CLK                                     RCC_APB1Periph_GPIOB #define ZK_GPIO_CS_PORT                                        GPIOA
#define ZK_GPIO_CS_PIN                                       GPIO_Pin_0
#define ZK_GPIO_CS_CLK                                       RCC_APB1Periph_GPIOA#define ZK_GPIO_FS0_PORT                                        GPIOA
#define ZK_GPIO_FS0_PIN                                      GPIO_Pin_4
#define ZK_GPIO_FS0_CLK                                      RCC_APB1Periph_GPIOA#define ZK_SPIx                                                     SPI1
#define ZK_SPI_APBxClock_FUN                                     RCC_APB2PeriphClockCmd
#define ZK_SPI_CLK                                               RCC_APB2Periph_SPI1
#define ZK_SPI_GPIO_AF                                                           GPIO_AF_SPI1
#define ZK_GPIO_PinSource_SCL                                                GPIO_PinSource3
#define ZK_GPIO_PinSource_SDA                                                GPIO_PinSource5
#define ZK_GPIO_PinSource_FS0                                            GPIO_PinSource4#define OLED_SCL_Clr() GPIO_ResetBits(OLED_GPIO_SCL_PORT,OLED_GPIO_SCL_PIN)//SCL
#define OLED_SCL_Set() GPIO_SetBits(OLED_GPIO_SCL_PORT,OLED_GPIO_SCL_PIN)#define OLED_SDA_Clr() GPIO_ResetBits(OLED_GPIO_SDA_PORT,OLED_GPIO_SDA_PIN)//SDA
#define OLED_SDA_Set() GPIO_SetBits(OLED_GPIO_SDA_PORT,OLED_GPIO_SDA_PIN)#define OLED_RES_Clr()  GPIO_ResetBits(OLED_GPIO_RES_PORT,OLED_GPIO_RES_PIN)//RES
#define OLED_RES_Set()  GPIO_SetBits(OLED_GPIO_RES_PORT,OLED_GPIO_RES_PIN)#define OLED_DC_Clr()  GPIO_ResetBits(OLED_GPIO_DC_PORT,OLED_GPIO_DC_PIN)//DC
#define OLED_DC_Set()  GPIO_SetBits(OLED_GPIO_DC_PORT,OLED_GPIO_DC_PIN)#define OLED_CS_Clr()  GPIO_ResetBits(OLED_GPIO_CS_PORT,OLED_GPIO_CS_PIN)//CS1
#define OLED_CS_Set()  GPIO_SetBits(OLED_GPIO_CS_PORT,OLED_GPIO_CS_PIN)#define ZK_CS_Clr()  GPIO_ResetBits(ZK_GPIO_CS_PORT,ZK_GPIO_CS_PIN)//CS2
#define ZK_CS_Set()  GPIO_SetBits(ZK_GPIO_CS_PORT,ZK_GPIO_CS_PIN)#define ZK_READ_FS0()   GPIO_ReadInputDataBit(ZK_GPIO_FS0_PORT,ZK_GPIO_FS0_PIN)//FS0u8 SPI1_ReadWriteByte(u8 TxData);//显示屏功能函数
void OLED_WR_REG(u8 reg);                   //写入一个指令
void OLED_WR_Byte(u8 dat);              //写入一个数据
void OLED_AddressSet(u8 x,u8 y);    //设置起始坐标函数
void OLED_Clear(void);                      //清平函数
void OLED_Fill(u16 x1,u8 y1,u16 x2,u8 y2,u8 color);                  //填充函数
void OLED_ShowChinese(u8 x,u8 y,u8 *s,u8 sizey,u8 mode);         //显示汉字串
void OLED_ShowChinese16x16(u8 x,u8 y,u8 *s,u8 sizey,u8 mode);//显示16x16汉字
void OLED_ShowChinese24x24(u8 x,u8 y,u8 *s,u8 sizey,u8 mode);//显示24x24汉字
void OLED_ShowChinese32x32(u8 x,u8 y,u8 *s,u8 sizey,u8 mode);//显示32x32汉字
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 sizey,u8 mode);           //显示单个字符
void OLED_ShowString(u8 x,u8 y,u8 *dp,u8 sizey,u8 mode);         //显示字符串
void OLED_ShowNum(u8 x,u8 y,u32 num,u16 len,u8 sizey,u8 mode);//显示整数变量
void OLED_DrawBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode);            //显示灰度图片
void OLED_DrawSingleBMP(u8 x,u8 y,u16 length,u8 width,const u8 BMP[],u8 mode);//显示单色图片
void OLED_Init(void);//字库函数
void ZK_command(u8 dat);            //向字库发送命令
u8  get_data_from_ROM(void);    //从字库度一个数据
void get_n_bytes_data_from_ROM(u8 AddrHigh,u8 AddrMid,u8 AddrLow,u8 *pBuff,u8 DataLen );//从字库读DataLen个数据
void Display_GB2312_String(u16 x,u8 y,u8 text[],u8 zk_num,u8 mode);                                         //显示汉字字符串
void Display_GB2312(u16 x,u8 y,u8 zk_num,u8 mode);                                                                          //显示汉字
void Display_Asc_String(u16 x,u8 y,u8 text[],u8 zk_num,u8 mode);                                                //显示ASCII 字符串
void Display_Asc(u16 x,u8 y,u8 zk_num,u8 mode);                                                                                 //显示ASCII
void Display_GBasc_String(u16 x,u8 y,u8 text[],u8 zk_num,u8 mode);                                          //显示GB2312 ascii 字符串
void Display_GBasc(u16 x,u8 y,u8 zk_num,u8 mode);                                                                               //显示GB2312 ascii void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler);
u8 SPI1_ReadWriteByte(u8 TxData);
void SPI1_Init(void);
void OLED1_Init(void);
#endif

3.主函数

//              GND    电源地
//              VCC  3.3v电源
//              D0   PB3(SCL)
//              D1   PB5(SDA)
//              RES  PD6
//              DC   PD7
//              CS1  PF9
//              FS0  PB4
//              CS2  PF10 #include "sys.h"
#include "delay.h"
#include "led.h"
#include "oled.h"
#include "bmp.h"int main(void)
{delay_init(168);
//  uart_init(115200);            //初始化USARTOLED_Init();while(1){GPIO_ResetBits(GPIOA, GPIO_Pin_15);delay_ms(1000);GPIO_SetBits(GPIOA, GPIO_Pin_15);delay_ms(1000);OLED_DrawBMP(0,0,256,64,gImage_1,0);//灰度图片显示delay_ms(1000);OLED_Clear();OLED_DrawSingleBMP(0,0,256,64,gImage_2,0);//单色图片显示delay_ms(1000);OLED_Clear();Display_GB2312_String(0,26,"中",12,0);//GB2312_12*12Display_GB2312_String(12,24,"景",16,0);//GB2312_15*16Display_GB2312_String(28,20,"园",24,0);//GB2312_24*24Display_GB2312_String(52,16,"电",32,0);//GB2312_32*32Display_GB2312_String(84,16,"子",32,0);//GB2312_32*32Display_GB2312_String(128,16,"中",32,1);//GB2312_12*12Display_GB2312_String(160,16,"景",32,1);//GB2312_15*16Display_GB2312_String(192,20,"园",24,1);//GB2312_24*24Display_GB2312_String(216,24,"电",16,1);//GB2312_32*32Display_GB2312_String(232,26,"子",12,1);//GB2312_32*32delay_ms(1000);OLED_Clear();Display_Asc_String(0,0,"ASCII:5x7",7,0);//5x7 ASCIIDisplay_Asc_String(0,13,"ASCII:7x8",8,0);//7x8 ASCIIDisplay_Asc_String(0,26,"ASCII:6x12",12,0);//6x12 ASCIIDisplay_Asc_String(0,43,"ASCII:8x16",16,0);//8x16 ASCIIdelay_ms(1000);OLED_Clear();Display_Asc_String(0,0,"ASCII:5x7",7,1);//5x7 ASCIIDisplay_Asc_String(0,13,"ASCII:7x8",8,1);//7x8 ASCIIDisplay_Asc_String(0,26,"ASCII:6x12",12,1);//6x12 ASCIIDisplay_Asc_String(0,43,"ASCII:8x16",16,1);//8x16 ASCIIdelay_ms(1000);OLED_Clear();Display_Asc_String(0,0,"ASC12x24",24,0);//12x24 ASCIIDisplay_Asc_String(0,30,"ASC16x32",32,0);//16x32 ASCIIdelay_ms(1000);OLED_Clear();Display_Asc_String(0,0,"ASC12x24",24,1);//12x24 ASCIIDisplay_Asc_String(0,30,"ASC16x32",32,1);//16x32 ASCIIdelay_ms(1000);//      Display_GB2312_String(16*0,0,"当",16,0);//GB2312_32*32
//      Display_GB2312_String(16*1,0,"前",16,0);//GB2312_32*32
//      Display_GB2312_String(16*2,0,"距",16,0);//GB2312_32*32
//      Display_GB2312_String(16*3,0,"离",16,0);//GB2312_32*32
//      Display_GB2312_String(16*4,0,":",16,0);//GB2312_32*32
//      Display_Asc_String(16*5,0,"32",16,0);//16x32 ASCII//      Display_GB2312_String(16*0,16,"设",16,0);//GB2312_32*32
//      Display_GB2312_String(16*1,16,"置",16,0);//GB2312_32*32
//      Display_GB2312_String(16*2,16,"距",16,0);//GB2312_32*32
//      Display_GB2312_String(16*3,16,"离",16,0);//GB2312_32*32
//      Display_GB2312_String(16*4,16,":",16,0);//GB2312_32*32
//      Display_Asc_String(16*5,16,"32",16,0);//16x32 ASCII//     Display_GB2312_String((12*0)+34,52,"设",12,0);//GB2312_32*32
//      Display_GB2312_String((12*1)+34,52,"置",12,0);//GB2312_32*32
//      Display_GB2312_String((12*2)+34,52,"距",12,0);//GB2312_32*32
//      Display_GB2312_String((12*3)+34,52,"离",12,0);//GB2312_32*32
//      Display_GB2312_String((12*4)+34,52,":",12,0);//GB2312_32*32//     Display_GB2312_String((12*0)+34,52,"设置",12,0);//GB2312_32*32
//      delay_ms(2000);OLED_Clear();}
}

“高通”字库芯片的使用方法相关推荐

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

    连续两个月的加班,给ODM客户生产温控器订单,今天终于顺利发货,对于工程师出身的我,终于可以对着电脑,消停几天,研究技术,分享技术了,闲话少说,直接进入正题: 半年前有个老客户介绍个中央某院的项目,我 ...

  2. E8卡 linux 系统 读写 高通 字库芯片

    在E8卡上通过linux的spi驱动读写高通字库芯片. spi是分主从的,字库芯片不会主动通过spi发送数据.只有在linux上发起读操作的时候,字库才会把他的数据发送出来. /* * spi mod ...

  3. 高通8155车载芯片_WEY来“摩卡”云首秀,搭载高通8155芯片

    本期亮点  "咖啡"一词源自埃塞俄比亚的一个名叫卡法的古镇,在希腊语中"Kaweh"的意思是"力量与热情",而摩卡咖啡代表着创新和更多可能性 ...

  4. 云栖科技评论第28期:高通宣布芯片内置亚马逊Alexa

    1.高通宣布芯片内置亚马逊Alexa 高通宣布芯片内置亚马逊Alexa [新闻摘要]高通宣布,旗下收购公司CSR的8670/8675芯片系列将内置亚马逊Alexa唤醒词支持.CSR蓝牙芯片占据业界高端 ...

  5. 芯片对蓝牙耳机影响有多大?南卡N2s发布,搭载高通3040芯片

    被众多数码媒体.评测机构誉为"最具性价比蓝牙耳机"的Nank南卡N2s今年又有新动作,发布了Nank南卡N2系列的升级版本Nank南卡N2s真无线蓝牙耳机. 作为升级版,Nank南 ...

  6. 高通MSM8998芯片参考资料免费下载

    高通MSM8998芯片参考资料免费下载 今日分享是高通MSM8998芯片的基础知识,现在分享是比较基础的资料,还有其他的项目案例和参考资料找个时间再分享出来,资料都在闯客网技术论坛上,也是可以免费下载 ...

  7. 高通MSM8998芯片数据资料参考

    高通MSM8998芯片数据资料参考 今日分享是高通MSM8998芯片的基础知识,现在分享是比较基础的资料,还有其他的项目案例和参考资料找个时间再分享出来,资料都在闯客网技术论坛上,也是可以免费下载的, ...

  8. 鸿蒙os适配平板,华为新平板搭载高通4G芯片,鸿蒙OS已适配完成,友商随时可用...

    上半年大家最期待,却又一直被鸽的产品有两款.一款是小米平板5,第三方放了很多烟雾弹,结果被官宣在下半年发布.另外一款是华为P50系列手机,从3月份就一直传,一直到现在都没有具体的发布时间.小米的平板会 ...

  9. 高通MDM9628芯片数据参考

    高通MDM9628芯片数据参考 啊哈哈,分享完MTK的芯片资料,现在来个MDM9628芯片的资料吧,只是想把所有的资料都分享出来给大家,所有高通的芯片资料都在闯客网技术论坛了,加群也可以获取资料,高通 ...

最新文章

  1. 聊聊 Service 命名与设计
  2. html5 ocr图片识别,OCR识别控件LEADTOOLS HTML5案例:整页OCR识别
  3. 修改Gravatar生成的默认头像
  4. 561. 数组拆分 I
  5. 谷歌浏览器加载外部 DLL 文件 关于chrome上的网银安全控件开发技术(chrome 调用本地dll)
  6. NLP自然语言处理系列-时间序列数据分析-趋势性、周期性、自相关性、冲量、差分、移动平均误差计算
  7. 思科为计算机配置ip命令,思科路由器配置IP方法
  8. Python 透视表
  9. FXGL JAVA游戏引擎 教程 .04 动画 (可爱乌贼娘)
  10. 微软E5账号OneDrive无法扩容解决方案(亲测有效)
  11. 《Python自然语言处理-雅兰·萨纳卡(Jalaj Thanaki)》学习笔记:07 规则式自然语言处理系统
  12. 手机端网页设计尺寸,手机端网页设计图片尺寸
  13. 【MATLAB】读取和写入文本文件
  14. 红色警戒3原版V1.00基址大全
  15. 用C语言求三个数的最大值与排序
  16. 戴尔ChromeBook 13-7310刷Ubutu18.04
  17. 暗黑破坏神不朽国服什么时候上线 暗黑破坏神不朽延期原因
  18. 安卓耗电监控app_拍照成罪魁祸首 十大安卓耗电App排行公布
  19. vue移动端高德地图的使用及实现最简单的地图功能
  20. 引入antd组件样式,按需引入的高级配置

热门文章

  1. win10系统下Bitlocker密码忘了的具体解决方法
  2. 汽车驱动力及发动机转矩曲线在python中拟合
  3. vue 引入高德地图 路线规划
  4. Shiro 生成秘钥
  5. python中怎么表示阶乘_python阶乘怎么写
  6. CCNA 2网络设备总结
  7. Python之进程 3 - 进程池和multiprocess.Poll
  8. 记2020年第十一届蓝桥杯感想
  9. XSS挑战之旅[全20关]上
  10. 高校新闻抓取分析之百度新闻篇---数据抓取