tom 发表于 2013-7-28 14:58:09

I2C接口1306芯片OLED屏12864,字符串向上下左右移动演示

本帖最后由 Microduino 于 2013-7-29 23:27 编辑

I2C接口1306芯片OLED屏12864,字符串向上下左右移动演示
作用:字符串向左移动,向右移动,向下称动,向上移动,在同一个位置显示一个ASCII字符

I2C接口OLED屏12864 张老师的
1306驱动芯片
IDE V1.01
u8glib V1.12

OLED屏线路连接 GND接Ardunio GND
            VCC接Arduino 3.3V
            SDA接Ardunio 模拟口A4
            SCL接Ardunio 模拟口A5

这个屏只能使用 u8glib 这个库文件

驱动芯片选择 U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);        // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins areSCK = 13 and MOSI = 11)

OLED 12864图片


由于个人经验不足,没有找到清屏的函数,或是用空格清除指定位置的字符的函数。
经实验发现,可以用翻页的方法实现。

比如一个字符串向左移动

第一页,在坐标0,0显示字符串
接下来 下一页,在坐标-10,0显示字符串
再一页,在坐标-20,0显示字符串 如此类推,就实现了字符串的移动功能。

完整的Arduino代码如下:
//张老师的OLED版12864
//本程序实现了一个字符串向左移动,向右移动,向下称动,向上移动,在同一个位置显示一个ASCII字符
//该程序的函数不能通用化,使用起来麻烦
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);        // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins areSCK = 13 and MOSI = 11)
char str1[]="HW SPI Com: CS = 10, A0 = 9 ";
char str2[]="HW SPI Com: CS = 10, A0 = 9 (Hardware Pins areSCK = 13 and MOSI = 11)";


void moveStrToRight(void)
//这个函数未实现字符串从左向右移动,而是出现了字符串叠加的现象(使用str2)。
//原来是字符串太长了
{
u8g.setFont(u8g_font_unifont);
char str1[]="HW SPI Com: CS = 10, A0 = 9 ";
for (int i=0;i<=12;i++)
{
    u8g.firstPage();
    do {

      u8g.drawStr(i*10,10,(char *)str1);


    }
    while( u8g.nextPage() );   
    delay(100);
}

}
void moveStr2ToRight(char *str1,char *str2,int x1,int y1,int x2,int y2)
//这个函数未实现字符串从左向右移动,而是出现了字符串叠加的现象。
//原来是字符串太长了
{

for (int i=0;i<=12;i++)
{
    u8g.firstPage();
    do {

      u8g.drawStr(i*10+x1,y1,(char *)str1);
      u8g.drawStr(i*10+x2,y2,(char *)str2);


    }
    while( u8g.nextPage() );   
    delay(100);
}

}


void moveStrToLeft(void)
//这个函数未实现字符串从右向左移动,而是出现了字符串叠加的现象。
//原来是字符串太长了
{
u8g.setFont(u8g_font_unifont);

char str[]="HW SPI Com: CS = 10, A0 = 9 ";

for (int i=0;i<=12;i++)
{
    u8g.firstPage();
    do {
      u8g.drawStr(120-i*10,22,(char *)str);



    }
    while( u8g.nextPage() );   
    delay(300);
}

}
void moveStrToDown(void)// 这个过程是字符串竖直排,从上向下移动位置

{
u8g.setFont(u8g_font_unifont);//似乎只有设置这个字体drawStr90函数才起作用
char str[]="HW SPI Com: CS = 10 ";
//注这个字符串共有20个字符,20*8=160(字体像素以6*8计算)
//显示的位置是从Y轴-160开始,然后每次向下增进10个像素值,从上向下完全的完整显示字符串
for (int i=0;i<=10;i++)
{
    u8g.firstPage();
    do {
      u8g.drawStr90(10,i*16-160,(char *)str);



    }
    while( u8g.nextPage() );   
    delay(300);
}

}

void moveStrToUp(void)// 这个过程是字符串竖直排,从下向上移动位置

{
u8g.setFont(u8g_font_unifont);
char str[]="HW SPI Com: CS = 10 ";
//注这个字符串共有20个字符,20*8=160(字体像素以6*8计算)
//显示的位置是从Y轴-160开始,然后每次向上增进10个像素值,从下向上完全的完整显示字符串
//为了能显示最后一个字符,Y轴的值至少为-20*8=-160
for (int i=0;i<=17;i++)
{
    u8g.firstPage();
    do {
      u8g.drawStr90(10,60-i*10,(char *)str);



    }
    while( u8g.nextPage() );   
    delay(300);
}

}
void u8g_prepare(void) {
u8g.setFont(u8g_font_6x10);
u8g.setFontRefHeightExtendedText();
u8g.setDefaultForegroundColor();
u8g.setFontPosTop();
}
uint8_t draw_state = 0;

