字库生成软件:PCtoLCD2002
字模选项:阴码;逐列式;逆向(低位在前);
输出:C51十六进制
生成的点阵数据:
/*
ASCII码表排序,所以寻址需要加0x20
" "->>0x20
"!"->>0x21
...
"~"->>0x7E
Courier New
逐列逆向,低位在前
02468ace
13579bdf
*/
const u8 g_oled_asc2_1608[95][16]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x09,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x00,0x00,0xF0,0x00,0x30,0x00,0x00,0x00,0xF0,0x00,0x30,0x00,0x00,0x00},/*""",2*/
{0x00,0x00,0x40,0x1A,0xE0,0x07,0x58,0x02,0x40,0x1A,0xE0,0x07,0x58,0x02,0x00,0x00},/*"#",3*/
{0x00,0x00,0x00,0x00,0x60,0x06,0x90,0x04,0x98,0x1C,0x30,0x03,0x00,0x00,0x00,0x00},/*"$",4*/
{0x00,0x00,0x20,0x01,0x50,0x01,0x20,0x05,0x80,0x0A,0x80,0x04,0x00,0x00,0x00,0x00},/*"%",5*/
{0x00,0x00,0x00,0x00,0x00,0x06,0xC0,0x09,0x20,0x0B,0x20,0x0C,0x20,0x0A,0x00,0x00},/*"&",6*/
............
{0x00,0x00,0x00,0x01,0x80,0x00,0x80,0x00,0x00,0x01,0x00,0x01,0x80,0x00,0x00,0x00},/*"~",94*/
};
以上以‘#’来作为例子进行分析。
程序调试输出坐标值及是否着色(x,y)[mode]
//调试输出坐标
(10,00)[0],(10,01)[0],(10,02)[0],(10,03)[0],(10,04)[0],(10,05)[0],(10,06)[0],(10,07)[0],(10,08)[0],(10,09)[0],(10,10)[0],(10,11)[0],(10,12)[0],(10,13)[0],(10,14)[0],(10,15)[0],
(11,00)[0],(11,01)[0],(11,02)[0],(11,03)[0],(11,04)[0],(11,05)[0],(11,06)[1],(11,07)[0],(11,08)[0],(11,09)[1],(11,10)[0],(11,11)[1],(11,12)[1],(11,13)[0],(11,14)[0],(11,15)[0],
(12,00)[0],(12,01)[0],(12,02)[0],(12,03)[0],(12,04)[0],(12,05)[1],(12,06)[1],(12,07)[1],(12,08)[1],(12,09)[1],(12,10)[1],(12,11)[0],(12,12)[0],(12,13)[0],(12,14)[0],(12,15)[0],
(13,00)[0],(13,01)[0],(13,02)[0],(13,03)[1],(13,04)[1],(13,05)[0],(13,06)[1],(13,07)[0],(13,08)[0],(13,09)[1],(13,10)[0],(13,11)[0],(13,12)[0],(13,13)[0],(13,14)[0],(13,15)[0],
(14,00)[0],(14,01)[0],(14,02)[0],(14,03)[0],(14,04)[0],(14,05)[0],(14,06)[1],(14,07)[0],(14,08)[0],(14,09)[1],(14,10)[0],(14,11)[1],(14,12)[1],(14,13)[0],(14,14)[0],(14,15)[0],
(15,00)[0],(15,01)[0],(15,02)[0],(15,03)[0],(15,04)[0],(15,05)[1],(15,06)[1],(15,07)[1],(15,08)[1],(15,09)[1],(15,10)[1],(15,11)[0],(15,12)[0],(15,13)[0],(15,14)[0],(15,15)[0],
(16,00)[0],(16,01)[0],(16,02)[0],(16,03)[1],(16,04)[1],(16,05)[0],(16,06)[1],(16,07)[0],(16,08)[0],(16,09)[1],(16,10)[0],(16,11)[0],(16,12)[0],(16,13)[0],(16,14)[0],(16,15)[0],
(17,00)[0],(17,01)[0],(17,02)[0],(17,03)[0],(17,04)[0],(17,05)[0],(17,06)[0],(17,07)[0],(17,08)[0],(17,09)[0],(17,10)[0],(17,11)[0],(17,12)[0],(17,13)[0],(17,14)[0],(17,15)[0],
根据坐标值画点
void oled_draw_point(u8 x, u8 y, BOOL mode){
u8 page, data;
if(x>127 || y>63) return;
//将坐标转化为页eg.(100,29)
page = y / 8; //page3
data = y % 8; //data5
if(mode){
g_oled_gram[x][page] |= 0x01<
输出单个字符,这里做的有局限性,屏幕只能显示4行
具体思路:第一行page0,1;第二行page2,3;然后用的时候指定写哪一行(0-3)。
void oled_show_char(u8 line, u8 x, u8 dat){
u8 byte, bit;
u8 tmp_dat;
u8 y;
dat = dat - ' '; //0x20空格,数组从0x20起始
y = line * 16; //两页用作一行
for(byte=0; byte<16; byte++){
tmp_dat = g_oled_asc2_1608[dat][byte];
for(bit=0; bit<8; bit++){
oled_draw_point(x, y, tmp_dat&0x01);
tmp_dat>>=1;
y++;
}
if(byte%2){ //page0,1,0;换列,y轴重置
x++;
y = y-16;
}
}
}
写字符串,同样有局限性,不支持换行,没有行溢出判断。思路有 ,懒得做了。
void oled_show_string(u8 line, u8 x, u8 *str){
while(*str!='\0'){
oled_show_char(line, x, *str);
x+=8; //1608字库
str++;
}
}
写数字,此处设置为u16类型的数值,因此最大值为65535
void oled_show_num(u8 line, u8 x, u16 num){
u8 i;
u16 tmp_mod = 10000; //若要显示大于5位的数值改这里和i的最大值即可
BOOL begin = FALSE;
for(i=0; i<5; i++){
if(num/tmp_mod){
begin = TRUE; //防止前面有0,如果需要显示定长的begin默认值改为TRUE即可
}
if(begin){
oled_show_char(line, x, num/tmp_mod+'0');
num = num%tmp_mod;
x += 8;
}
tmp_mod = tmp_mod/10;
}
}
最终效果:
oled_show_char(0, 10, '#');
oled_show_string(1, 10, "Hello OLED !");
oled_show_string(2, 10, "0123456789ABCDEFGHIJKLMNOPQRST");
oled_show_num(3, 10, 0xffff);
oled_refresh_gram();