第一篇——Arduino之运用u8gbil库控制OLED

第一篇——Arduino之运用u8gbil库控制OLED

序言–算不上开始的开始

第一篇就从自我介绍开始吧2333,本人岭南技校大一新生一枚,学习信息工程专业,因为个人的兴趣,以及比较希望打打电赛,所以也就开始学一些单片机相关的东西,只是颇为惭愧,开学三个月来,总有一种草盛豆苗稀的感觉。
今日在学长的推荐下,来此试写博客,倒不怕先来人耻笑,一方面是想督促自己,一方面说不定能给后辈们一些微薄的帮助,也希望路过的先学之人能够斧正文章的偏颇之处,这也算是我这粗鄙之人写博文的荣幸了。

Arduino

开学以来学了些51的东西,总被寄存器搞得头昏脑胀。最近拿了朋友的arduino玩,觉得手感异常的好,前几天想起手头有块IIC口的OLED,又查到arduino有u8gbil库,索性整理了一下OLED的程序,算是在Arduino上的第一个认真的去整理的程序了吧。

arduino的OLED程序

以下。

#include "U8glib.h"
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 

这里引头文件,第二行大概是串口的声名吧,这里理解的不是很好,不过这么用是没问题的。

# define Con_interval 6   
# define Con_pages 21
uint16_t draw_state = 0;

定义了两个常量, Con_interval 用来表示每一屏的时间,时长为pow(2,Con_interval)个单位时间。Con_pages就是屏数,应当与case所跟的情况数相对应。
draw_state比较关键的一个变量,随程序运行自增,算是充当时间变量吧。

void loop(void) {
  u8g.firstPage();  
  do {
      draw();
      } 
  while( u8g.nextPage() );
  draw_state++;
  if ( draw_state >= Con_pages * pow(2,Con_interval))
    draw_state = 0;
}

主函数里分别调用显示开始和显示结束的函数u8g.firstPage(),u8g.nextPage(),这之间调用自己定义的draw()。每显示一次结束后,draw_state自增,加到大于页数乘每页显示时间时,归零。

void u8g_prepare(void) {
  u8g.setFont(u8g_font_6x10);
  //  u8g.setFont(u8g_font_unifont);
  //  u8g.setFont(u8g_font_osb21);
  //  u8g.setFont(u8g_font_6x10);
  //  u8g.setFont(u8g_font_osb18);

  u8g.setFontRefHeightExtendedText();
  u8g.setDefaultForegroundColor();
  u8g.setFontPosTop(); 

}

这里倒也不复杂,一个prepare函数,作用就是每次显示之前调用一次,完成显示的一些设置。
u8g.setFont函数用于选择字体,颇为沮丧的是本小白在各类网站上都没有查到这个库提供了哪些字体,只从例程中找到了4种出现的字体来用。
u8g.setFontRefHeightExtendedText()这个函数本小白还没有搞明白。。。反正,用就对了。
u8g.setDefaultForegroundColor()这个函数是设置为前景色,通俗的说就是点亮下文中绘制的像素点。
与之相应的有函数u8g.setDefaultBackgroundColor()用于设置背景色,即擦除下文中绘制的像素点。
u8g.setFontPosTop()这个函数使用后,显示的时候定位的位置就是以字符顶为标准了。(举个简单的例子,不用的时候drawstr纵坐标参数为0,显示的字符下端的坐标为0,使用函数后,则是字符上端坐标为0)