void mydraw(void) {
u8g_prepare();
switch(draw_state >> 3) {
case 0:
    moveStrToLeft();
    break;
case 1:   
    moveStrToRight() ;
    break;
case 2:
    moveStrToUp();
    break;
case 3:
    moveStrToDown();
    break;
case 4:
    displayAchar();
    break;
case 5:
    u8g_ascii_1();
    break;
case 6:
    newtest();
    break;


}
}


void u8g_ascii_1() //显示ascii在屏幕上
{
char s = " ";
uint8_t x, y;
u8g.drawStr( 0, 0, "ASCII page 1");
for( y = 0; y < 6; y++ ) {
    for( x = 0; x < 16; x++ )
    {
      s = y*16 + x + 32;
      u8g.firstPage();
      do {

      u8g.drawStr(31, 40, s);
      //如果需要依次在不同的位置显示,如下行
      //u8g.drawStr(x*7, y*10+10, s);
      delay(50);

      }
      while( u8g.nextPage() );


    }
}
}
char s=" ";
void test(char s)//显示一个ASCII字符
{

uint8_t x,y;
u8g.drawStr(0,0,"ASCII a char");


u8g.drawStr(100,50,(char *)s);
delay(100);

}
void newtest()//显示一个ASCII字符
{
int i=33;
s=i;
test( s);
if (i>126) //如是i>126进入死循环中,不在做任何事
    while (true)
    {
      continue;
    }

i++;
}   


void setup()
{


if ( u8g.getMode() == U8G_MODE_R3G3B2 )
    u8g.setColorIndex(255);   // white
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
    u8g.setColorIndex(3);         // max intensity
else if ( u8g.getMode() == U8G_MODE_BW )
    u8g.setColorIndex(1);         // pixel on

u8g.setFont(u8g_font_unifont);
Serial.begin(9600);


u8g_prepare();//初始化字体,屏幕参数



}

void loop()
{


mydraw();

draw_state++;
if ( draw_state >= 7*8 )
    draw_state = 0;

// rebuild the picture after some delay
delay(100);

}



void displayAchar()//这个过程,在同一个位置,显示不同的字符
{

char s = " ";
uint8_t x, y;
u8g.drawStr( 0, 0, "ASCII page 1");
for( y = 0; y < 6; y++ ) {
    for( x = 0; x < 16; x++ )
    {
      s = y*16 + x + 32;
      u8g.firstPage();
      do {

      u8g.drawStr(31, 40, s);
      //如果需要依次在不同的位置显示,如下行
      //u8g.drawStr(x*7, y*10+10, s);
      delay(50);

      }
      while( u8g.nextPage() );



    }
}

}




为了方便程序的移植,将各个函数标准化,使之能通用。
代码如下:



//张老师的I2C OLED版12864
//本程序实现了一个字符串向左移动,向右移动,向下称动,向上移动,在同一个位置显示一个ASCII字符
//将各个函数改写使之通用化
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);        // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins areSCK = 13 and MOSI = 11)
char str1[]="HW SPI Com: CS = 10, A0 = 9 ";
char str2[]="HW SPI Com: CS = 10, A0 = 9 (Hardware Pins areSCK = 13 and MOSI = 11)";


void moveStrToRight(char *str,int x,int y)
//这个函数未实现字符串从左向右移动,而是出现了字符串叠加的现象。
//原来是字符串太长了
{

for (int i=0;i<=12;i++)
{
    u8g.firstPage();
    do {

      u8g.drawStr(i*10+x,y,(char *)str);


    }
    while( u8g.nextPage() );   
    delay(100);
}

}

void moveStr2ToRight(char *str1,char *str2,int x1,int y1,int x2,int y2)
//这个函数未实现字符串从左向右移动,而是出现了字符串叠加的现象。
//原来是字符串太长了
{

for (int i=0;i<=12;i++)
{
    u8g.firstPage();
    do {

      u8g.drawStr(i*10+x1,y1,(char *)str1);
      u8g.drawStr(i*10+x2,y2,(char *)str2);


    }
    while( u8g.nextPage() );   
    delay(100);
}

}


void moveStrToLeft(char *str,int x, int y)
//这个函数未实现字符串从右向左移动,而是出现了字符串叠加的现象。
//原来是字符串太长了
{



for (int i=0;i<=12;i++)
{
    u8g.firstPage();
    do {
      u8g.drawStr(x-i*10,y,(char *)str1);

    }
    while( u8g.nextPage() );   
    delay(100);
}

}
void moveStrToDown(char *str,int x ,int y)// 这个过程是字符串竖直排,从上向下移动位置

