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() );
}
}
}
阅。。。有空尝试。。 看着好麻烦的样子呀 赞一个!:lol 能给这LCD的TB链接么? 试过了,可用。
再研究一下,看看怎么才能用起来。
页:
[1]