void draw(void) {
  u8g_prepare();
  switch(draw_state >> Con_interval) {
    case 0 : u8g_print1 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    }

绘制函数,先执行一次prepare,然后根据draw_state判断应该执行哪个case(即哪一页),每页的时长为Con_interval ,因此在switch的判断里draw_state 要右移相应位数。case当然要根据需要做相应扩充,并补充相应的函数。

void u8g_print1(uint8_t a) {
  u8g.drawStr( 0, 0-a/8, "one day");
  u8g.drawStr( 0, 11-a/8, "in the morning");
  u8g.drawStr( 0 ,22-a/8, "go to school");
  u8g.drawStr( 0 ,33-a/8, "do exercise");
  u8g.drawStr( 0 ,44-a/8, "run away");
}

这是case 0 调用的函数,u8g.drawStr用于显示字符串,三个参数依次是字符串的横坐标,纵坐标,内容。
函数的纵坐标是与a相关的表达式,实现的效果就是纵坐标随时间有规律的改变,这里的变化效果是滚屏。
每一屏的时间是Con_interval 决定的,也就是说a的范围是
0~pow(2,Con_interval)-1.

其他的一些绘制图形的函数不一一列举了,不妨放一个链接上来,需要的可以移步此类网站学习。

https://www.arduino.cn/thread-41158-1-1.html

一首小诗的显示

大体了解了一些显示的技巧,就写了一个英文诗滚屏显示的程序练练手,英文诗是从网上扒的,内容如下:
Schools apart, day after day,
And I slowly go insane.
But you left without delay,
which was my deep pain.
Since you’ve broken my heart,
you need not be with me.
Let’s say goodbye and depart,
And I’m what I used to be.
Do not say forever;
Do not meet tomorrow.
And I see you never,
I am virtue as snow.

于是有了如下程序:

#include "U8glib.h"
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 
# define Con_interval 6   
# define Con_pages 14
void u8g_prepare(void) {
  u8g.setFont(u8g_font_6x10);
  u8g.setFontRefHeightExtendedText();
  u8g.setDefaultForegroundColor();
  u8g.setFontPosTop(); 
}
void u8g_print1(uint8_t a) {
  u8g.drawStr( 0, 0-a/4, "Schools apart,");
  u8g.drawStr( 0, 10-a/4, "day after day,");
  u8g.drawStr( 0 ,20-a/4, "And I slowly ");
  u8g.drawStr( 0 ,30-a/4, "go insane.");
  u8g.drawStr( 0 ,40-a/4, "But you left");
}
void u8g_print2(uint8_t a) {
  u8g.drawStr( 0, 10-a/4-16, "day after day,");
  u8g.drawStr( 0 ,20-a/4-16, "And I slowly ");
  u8g.drawStr( 0 ,30-a/4-16, "go insane.");
  u8g.drawStr( 0 ,40-a/4-16, "But you left");
  u8g.drawStr( 0, 50-a/4-16, "which was");
}
void u8g_print3(uint8_t a) {
  u8g.drawStr( 0 ,30-a/4-32, "go insane.");
  u8g.drawStr( 0 ,40-a/4-32, "But you left");
  u8g.drawStr( 0, 50-a/4-32, "which was");
  u8g.drawStr( 0, 60-a/4-32, "my deep pain.");
  u8g.drawStr( 0, 70-a/4-32, "Since you've");
}
void u8g_print4(uint8_t a) {
  u8g.drawStr( 0 ,40-a/4-48, "But you left");
  u8g.drawStr( 0, 50-a/4-48, "which was");
  u8g.drawStr( 0, 60-a/4-48, "my deep pain.");
  u8g.drawStr( 0, 70-a/4-48, "Since you've");
  u8g.drawStr( 0, 80-a/4-48, "broken my heart,");
}
void u8g_print5(uint8_t a) {
  u8g.drawStr( 0, 60-a/4-64, "my deep pain.");
  u8g.drawStr( 0, 70-a/4-64, "Since you've");
  u8g.drawStr( 0, 80-a/4-64, "broken my heart,");
  u8g.drawStr( 0, 90-a/4-64, "you need not");
  u8g.drawStr( 0, 100-a/4-64, "be with me.");
}
void u8g_print6(uint8_t a) {
  u8g.drawStr( 0, 80-a/4-80, "broken my heart,");
  u8g.drawStr( 0, 90-a/4-80, "you need not");
  u8g.drawStr( 0, 100-a/4-80, "be with me.");
  u8g.drawStr( 0, 110-a/4-80, "Let's say goodbye");
  u8g.drawStr( 0, 120-a/4-80, "and depart,");
}
void u8g_print7(uint8_t a) {
  u8g.drawStr( 0, 90-a/4-96, "you need not");
  u8g.drawStr( 0, 100-a/4-96, "be with me.");
  u8g.drawStr( 0, 110-a/4-96, "Let's say goodbye");
  u8g.drawStr( 0, 120-a/4-96, "and depart,");
  u8g.drawStr( 0, 130-a/4-96, "And I'm what");
}
void u8g_print8(uint8_t a) {
   u8g.drawStr( 0, 110-a/4-112, "Let's say goodbye");
  u8g.drawStr( 0, 120-a/4-112, "and depart,");
  u8g.drawStr( 0, 130-a/4-112, "And I'm what");
  u8g.drawStr( 0, 140-a/4-112, "I used to be.");
  u8g.drawStr( 0, 150-a/4-112, "Do not say forever;");
}
void u8g_print9(uint8_t a) {
   u8g.drawStr( 0, 120-a/4-128, "and depart,");
  u8g.drawStr( 0, 130-a/4-128, "And I'm what");
  u8g.drawStr( 0, 140-a/4-128, "I used to be.");
  u8g.drawStr( 0, 150-a/4-128, "Do not say forever;");
  u8g.drawStr( 0, 160-a/4-128, "Do not");
}
void u8g_print10(uint8_t a) {
 u8g.drawStr( 0, 140-a/4-144, "I used to be.");
  u8g.drawStr( 0, 150-a/4-144, "Do not say forever;");
  u8g.drawStr( 0, 160-a/4-144, "Do not");
  u8g.drawStr( 0, 170-a/4-144, "meet tomorrow.");
  u8g.drawStr( 0, 180-a/4-144, "And I see you never,");
}
void u8g_print11(uint8_t a) {
  u8g.drawStr( 0, 160-a/4-160, "Do not");
  u8g.drawStr( 0, 170-a/4-160, "meet tomorrow.");
  u8g.drawStr( 0, 180-a/4-160, "And I see you never,");
  u8g.drawStr( 0, 190-a/4-160, "I am virtue as snow.");
}
void u8g_print12(uint8_t a) {
 u8g.drawStr( 0, 170-a/4-176, "meet tomorrow.");
  u8g.drawStr( 0, 180-a/4-176, "And I see you never,");
  u8g.drawStr( 0, 190-a/4-176, "I am virtue as snow.");
}
void u8g_print13(uint8_t a) {
u8g.drawStr( 0, 190-a/4-192, "I am virtue as snow.");
}
unsigned long draw_state = 0;
void draw(void) {
  u8g_prepare();
  switch(draw_state >> Con_interval) {
    case 0 : u8g_print1 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 1 : u8g_print2 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 2 : u8g_print3 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 3 : u8g_print4 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 4 : u8g_print5 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 5 : u8g_print6 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 6 : u8g_print7 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 7 : u8g_print8 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 8 : u8g_print9 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 9 : u8g_print10 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 10 : u8g_print11 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 11 : u8g_print12 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 12 : u8g_print13 (draw_state&(uint8_t)(pow(2,Con_interval)-1)); break;
    case 13 : break;
  }
}
void setup(void) {
  u8g.setRot180();
void loop(void) {
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  draw_state++;
  if ( draw_state >= Con_pages * pow(2,Con_interval))
}

不知道为什么没能实现在一屏里完成所有内容的滚动,才搞得程序如此冗长,不过效果起码是实现了。
下一步会争取弄懂所有的函数,找一下之前的bug,并简化一下程序的。

PS:没办法上传短视频的吗。。。大概我太菜了

在这里插入图片描述
嗯,这样处女篇就到此了,鄙人不才,(滑稽。jpg)告辞。

追加一下,发现原来的bug了,还是自己基本功不够硬啊……具体的在下一篇里解释吧,电脑要没电了(逃了)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值