试了一下SSD1306芯片的OLED12864屏幕专有的显示方式
把43张 76×64像素的图片取模成一个大数组 DANCER[26144];
屏幕的寻址模式设置成 【水平地址模式】
用OLED的设置显示范围的指令 0x21和 0x22 把屏幕控制范围缩小到图片的大小
- void DMA_OLED_Set_Area( u8 x, u8 y, u8 width, u8 height )
- {
- u8 CMD[6];
-
- u8 page = ( height % 8 ) ? ( height/8+1 ) : ( height/8 );
-
- if( x<0 || (x+width-1)>127 ) return; //坐标范围不可以超出屏幕范围
- if( y<0 || (y+ page-1)> 7 ) return;
-
- CMD[0]= 0x21; //设置列范围
- CMD[1]= x; //设置起始列
- CMD[2]= x+width-1; //设置结束列
-
- CMD[3]= 0x22; //设置行范围
- CMD[4]= y; //设置起始行
- CMD[5]= y+page-1; //设置结束行
-
- DMA_SendCommand( CMD, 6 );
- }
复制代码
然后直接发送图片里的所有数据
- DMA_OLED_Set_Area ( 26, 0, 76, 64 ); // 设置显示区域
-
- DMA_SendData ( DANCER, 76*8*43 ); // 发送所有数据
-
- DMA_OLED_Set_Area( 0, 0, 128, 64 ); // 恢复全屏区域
复制代码
显示完一组内容之后,就可以重新设置其他显示区域
显示效果:
===============================================
还可以直接创建一个显示图片的函数
- void DMA_OLED_ShowImage( u8 x, u8 y, u8 *pic, u8 width, u8 height )
- {
- u16 bytes = ( height % 8 ) ? ( (height/8+1)*width ) : ( height/8*width ); //计算图片总字节数
- DMA_OLED_Set_Area( x, y, width, height ); //设置将控制区域为图片大小
- DMA_SendData ( pic, bytes ); //发送图片所有数据
- DMA_OLED_Set_Area( 0, 0, 128, 64 ); //恢复控制区域为全屏
- }
复制代码
不过这两个指令并不是通用指令
SSD1036、SSD1315、SSD1309等等支持,
SH1306等等不支持,还是要老老实实一行一行发送
定位函数
- void DMA_OLED_Set_Pos( u8 x, u8 y )
- {
- u8 CMD[3];
- x += 0;
- CMD[0] = ( 0xB0 + y ); // 设置起始列地址
- CMD[1] = ( x & 0x0F ); // 设置起始行地址低八位
- CMD[2] = ( 0x10 + ( x >> 4 ) ); // 设置起始行地址高八位
- DMA_SendCommand( CMD, 3 );
- }
复制代码
两种清屏函数
- void DMA_OLED_Clear() // 通用
- {
- u8 DAT[128]={0};
- u8 i;
- for(i=0;i<8;i++)
- {
- DMA_OLED_Set_Pos( 0, i );
- DMA_SendData( DAT, 128 );
- }
- }
-
- void DMA_OLED_Clear() // 适合SSD1306等,不适合SH1106
- {
- u8 DAT[1024]={0};
- DMA_OLED_Set_Pos( 0, 0 );
- DMA_SendData( DAT, 1024 );
- }
复制代码
通用的显示图片函数
- void DMA_OLED_ShowImage( u8 x, u8 y, u8 *pic, u8 width, u8 height )
- {
- u8 i;
- u8 pages = ( height % 8 ) ? ( height/8+1 ) : ( height/8 );
-
- for( i=0; i<pages; i++ )
- {
- DMA_OLED_Set_Pos( x, y+i );
- DMA_SendData ( pic + width*i, width );
- }
- }
复制代码
|