小车调试进度三更~
写在前面: 我的主控板上OLED部分片选端CS是直接接地的,底层中除汉字显示和图片显示的部分我参照的是:【常用模块】OLED显示模块(原理讲解、STM32实例操作),博主关于原理方面讲解地也比较详细,里面也有一些基本的底层,比如显示字符、数字、字符串都有,下面我只贴出汉字显示和图片显示部分的代码,汉字显示部分我用了两种方法,emmm,都会贴出来。
//显示一个汉字
void OLED_ShowGBK(u8 x, u8 y, u8 num, u8 size,u8 mode)
{
u8 temp,t,t1;
u8 y0=y;
u8 csize=(size/8 + ((size%8)?1:0)) * size; //得到字体一个字符对应点阵集所占的字节数
for(t=0;t>=1;
y++;
if((y-y0)==size)
{
y=y0;
x++;
break;
}
}
}
}
//显示中文字符串
//x,y:起点坐标
//*p:字符串起始地址
//用1616字体
//i的取值取最长的中文字符串的长度
void OLED_ShowChinese(u8 x,u8 y,const int *p)
{
#define MAX_CHIN_POSX 120
#define MAX_CHIN_POSY 49
u8 i = 0;
while(i < 6)
{
if(x>MAX_CHIN_POSX){x=0;y+=16;}
if(y>MAX_CHIN_POSY){y=x=0;OLED_Clear();}
OLED_ShowGBK(x+16*i,y,*(p+i),16,1);
i+=1;
}
}
emmm,显示一个汉字的思想与显示字符的思想差不多,主要就是显示中文字符串的函数,我觉得一个一个汉字地显示实在是太过麻烦,就想按照显示字符串的思想来显示中文字符串,但是这就要求*p必须是整形const int *p
的,因为显示一个汉字的函数里传进去的参数num是一个整数(0、1、2等等),所以我就定义了一个整形的数组,用来存放需要显示的汉字字符串对应的汉字的数字 (这个数字就是用取模软件生成的字模后面带的数字),额,,感觉是比一个一个显示汉字省事了那么一点点,,,看一下应用:
int mode11[6] = {17,0,1,2,3,16};//【蓝牙模式】
int mode12[6] = {0,1,2,3,18,18};//蓝牙模式
int mode21[6] = {17,4,5,2,3,16};//【寻迹模式】
int mode22[6] = {4,5,2,3,18,18};//寻迹模式
int mode31[6] = {17,6,7,2,3,16};//【调速模式】
int mode32[6] = {6,7,2,3,18,18};//调速模式
int ret11[6] = {17,8,9,16,18,18};//【返回】
int ret12[6] = {8,9,18,18,18,18};//返回
void fun1(void)
{
OLED_ShowChinese(10,0,mode11);//显示【蓝牙模式】
OLED_ShowChinese(10,17,mode22);//显示寻迹模式
OLED_ShowChinese(10,33,mode32);//显示调速模式
OLED_ShowChinese(10,49,ret12);//显示返回
OLED_Refresh_Gram();
}
这个方法可以显示汉字字符串了,但是不能显示汉字加上英文的字符串,于是就有了方法二,,,贼好使,通用
//第一种
const unsigned short ChsIndex[CHS_TOTAL]={
0xA1BE, 0xA1BF,0xA3BA,0xB0E6,0xB1BE,0xB5B1,0xB5F7,0xB6C8,0xB7B5,
0xBAC5,0xBBD8,0xBCA3,0xC0B6,0xC4A3,0xC7B0,0xCABD,0xCBD9,0xD1B0,
0xD1C0,0xD5DF, 0xD6B5, 0xD7F7};
//精简汉字字符库(顺序是):【】:版本当调度返号回迹蓝模前式速寻牙者值作
//第二种
const unsigned short ChsIndex[CHS_TOTAL]={
'【','】',';','版','本','当','调','度','返','号','回','迹','蓝',
'模','前','式','速','寻','牙','者','值','作'
};
第一种是用GB2312编码查询软件查询每个汉字的编码,第二种是直接用单引号获取字符编码,但是第二种方法会产生警告,但这个警告并不影响程序的正常运行。
2. 具体代码:
//显示一个汉字
void OLED_ShowGBK(u8 x, u8 y, u16 index, u8 size,u8 mode)
{
u8 temp,t1,i;
u8 y0=y;
for(i=0;i<32;i++)
{
if(size==16)
temp = gbk_1616[index*32+i]; //调用1616字体
for(t1=0;t1<8;t1++)
{
if(temp&0x80)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp<<=1;
y++;
if((y-y0)==size)
{
y=y0;
x++;
break;
}
}
}
}
/* 二分法查找字符位置; chs-GB2312码; 返回值-汉字索引*/
u16 GetChsIndex(u16 chs)
{
u16 Index,Min,Max;
Min = 0;
Max = CHS_TOTAL-1;
while(1)
{
Index = (Min+Max) / 2; //二分法查找字符
if(chs == ChsIndex[Index])
{
break; //找到,退出
}
else if(chs > ChsIndex[Index]) //未找到时,更新二分点
{
Min = Index;
}
else
{
Max = Index;
}
if( (Max-Min) <= 1) //二分点相邻时,作最后的判断
{
if(chs == ChsIndex[Min])
{
Index = Min;
break;
}
else if(chs == ChsIndex[Max])
{
Index = Max;
break;
}
else
{
Index = 0; //未找到时,返回0
break;
}
}
}
return Index;
}
//OLED可显示汉字串和字符串以及二者的混合体
void OLEDShowString(u8 x, u8 y, char *str)
{
#define MAX_CHIN_POSX 120
#define MAX_CHIN_POSY 49
u16 index,chr;
while(*str != '\0')
{
if(x>MAX_CHIN_POSX){x=0;y+=16;}
if(y>MAX_CHIN_POSY){y=x=0;OLED_Clear();}
if(*str > 127) //区分ASCII字符和汉字,编码大于127为汉字
{
chr = *str<<8 | *(str+1); //获取汉字GB2312码
index = GetChsIndex(chr); //将GB2312编码转换为精简字库中的字符索引
OLED_ShowGBK(x, y, index, 16,1);
x += 16;
str +=2;
}
else //编码小于等于127为ASCII码
{
OLED_ShowString(x,y,str);
x += 8;
str++;
}
}
}
//显示图片(通过改变索引值和图片对应的像素可以显示不同像素的图片)
//x,y:图片的起点坐标
//px,py:图片的像素(与实际取模的图片像素一致)
//index:图片索引
void OLED_ShowBMP(u8 x, u8 y, u8 px, u8 py, u8 index, u8 mode)
{
u8 temp,t1;
u16 j,i;
u8 y0=y;
i = (px/2)*(py/4);
for(j = 0; j < i;j++)
{
temp = Image[index][j]; //调用图片
for(t1=0;t1<8;t1++)
{
if(temp&0x80)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp<<= 1;
y++;
if((y-y0) == py)
{
y=y0;
x++;
break;
}
}
}
}