数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 2239|回复: 4

[other] STC驱动教程系列——CDC驱动虚拟OLED显示汉字字符

[复制链接]
发表于 2022-10-20 09:28:08 | 显示全部楼层 |阅读模式
本帖最后由 国学芯用 于 2022-10-20 15:19 编辑

一、前言
        看到STC家最近最新推出了STC32G(PS:STC8H8K64与他功能类似),看到了全网首发的一个USB-CDC的虚拟串口功能,号称不用USBTTL的芯片,只需要单片机通过USB连接电脑就可以实现串口通信,甚至在ISP软件上还有虚拟的各种设备可以直接驱动看效果(显示效果如下图),果断联系销售要了一个试试性能。
当然,因为DEMO程序可能有些刚入门的小伙伴不会使用,在这里我特出一期教程帮助大家入门,本教程围绕开天斧主板,最终实现功能如下:(详情见演示视频)
    1.直接驱动和缓存驱动两种驱动方式;
    2.内建汉字字库索引和ascll字符库,能实现汉字和字符的任意显示;
    3.缓存驱动实现画点函数和简易划线函数;
    4.虚拟键盘实现6OLED页面的功能演示。

二、实现过程        
2.1工程的建立
  因为已知有现成的OLED的驱动函数,所以我们这里直接寻找一个现成的示例代码导入,当然想要从零新建一个工程的可以直接参考STC8H的手册实现,这里为了精简,我就直接从官网下载一个最新的示例代码库了。直接登录官网http://www.STCAI.com/,找到下图中的“开天斧-STC8H-实验板演示程序”下载下来。
解压出来找到历程包里有如下两个文件
随后,我们给他复制到一个新的文件夹,得到一个新的工程,具体如下(有需要的可以给16-STC开头的的那个文件夹改个名字,这里为了演示方便就不修改了),这里前一个文件夹是用户代码,COMM文件夹里是STCUSB相关的驱动库,为了后期方便升级替换,这里就放在了工程目录里
然后打开工程文件夹,开始编译工程。打开16-STC-ISP调试接口通过USB CDC协议驱动虚拟设备”文加夹,双击“stc_usb_ser.uvproj”即可打开工程,然后开始编译,如下图说明编译成功。
2.2工程下载
  这里选择开天斧作为主控,先按下板子上的P3.2按钮不松开,然后按一下板子上的OFF按钮并松开,此事在松开P3.2按钮,然后打开ISP软件,随后按照下图配置:

2.3工程测试(按照如下图一步一步的设置)
然后分别打开STC调试接口里的“虚拟键盘”和“OLED-128*64”。
具体的功能可以见这个程序的注释,可以直接按下这个键盘上对应的按钮进行操作(例如按下虚拟键盘上的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个大行(因为一次写8bit,这里8个大行*8bit(八个小行)刚好64bit),且每个byte的数据发过去高位在下,低位在上。也就是说整屏幕的刷新广汇能源要显示数据一共是128*8个,每次发送的数据在的位数对应下图。横向8行,竖向128列,写入的1024个字节的数据中,第一个字节在第一行第一列,第128个字节在第一行第127列。
因为上表中单独一行中,每个列都是1个字节的,换成二进制数就是8个位。例如0X01,这是一个16进制数,也是一个字节的数据,写成二进制数就是0000 0001b,可以看到他前面有70,末尾有11。我们知道1代表点亮,也就是说这一大行的八个小行里,第一个小行的那个位置会被点亮。

  知道了这个驱动逻辑,那我们就可以开始取字模了,首先是写1点亮,这属于阴码格式,以行位单位,每次8个位的写数据,属于列行式,高位在下,低位在上属于逆向。所以取模软件的设置如下。
所以到了这里想玩转这个显示屏就很简单了,想点亮作为为(0,0,)的点,我们只需要通过这个函数void OLED12864_ShowPicture(BYTE x, BYTE y, BYTE cx, BYTE cy, BYTE *dat);,将他的xy坐标都设置为0就可以指向原点位置,cxcy都设置为1表示只需要输出一个字节,因为点亮的位置是在最上面,所以参数就是0x01即可。
  一个ascll就是横向写八个字节的数据,在换一行在写8个字节的数据,确定好xy的地址之后,数据起始的指针指向这个字符对应的数组开始的地方就可以了。

2.5:实际测试(另外,不建议用这个方式,所以这里不细展开讲解了,推荐第三章的方式)



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 1家元 +40 收起 理由
家睦 + 40

查看全部打赏

 楼主| 发表于 2022-10-20 09:41:27 | 显示全部楼层
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);       //亮度值(范围0255(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[0]== GBK16.gbn_bum[0] )&&( gbk[1]== GBK16.gbn_bum[1] ))
        {
            OLED12864_ShowPicture(x,y, 16, 2, (BYTE *)&GBK16.gbk_font[0]);  
        }
    }  
}
void OLED_ShowString(unsigned char x,unsigned char y,char *s)
{
    char s_num[2];
        while(*s != '\0')       //字符串不为空,循环
        {
        if ((unsigned char)*s < 0x80)     //根据输入数据的大小判断是字符还是汉字,
        {
            OLED_ShowChar(x,y,*s);
            x+=8;
            s++;
        }
        else
        {
            s_num[0] = *s ;
            s_num[1] = *(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[][8]=         
{
  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[32];
    unsigned char gbn_bum[2];
};
const  struct 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>
在主函数中,siwtch中只保留这几行,别的都删掉
  然后将其中的几行语句改成:
<font size="3"> switch (UsbOutBuffer[5])
                {
                    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,34就可以按顺序出现下面的字了。
三、高级驱动
  首先定义一片缓存区域,因为我们上面讲到一次会输出1024个字节的数据,且这些数据代表了八个大行和128个列。
unsigned char xdata ShowBUFF[8][128];
3.1点的显示:我们刚刚已经分析过了,怎么去点亮一个点,那么这里先来显示一个点,
<font size="3">void OLED_BuffShowPoint(unsigned char x,unsigned char y)     //OLED显示一个dian,x:0-127,y:0-63
{
    ShowBUFF[y/8][x] |= 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[j+y][x+k]=Ascll_16[(asc-' ')*2][j*8+k];
        }
    }   
}</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[0]== GBK16.gbn_bum[0] )&&( gbk[1]== GBK16.gbn_bum[1] ))
        {
            for( j=0;j<2;j++ )
            {
                for( k=0;k<16;k++ )
                {
                    ShowBUFF[j+y][x+k]=GBK16.gbk_font[j*16+k];
                }
            }
            break;
        }
    }   
}</font>
这里还有一个汉字显示的程序,大家可以先自己分析一下,这个的实现原理,后面我会单独把答案放评论区里和群里。
3.4汉字和字符的混合现实
<font size="3">void OLED_BuffShowString(unsigned char x,unsigned char y,char *s)
{
    char s_num[2];
        while(*s != '\0')       //字符串不为空,循环
        {
        if ((unsigned char)*s < 0x80)     //根据输入数据的大小判断是字符还是汉字,
        {
            OLED_BuffShowChar(x,y,*s);
            x+=8;
            s++;
        }
        else
        {
            s_num[0] = *s ;
            s_num[1] = *(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[5])
                {
                    
                    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-127y坐标0-63
                        OLED_BuffShowLine(20,50,108,50);        //
                        OLED_BuffShow();                        //缓存显示一定要开显示
                        break;                                
                    
                }</font>
最后就能完美的运行起来了,运行效果见开头的视频哈。或者这里留下几个截图


看完了文章,觉得有用的请在文末点个赞哈哈undefined

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2022-10-20 16:47:52 | 显示全部楼层
    使用USB接口进行数据通信非常方便,在STC-ISP软件上STC USB-CDC/就是串口还能驱动:模拟LED灯,数码管,12864 屏,以及虚拟键盘的输入等功能。  STC最快的1T8051STC8H8K64U核心功能实验板 (开天斧),免费送,来电0513-55012928申请哦!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2022-10-22 10:07:40 | 显示全部楼层
图7,第2步骤小错误纠正一下:因为走的是USB-HID通信协议,不需要安装任何驱动的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2022-10-22 10:10:40 | 显示全部楼层
图7,步骤2有点小错误,纠正下:因为走的是USB-HID通信协议,不需要安装任何驱动的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-6-30 20:14 , Processed in 0.218400 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表