{

//注这个字符串共有20个字符,20*8=160(字体像素以6*8计算)
//显示的位置是从Y轴-160开始,然后每次向下增进10个像素值,从上向下完全的完整显示字符串
for (int i=0;i<=10;i++)
{
    u8g.firstPage();
    do {
      u8g.drawStr90(x,i*16-y,(char *)str);



    }
    while( u8g.nextPage() );   
    delay(100);
}

}

void moveStrToUp(char *str,int x,int y)// 这个过程是字符串竖直排,从下向上移动位置

{


//str1[]注这个字符串共有20个字符,20*8=160(字体像素以6*8计算)
//显示的位置是从Y轴-160开始,然后每次向上增进10个像素值,从下向上完全的完整显示字符串
//为了能显示最后一个字符,Y轴的值至少为-20*8=-160
for (int i=0;i<=17;i++)
{
    u8g.firstPage();
    do {
      u8g.drawStr90(x,y-i*10,(char *)str1);

    }
    while( u8g.nextPage() );   
    delay(100);
}

}
void u8g_prepare(void) {
u8g.setFont(u8g_font_6x10);
u8g.setFontRefHeightExtendedText();
u8g.setDefaultForegroundColor();
u8g.setFontPosTop();
}
uint8_t draw_state = 0;

void mydraw(void) {
u8g_prepare();
switch(draw_state >> 3) {
case 0:
    moveStrToLeft(str1,120,10); //x=20(个字符数)*6(字符宽),y=10差不多在第一行
    break;
case 1:   
    moveStrToRight(str1,0,10) ; //x=0,y=10 ,y=10差不多在第一行
    break;
case 2:
    moveStrToUp(str1,10,60); //x=10,y=60 x在超过一个字符位置,Y在差不多第六行
    break;
case 3:
    moveStrToDown(str1,10,120); //x=10,由于str1字符长度20个,字符串长度是=20*8=160,y就等于120
    break;
case 4:
    displayAchar(); //在依次显示不同的ASCII字符
    break;
case 5:
    u8g_ascii_1(30,50); //在指定的坐标,显示不同的ASCII字符
    break;



}
}


void u8g_ascii_1(int i,int j) //显示ascii在屏幕上
{
char s = " ";
uint8_t x, y;

for( y = 0; y < 6; y++ ) {
    for( x = 0; x < 16; x++ )
    {
      s = y*16 + x + 32;
      do {
      u8g.drawStr( 0, 0, "ASCII page 1");
      u8g.drawStr(i, j, s);   
      //如果需要依次在不同的位置显示,如下行
      //u8g.drawStr(x*7+i, y*10+j, s);      
      delay(50);

      }
      while( u8g.nextPage() );



    }
}
}


void setup()
{


if ( u8g.getMode() == U8G_MODE_R3G3B2 )
    u8g.setColorIndex(255);   // white
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
    u8g.setColorIndex(3);         // max intensity
else if ( u8g.getMode() == U8G_MODE_BW )
    u8g.setColorIndex(1);         // pixel on

// u8g.setFont(u8g_font_unifont);
Serial.begin(9600);


u8g_prepare();//初始化字体,屏幕参数



}

void loop()
{


//moveStr2ToRight(str1,str2,0,0,0,10);
mydraw();
draw_state++;
if ( draw_state >= 7*8 )
    draw_state = 0;

// rebuild the picture after some delay
delay(100);

}



void displayAchar()//这个过程,依次在不同的坐标,显示不同ASCII的字符
{

char s = " ";
uint8_t x, y;

for( y = 0; y < 6; y++ ) {
    for( x = 0; x < 16; x++ )
    {
      s = y*16 + x + 32;
      u8g.firstPage();
      do {
      u8g.drawStr( 0, 0, "ASCII page 1");
      //u8g.drawStr(31, 40, s);   
      //如果需要依次在不同的位置显示,如下行
      u8g.drawStr(x*7, y*10, s);      
      delay(50);

      }
      while( u8g.nextPage() );



    }
}

}












zcbzjx 发表于 2013-7-28 15:25:17

阅。。。有空尝试。。

1537141654 发表于 2013-7-28 22:54:38

看着好麻烦的样子呀

huang1234 发表于 2013-12-29 00:01:24

赞一个!:lol

fairsky 发表于 2014-2-24 17:52:24

能给这LCD的TB链接么?

yw26215 发表于 2018-5-22 15:07:30

试过了,可用。

再研究一下,看看怎么才能用起来。
页: [1]
查看完整版本: I2C接口1306芯片OLED屏12864,字符串向上下左右移动演示