STC USB-CDC虚拟串口驱动教程系列——虚拟OLED显示汉字
开帖序言===内含如何做汉字字模首先庆祝一下STC终于开放了自己的论坛,STC家的单片机用来快十年了一直很好用,尤其是最新款的STC32G,可以说把51核的单片机性能提升了一个境界:lol。作为一个热心的电子工程师以后我会在这里经常分享一些驱动类的教程(如果此刻屏幕前的看官们需要STC的某些驱动,可以留言给我,如果需要的人多的话我会考虑出一期完整的教程专门讲解)。当然我也会偶尔发一些开源小项目,主要以STC为主(在这里需要重点感谢一下STC给我送来的核心板等,重点实名表扬一下STC的聂(qq:2593903262)和STC的吴(qq:1463035472),感谢他们近期对我开源的大力支持,以及感谢所有STC的工作人员的辛勤付出,如果你们看完我的文章,有需要板子的朋友也可以去找他们(添加其中一个就可以啦)看看能不能免费申请一个。(当然申请渠道多多,联系任意一个STC的销售人员,或者官网电话亦可),只要对电子感兴趣,愿意动手的,想学习STC的,无论你是个人还是单位,无论是学生还是打工人均可以尝试着申请一下),另外在这里还要特别感谢一下STC的姚总,为大家提供了各类免费的开发板学习,为电子这一行做出了巨大的贡献,感谢姚总!!祝愿STC越做越大,越做越强!!
另外原创不易,转载请注明出处,谢谢。(想联系我的可以加官方入驻的QQ大群:453616422或者个人的QQ小群:884047237,随便加一个群就好了,两个群里都有STC的官方人员可以免费申请板子,都可以下载附件)第一次发文,有什么不好的地方欢迎大家指出,也欢迎大家留下好的建议,如果看完了全文希望也能你留下你的足迹,另外希望我的文章能对大家有所帮助,最后祝大家事业有成。
一、前言
看到STC家最近最新推出了STC32G(PS:STC8H8K64U与他功能类似),看到了全网首发的一个USB-CDC的虚拟串口功能,号称不用USB转TTL的芯片,只需要单片机通过USB连接电脑就可以实现串口通信,甚至在ISP软件上还有虚拟的各种设备可以直接驱动看效果(显示效果如下图),果断联系销售要了一个试试性能。
当然,因为DEMO程序可能有些刚入门的小伙伴不会使用,在这里我特出一期教程帮助大家入门,本教程围绕开天斧(STC8H8K64U主控)主板,最终实现功能如下:(详情见演示视频) 1.直接驱动和缓存驱动两种驱动方式; 2.内建汉字字库索引和ascll字符库,能实现汉字和字符的任意显示; 3.缓存驱动实现画点函数和简易划线函数; 4.虚拟键盘实现6个OLED页面的功能演示
二、实现过程 2.1工程的建立因为已知有现成的OLED的驱动函数,所以我们这里直接寻找一个现成的示例代码导入,当然想要从零新建一个工程的可以直接参考STC8H的手册实现,这里为了精简,我就直接从官网下载一个最新的示例代码库了。直接登录官网https://stcai.com/hxgnsyb,找到下图中的“开天斧”下载下来。解压出来找到历程包里有如下两个文件:随后,我们给他复制到一个新的文件夹,得到一个新的工程,具体如下(有需要的可以给16-STC开头的的那个文件夹改个名字,这里为了演示方便就不修改了),这里前一个文件夹是用户代码,COMM文件夹里是STC的USB相关的驱动库,为了后期方便升级替换,这里就放在了工程目录里然后打开工程文件夹,开始编译工程。打开“16-STC-ISP调试接口通过USB CDC协议驱动虚拟设备”文加夹,双击“stc_usb_ser.uvproj”即可打开工程,然后开始编译,如下图说明编译成功。
2.2工程下载这里选择开天斧作为主控,先按下板子上的P3.2按钮不松开,然后按一下板子上的OFF按钮并松开,此时在松开P3.2按钮,然后打开ISP软件,随后按照下图配置并下载程序。2.3工程测试(按照如下图一步一步的设置)
然后分别打开STC调试接口里的“虚拟键盘”和“OLED-128*64”。然后看到我们的程序里,从按键P到按键NEXT都是关于OLED的操作具体的功能可以见这个程序的注释,可以直接按下这个键盘上对应的按钮进行操作(例如按下虚拟键盘上的R就会打开显示,Q就会关闭显示)。但是看完了这个程序很多人会好奇,怎么只有一个显示图片的程序呢,我就想给他显示一个字母,我要怎么操作呢,怎么这里连显示一个字母的函数都没有呢?
2.4驱动逻辑分析看到“STC调试接口”里的调试接口协议,里面有全部的OLED的驱动函数,可以看到全部的函数如下图所示,仔细分析下来操作屏幕显示的只有一行OLED12864_ShowPicture的函数,所以我们要想在屏幕上显示一个字母,就得首先从这个函数入手。可以看到这个有这么一个函数:void OLED12864_ShowPicture(BYTE x, BYTE y, BYTE cx, BYTE cy, BYTE *dat);他的入口参数是一个指针,一般都是指向一个数组的首地址,那么显示一个数组的就必须要知道他对应的数组里存放的顺序,我们看到这个SSD1306的手册,重点部分如下截图:已知默认OLED用的水平寻址模式,参考OLED的手册,可以看到该模式下他将128*64的像素点分成了纵向的128列,横向的8个大行(因为一次写8个bit,这里8个大行*8bit(八个小行)刚好64bit),且每个byte的数据发过去高位在下,低位在上。也就是说整屏幕的刷新广汇能源要显示数据一共是128*8个,每次发送的数据在的位数对应下图。横向8行,竖向128列,写入的1024个字节的数据中,第一个字节在第一行第一列,第128个字节在第一行第127列。因为上表中单独一行中,每个列都是1个字节的,换成二进制数就是8个位。例如0X01,这是一个16进制数,也是一个字节的数据,写成二进制数就是0000 0001b,可以看到他前面有7个0,末尾有1个1。我们知道1代表点亮,也就是说这一大行的八个小行里,第一个小行的那个位置会被点亮。
知道了这个驱动逻辑,那我们就可以开始取字模了,首先是写1点亮,这属于阴码格式,以行位单位,每次8个位的写数据,属于列行式,高位在下,低位在上属于逆向。所以取模软件的设置如下。当然,为了我们建立字库的时候更加方便,完整的取模设置可以参考下图:所以到了这里想玩转这个显示屏就很简单了,想点亮作为为(0,0,)的点,我们只需要通过这个函数void OLED12864_ShowPicture(BYTE x, BYTE y, BYTE cx, BYTE cy, BYTE *dat);,将他的x,y坐标都设置为0就可以指向原点位置,cx和cy都设置为1表示只需要输出一个字节,因为点亮的位置是在最上面,所以参数就是0x01即可。 一个ascll字符就是横向写八个字节的数据,在换一行在写8个字节的数据,确定好x和y的地址之后,数据起始的指针指向这个字符对应的数组开始的地方就可以了。
2.5:实际测试(另外,不建议用这个方式,所以这里不细展开讲解了,推荐第三章的方式)OLED.C文件内容如下:<font size="3">#include "oled.h"
#include <stdio.h>
#include <string.h>
#include "font.h"
/****************************************系统操作****************************************/
void OLED_Init(void) //OLED初始化
{
OLED12864_SetContrast(255); //亮度值(范围0~255)(255);//亮度最大
OLED12864_ScrollStop(); //停止滚屏
OLED12864_DisplayOn(); //打开OLED12864的显示
OLED12864_DisplayContent(); //显示屏幕内容
OLED12864_SetAddressMode(0x00); //
}
/****************************************直接驱动****************************************/
void OLED_ShowChar(unsigned char x,unsigned char y,char asc) //OLED显示一个8*16字符
{
OLED12864_ShowPicture(x, y, 8, 2, (BYTE *)&Ascll_16[(asc-' ')*2]);
}
void OLED_ShowGBK(unsigned char x,unsigned char y,char *gbk) //OLED显示一个16*16汉字
{
unsigned char i;
for( i=0;i<100;i++ )
{
if(( gbk== GBK16.gbn_bum )&&( gbk== GBK16.gbn_bum ))
{
OLED12864_ShowPicture(x,y, 16, 2, (BYTE *)&GBK16.gbk_font);
}
}
}
void OLED_ShowString(unsigned char x,unsigned char y,char *s)
{
char s_num;
while(*s != '\0') //字符串不为空,循环
{
if ((unsigned char)*s < 0x80) //根据输入数据的大小判断是字符还是汉字,
{
OLED_ShowChar(x,y,*s);
x+=8;
s++;
}
else
{
s_num = *s ;
s_num = *(s+1) ;
OLED_ShowGBK(x,y,s_num);
x+=16;
s+=2;
}
if(x>128)
{
x=0;
y+=16;
}
}
}</font>OLED.H文件内容如下:<font size="3">#ifndef __OLED_H
#define __OLED_H
#include "../comm/STC8h.h"//包含此头文件后,不需要再包含"reg51.h"头文件
#include "../comm/usb.h" //USB调试及复位所需头文件
void OLED_Init(void); //OLED初始化
void OLED_ShowChar(unsigned char x,unsigned char y,char asc); //OLED显示一个8*16字符
void OLED_ShowGBK(unsigned char x,unsigned char y,char *gbk); //OLED显示一个16*16汉字
void OLED_ShowString(unsigned char x,unsigned char y,char *s);
#endif</font>
FONT.H文件内容如下:(需要显示的内容需要取模放进来哦,不做字模的话无法识别)<font size="3">#ifndef __FONT_H
#define __FONT_H
/****************************************8*16的点阵************************************/
const char code Ascll_16[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
//阴码,列形式,逆向,
struct s_font
{
unsigned char gbk_font;
unsigned char gbn_bum;
};
conststruct s_font code GBK16[]=
{
0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,
0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00,"电",//0
0x80,0x82,0x82,0x82,0x82,0x82,0x82,0xE2,0xA2,0x92,0x8A,0x86,0x82,0x80,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,"子",//1
0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,
0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00,"小",//2
0x10,0x2C,0x24,0x24,0xA4,0xA4,0x65,0xA6,0x24,0x24,0x24,0x24,0xA4,0x34,0x0C,0x00,
0x40,0x49,0x49,0x29,0x24,0x14,0x52,0x89,0x7F,0x04,0x0A,0x11,0x10,0x20,0x20,0x00,"家",//3
0x00,0x04,0x04,0xF4,0x94,0x94,0x94,0x9F,0x94,0x94,0x94,0xF4,0x04,0x04,0x00,0x00,
0x40,0x40,0x40,0x7F,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7F,0x40,0x40,0x40,0x00,"直",//4
0x10,0x10,0x10,0xFF,0x10,0x50,0x44,0x54,0x65,0xC6,0x44,0x64,0x54,0x44,0x40,0x00,
0x04,0x44,0x82,0x7F,0x01,0x82,0x82,0x4A,0x56,0x23,0x22,0x52,0x4E,0x82,0x02,0x00,"接",//5
0x02,0xFA,0x82,0x82,0xFE,0x80,0x00,0xFE,0x02,0x12,0x62,0x82,0x62,0x1A,0x02,0x00,
0x08,0x18,0x48,0x84,0x44,0x3F,0x00,0x7F,0x50,0x48,0x46,0x41,0x46,0x58,0x40,0x00,"驱\xfd",//6
0x40,0x44,0xC4,0x44,0x44,0x44,0x40,0x10,0x10,0xFF,0x10,0x10,0x10,0xF0,0x00,0x00,
0x10,0x3C,0x13,0x10,0x14,0xB8,0x40,0x30,0x0E,0x01,0x40,0x80,0x40,0x3F,0x00,0x00,"动",//7
0x20,0x30,0xAC,0x63,0x30,0x02,0x26,0x2A,0xE2,0x26,0x29,0x21,0x29,0x25,0x00,0x00,
0x22,0x67,0x22,0x12,0x52,0x21,0x99,0x87,0x4D,0x55,0x25,0x55,0x4D,0x81,0x81,0x00,"缓",//8
0x04,0x04,0x84,0xE4,0x1C,0x07,0x24,0x24,0x24,0x24,0xA4,0x64,0x24,0x04,0x04,0x00,
0x02,0x01,0x00,0xFF,0x00,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x00,"存",//9
0x00,0x00,0xF8,0x49,0x4A,0x4C,0x48,0xF8,0x48,0x4C,0x4A,0x49,0xF8,0x00,0x00,0x00,
0x10,0x10,0x13,0x12,0x12,0x12,0x12,0xFF,0x12,0x12,0x12,0x12,0x13,0x10,0x10,0x00,"单",//0
0x80,0x80,0x40,0x20,0x10,0x08,0x04,0xC3,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,"个",//1
0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0x26,0xA4,0x64,0x24,0x04,0x04,0x14,0x0C,0x00,
0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,"字",//2
0x10,0x08,0x04,0x87,0x6C,0x14,0x84,0x94,0x88,0x87,0x84,0xEC,0x94,0x84,0x84,0x00,
0x04,0x02,0x01,0xFF,0x00,0x00,0x00,0x02,0x0C,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,"符",//3
0x10,0x60,0x02,0x0C,0xC0,0x02,0x1E,0xE2,0x02,0x02,0x02,0xE2,0x1E,0x00,0x00,0x00,
0x04,0x04,0x7C,0x03,0x80,0x80,0x40,0x20,0x13,0x0C,0x13,0x20,0x40,0x80,0x80,0x00,"汉",//4
0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0x26,0xA4,0x64,0x24,0x04,0x04,0x14,0x0C,0x00,
0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,"字",//5
0x00,0x00,0xC0,0x40,0x40,0x40,0x7F,0x48,0x48,0x48,0x48,0xC8,0x08,0x08,0x00,0x00,
0x80,0x40,0x37,0x04,0x04,0x14,0x64,0x04,0x14,0x64,0x04,0x07,0x10,0xE0,0x00,0x00,"点",//0
0x20,0x30,0xAC,0x63,0x20,0x18,0x80,0x90,0x90,0xFF,0x90,0x49,0x4A,0x48,0x40,0x00,
0x22,0x67,0x22,0x12,0x12,0x12,0x40,0x40,0x20,0x13,0x0C,0x14,0x22,0x41,0xF8,0x00,"线",//1
0x10,0x60,0x02,0x8C,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,
0x04,0x04,0x7E,0x01,0x00,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,"清",//0
0x00,0x00,0xFE,0x12,0x92,0xB2,0xD2,0x92,0x92,0x92,0xD2,0xB2,0x9E,0x00,0x00,0x00,
0x40,0x30,0x0F,0x04,0x84,0x64,0x1F,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x00,0x00,"屏",//1
0x00,0x10,0x90,0x92,0x52,0x32,0x12,0xFE,0x12,0x31,0x51,0x91,0x90,0x10,0x00,0x00,
0x01,0x81,0x80,0x40,0x31,0x0F,0x01,0x01,0x01,0x4D,0x8B,0x48,0x38,0x01,0x01,0x00,"秀",//2
0x10,0x60,0x02,0x8C,0x00,0x0C,0xA4,0xA4,0xA5,0xE6,0xA4,0xA4,0xA4,0x0C,0x00,0x00,
0x04,0x04,0x7E,0x01,0x00,0x80,0x4F,0x2A,0x0A,0x0F,0x0A,0x2A,0x4F,0x80,0x00,0x00,"演",//0
0x40,0x40,0x42,0x42,0x42,0x42,0x42,0xC2,0x42,0x42,0x42,0x42,0x42,0x40,0x40,0x00,
0x20,0x10,0x08,0x06,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x02,0x04,0x08,0x30,0x00,"示",//1
};
#endif </font>
在主函数中,switch中只保留这几行,别的都删掉 然后将其中的几行语句改成:<font size="3"> switch (UsbOutBuffer)
{
case VK_DIGIT_0:
OLED_Init();
break;
case VK_DIGIT_2:
OLED_ShowChar(0,0,'1');
break;
case VK_DIGIT_3:
OLED_ShowGBK(0,2,"电");
break;
case VK_DIGIT_4:
OLED_ShowString(0,4,"电子DIY小家");
break;
}
</font>随后按下键盘的0,2,3,4就可以按顺序出现下面的字了。三、高级驱动首先定义一片缓存区域,因为我们上面讲到一次会输出1024个字节的数据,且这些数据代表了八个大行和128个列。unsigned char xdata ShowBUFF;
3.1点的显示:我们刚刚已经分析过了,怎么去点亮一个点,那么这里先来显示一个点,<font size="3">void OLED_BuffShowPoint(unsigned char x,unsigned char y) //OLED显示一个dian,x:0-127,y:0-63
{
ShowBUFF |= 1<<(y%8);
}</font>上面的代码第一个y/8表示他在第几行,因为y坐标的取值是0-63,8个点才显示一行,所以除以8取整数就知道他在第几行了,x坐标取值0-127就直接写到对应的列的位置就好了。因为一次写入一个字节,那么这里就要判断这个点在这个字节中的第几个位置,上面y除以8之后,剩下的余数就是他的第几个位置。例如y取值是4,那么他在4/8也就是第0大行的位置,余数是4,说明他是第四小行,而1<<4就是把1往前移动4位。
3.2:字符的显示<font size="3">void OLED_BuffShowChar(unsigned char x,unsigned char y,char asc) //OLED显示一个8*16字符
{
unsigned char j,k;
for( j=0;j<2;j++ )
{
for( k=0;k<8;k++ )
{
ShowBUFF=Ascll_16[(asc-' ')*2];
}
}
}</font>首先这里的一个字符是8*16,那么他必然有一个循环两次的for,这样就可以实现两个大行的显示,这里就是 for( j=0;j<2;j++ )。其次他有八个列,那么需要循环八次,这里就是 for( k=0;k<8;k++ ),这样行和列的坐标就可以确定了,每次写的行就是j+y,列就是x+k。最后我们的取模的数组是从‘ ’开始按顺往下序取的,所以字符的开头减去这个就是起始坐标,其次在字库里一个字符分两行,所以第一个字符的坐标就是0,第二个字符就是2,所以这里第一个坐标要写成(asc-' ')*2,第二个坐标就是这个坐标里的第几个数据了,第一行就是k,第二行就是8+k。
3.3:汉字的显示<font size="3">void OLED_BuffShowGBK(unsigned char x,unsigned char y,char *gbk) //OLED显示一个16*16字符
{
unsigned char i;
unsigned char j,k;
for( i=0;i<150;i++ )
{
if(( gbk== GBK16.gbn_bum )&&( gbk== GBK16.gbn_bum ))
{
for( j=0;j<2;j++ )
{
for( k=0;k<16;k++ )
{
ShowBUFF=GBK16.gbk_font;
}
}
break;
}
}
}</font>这里还有一个汉字显示的程序,大家可以先自己分析一下,这个的实现原理,后面我会单独把讲解放评论区里和群里。
3.4汉字和字符的混合显示<font size="3">void OLED_BuffShowString(unsigned char x,unsigned char y,char *s)
{
char s_num;
while(*s != '\0') //字符串不为空,循环
{
if ((unsigned char)*s < 0x80) //根据输入数据的大小判断是字符还是汉字,
{
OLED_BuffShowChar(x,y,*s);
x+=8;
s++;
}
else
{
s_num = *s ;
s_num = *(s+1) ;
OLED_BuffShowGBK(x,y,s_num);
x+=16;
s+=2;
}
if(x>127)
{
x=0;
y+=2;
}
}
}</font>首先这个函数需要在输入的地方,判断输入的地方是不是为空,通过while(*s != '\0') 来实现,然后判断第一个字节的内码。因为在GBK的内码里,一个字符是1个字节,汉字是2个字节,且字符内码小于0x80,所以如果是字符,调用字符的程序,调用完了x坐标+8,然后指向的地址+1,去开始查询下个字节。汉字的内码是2个字节,显示玩一个汉字x坐标+16,指向的地址+2<font size="3">void OLED_BuffShow(void)
{
OLED12864_ShowPicture(0,0, 128,8, (BYTE *)&ShowBUFF);
}</font>因为用的缓存的办法实现,所有的需要显示的数据都在单片机内存里,需要显示的话一定要给他发出去才行,这里就是将8*128个数据一次性发出去显示出来。上述就是实现的全部过程了,程序里还有一个简单的划线函数(通过画点函数实现),留给屏幕前的你们自由发挥和想象,可以改写个画圆,画方的程序出来。
最后在主函数中插入这个:<font size="3"> switch (UsbOutBuffer)
{
case VK_DIGIT_0:
OLED_Init();
break;
case VK_DIGIT_1:
OLED_BuffClear();
OLED_ShowString(0,0,"OLED直接驱\xfd动演示");
OLED_ShowString(80,2,"--字符");
OLED_ShowChar(0,4,'1');
OLED_ShowString(0,6,"666");
break;
case VK_DIGIT_2:
OLED_BuffClear();
OLED_ShowString(0,0,"OLED直接驱\xfd动演示");
OLED_ShowString(80,2,"--汉字");
OLED_ShowGBK(0,4,"秀");
OLED_ShowString(0,6,"电子DIY小家"); //这一行函数可以自动判断汉字或者字符并显示
break;
case VK_DIGIT_3:
OLED_BuffClear();
OLED_ShowString(0,0,"OLED清屏");
break;
case VK_DIGIT_5:
OLED_BuffClear();
OLED_BuffShowString(0,0,"OLED缓存驱\xfd动演示");
OLED_BuffShowString(80,2,"--字符");
OLED_BuffShowChar(0,4,'1');
OLED_BuffShowString(0,6,"6666666");
OLED_BuffShow(); //缓存显示一定要开显示
break;
case VK_DIGIT_6:
OLED_BuffClear();
OLED_BuffShowString(0,0,"OLED缓存驱\xfd动演示");
OLED_BuffShowString(80,2,"--汉字");
OLED_BuffShowGBK(0,4,"秀");
OLED_BuffShowString(0,6,"电子DIY小家"); //这一行函数可以自动判断汉字或者字符并显示
OLED_BuffShow(); //缓存显示一定要开显示
break;
case VK_DIGIT_7:
OLED_BuffClear();
OLED_BuffShowString(0,0,"OLED缓存驱\xfd动演示");
OLED_BuffShowString(80,2,"--点线");
OLED_BuffShowPoint(0,40);
OLED_BuffShowPoint(64,40); //点和线的x坐标都是0-127,y坐标0-63
OLED_BuffShowLine(20,50,108,50); //
OLED_BuffShow(); //缓存显示一定要开显示
break;
}</font>最后就能完美的运行起来了,运行效果见视频哈。或者这里留下几个截图看完了文章,觉得有用的请在文末点个赞哈哈;P由于附件的空间受限,需要上述所需文件的请进群下载~
冲哥厉害!感谢分享 支持支持,STC单片机越做越好了 感谢 令狐大侠第一次下山,就:
左手开天斧-STC8H8K64U,右手屠龙刀-STC32G12K128,给 全球 32位8051世界 带来了令人震撼 的:科学计算器-STC32G12K128-屠龙刀、科学计算器-STC8H8K64U-开天斧
源码全部开源,硬件全部开源,已上传到STCAI.com应用方案|核心功能实验板 板块 的 屠龙刀三程序包、中应用方案|核心功能实验板 板块 的开天斧程序 包中。
感谢 令狐大侠的制作,感谢宏晶的分享! 超级强悍的技术贴,大补猛药 你每一篇技术贴含金量都这么高,牛 必须点赞。 这是2022年最精华的技术贴之一:) 令狐大侠不亏是令狐大侠,写的真详细,精华!!!
页:
[1]
2