本帖最后由 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 are SCK = 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 are SCK = 13 and MOSI = 11)
- char str1[]="HW SPI Com: CS = 10, A0 = 9 ";
- char str2[]="HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 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[2] = " ";
- uint8_t x, y;
- u8g.drawStr( 0, 0, "ASCII page 1");
- for( y = 0; y < 6; y++ ) {
- for( x = 0; x < 16; x++ )
- {
- s[0] = 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[2]=" ";
- 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[2]=i;
- test( s[0]);
- 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[2] = " ";
- uint8_t x, y;
- u8g.drawStr( 0, 0, "ASCII page 1");
- for( y = 0; y < 6; y++ ) {
- for( x = 0; x < 16; x++ )
- {
- s[0] = 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 are SCK = 13 and MOSI = 11)
- char str1[]="HW SPI Com: CS = 10, A0 = 9 ";
- char str2[]="HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 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[2] = " ";
- uint8_t x, y;
- for( y = 0; y < 6; y++ ) {
- for( x = 0; x < 16; x++ )
- {
- s[0] = 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[2] = " ";
- uint8_t x, y;
- for( y = 0; y < 6; y++ ) {
- for( x = 0; x < 16; x++ )
- {
- s[0] = 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() );
- }
- }
- }
复制代码
|