久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3760|回復: 3
收起左側

STM32F1驅動OLED顯示畫圖及動畫特效

[復制鏈接]
ID:394949 發表于 2021-12-6 21:28 | 顯示全部樓層 |閱讀模式
本帖最后由 田裕中 于 2021-12-9 15:41 編輯

OLED的界面UI顯示





      本文主要總結OLED顯示繪圖及動畫特效的相關功能函數,記錄自己的開發過程或作為自己的開發筆記,以便不時之需!
      本次OLED采用的SSD1306驅動,分辨率為128*32像素。項目編譯環境使用KEIL5開發,由于調試發現,采用軟件模擬IIC不能滿足刷新幀率,故采用硬件IIC驅動。而顯示功能部分不依賴于軟件或者硬件IIC驅動,只需提供對應的讀寫IIC接口即可!

創建顯示Buf,更新顯存
      創建128 * 32的像素點陣大小,任何顯示功能特效都只需對該點陣進行填充操作,1Byte = 8bit,4 * 8 = 32,點陣填充完畢后調用該函數即可完成刷新顯示。
unsigned char OLED_GRAM[4][128];
void OLED_Refresh_Gram(void)
{
    unsigned char i,n;
    for(i=0;i<4;i++)  
    {  
        WriteCmd(0xb0+i);    //設置頁地址(0~4)
        WriteCmd(0x00);      //設置顯示位置—列低地址
        WriteCmd(0x10);      //設置顯示位置—列高地址   
        WriteDat(OLED_GRAM[ i]);
    }

清除屏幕顯示
      調用該函數后整個屏幕是黑色的,和沒點亮一樣!
void OLED_Clear(void)  
{  
    memset(OLED_GRAM,0,sizeof(OLED_GRAM));
    OLED_Refresh_Gram();//更新顯示
}

畫點填充
      在對應的坐標位置填充像素點顏色,該函數包含4個方向的顯示,拓展了函數的可移植性,通過宏設置顯示的方向。
#define TFT_ROT_NONE        1
#define TFT_ROT_RIGHT       0
#define TFT_ROT_LEFT        0
#define TFT_ROT_FLIP        0/*
@parameter:
           x:橫坐標
           y:縱坐標
           t:0 or 1
*/
void OLED_DrawPoint(unsigned char x,unsigned char y,unsigned char t)
{
    unsigned char pos,bx,temp=0;
#if TFT_ROT_RIGHT
    if(x>31||y>127)return;//超出范圍了.
    pos=x/8;
    bx=x%8;
    temp=1<<bx;
?
    if(t)
    {
        OLED_GRAM[pos][127-y]|=temp;
    }
    else
    {
        OLED_GRAM[pos][127-y]&=~temp;     
    }   
#elif TFT_ROT_LEFT
    if(x>31||y>127)return;
    pos=3-x/8;
    bx=x%8;
    temp=1<<(7-bx);
    if(t)
    {
        OLED_GRAM[pos][y]|=temp;
    }
    else
    {
        OLED_GRAM[pos][y]&=~temp;     
    }   
#elif TFT_ROT_FLIP
    if(x>127||y>31)return;
    pos=3-y/8;
    bx=y%8;
    temp=1<<(7-bx);
    if(t)
    {
        OLED_GRAM[pos][127-x]|=temp;
    }
    else
    {
        OLED_GRAM[pos][127-x]&=~temp;     
    }
#else
    if(x>127||y>31)return;//超出范圍了.
    pos=y/8;
    bx=y%8;
    temp=1<<bx;
?
    if(t)
    {
        OLED_GRAM[pos][x]|=temp;
    }
    else
    {
        OLED_GRAM[pos][x]&=~temp;     
    }   
#endif
}

畫任意直線
      由一點到另一點的直線!
/*
@parameter:
           x1:初始點橫坐標
           y1:初始點縱坐標
           x2:終點橫坐標
           y2:終點縱坐標
           color:0 or 1
*/
void OLED_DrawLine(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char color)
{
    int dx,dy,e;
    dx = x2 - x1;
    dy = y2 - y1;
   
    if(dx >= 0)
    {
        if(dy >= 0)
        {
            if(dx >= dy)
            {
                e = dy - dx/2;
                while(x1<=x2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        y1+=1;
                        e-=dx;
                    }
                    x1+=1;
                    e+=dy;
                }
            }
            else
            {
                e=dx-dy/2;
                while(y1<=y2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        x1+=1;
                        e-=dy;
                    }
                    y1+=1;
                    e+=dx;
                }
            }
        }
        else
        {
            dy=-dy;
            if(dx>=dy)
            {
                e=dy-dx/2;
                while(x1<=x2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        y1-=1;
                        e-=dx;
                    }
                    x1+=1;
                    e+=dy;
                }
            }
            else
            {
                e=dx-dy/2;
                while(y1>=y2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        x1+=1;
                        e-=dy;
                    }
                    y1-=1;
                    e+=dx;
                }
            }
        }
    }
    else
    {
        dx=-dx;
        if(dy>=0)
        {
            if(dx>=dy)
            {
                e=dy-dx/2;
                while(x1>=x2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        y1+=1;
                        e-=dx;
                    }
                    x1-=1;
                    e+=dy;
                }
            }
            else
            {
                e=dx-dy/2;
                while(y1<=y2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        x1-=1;
                        e-=dy;
                    }
                    y1+=1;
                    e+=dx;
                }
            }
        }
        else
        {
            dy = -dy;
            if(dx>=dy)
            {
                e=dy-dx/2;
                while(x1>=x2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        y1-=1;
                        e-=dx;
                    }
                    x1-=1;
                    e+=dy;
                }
            }
            else
            {
                e=dx-dy/2;
                while(y1>=y2)
                {
                    OLED_DrawPoint(x1,y1,color);
                    if(e>0)
                    {
                        x1-=1;
                        e-=dy;
                    }
                    y1-=1;
                    e+=dx;
                }
            }
        }
    }
}

畫圓
      畫指定半徑的圓,分為靜止態和動態。
//-------------畫圓函數。參數:圓心,半徑,顏色----------
//        畫1/8圓 然后其他7/8對稱畫
//          ---------------->X
//          |(0,0)   0
//          |     7     1
//          |    6       2
//          |     5     3
//       (Y)V        4
//
//      L = x^2 + y^2 - r^2
void OLED_DrawCircle(unsigned char x,unsigned char y,unsigned char r,unsigned char color,unsigned char n)
{
#if 0 //畫靜止的圓
    int a,b,num,i;
    a=0;
    b=r;
   
    while(2*b>a)
    {
      OLED_DrawPoint(x+a,y-b,color);//0~1
        OLED_DrawPoint(x-a,y-b,color);//0~7
        OLED_DrawPoint(x-a,y+b,color);//4~5
        OLED_DrawPoint(x+a,y+b,color);//4~3
        OLED_DrawPoint(x+b,y+a,color);//2~3
        OLED_DrawPoint(x+b,y-a,color);//2~1
        OLED_DrawPoint(x-b,y-a,color);//6~7
        OLED_DrawPoint(x-b,y+a,color);//6~5
        
        a++;
        num=(a*a+b*b)-r*r;//計算畫的點離圓心的距離
        if(num>0)
        {
            b--;
            a--;
        }
        OLED_Refresh_Gram();
    }
#elif 1
    int di=0;
    int con_r=r*r;
   
    int a=0;
    int b=r;
    int bar=0;
    int lvel=0;
   
    lvel = n / 25;
    bar = (n % 25) * (r*10/25) /10;
   
    if(lvel==0)//第一象限
    {
        while(b)
        {   
            if(b<(r-bar))
            {
                OLED_Clear();
                return;
            }
            OLED_DrawPoint(x+a,y+b,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
            OLED_Refresh_Gram();
        }
    }   
    else if(lvel==1)//第二象限
    {
        while(b)
        {   
            OLED_DrawPoint(x+a,y+b,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
        }
        a=0;
        b=r;
        while(b)
        {   
            if(b<(r-bar))
            {
                OLED_Clear();
                return;
            }
            OLED_DrawPoint(x+b,y-a,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
            OLED_Refresh_Gram();
        }
    }
    else if(lvel==2)//第三象限
    {
        while(b)
        {   
            OLED_DrawPoint(x+a,y+b,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
        }
        a=0;
        b=r;
        while(b)
        {   
            OLED_DrawPoint(x+b,y-a,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
        }
        a=0;
        b=r;
        while(b)
        {   
            if(b<(r-bar))
            {
                OLED_Clear();
                return;
            }
            OLED_DrawPoint(x-a,y-b,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
            OLED_Refresh_Gram();
        }
    }
    else if(lvel==3)//第四象限
    {
        while(b)
        {   
            OLED_DrawPoint(x+a,y+b,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
        }
        a=0;
        b=r;
        while(b)
        {   
            OLED_DrawPoint(x+b,y-a,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
        }
        a=0;
        b=r;
        while(b)
        {   
            OLED_DrawPoint(x-a,y-b,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
        }
        a=0;
        b=r;
        while(b)
        {   
            if(b<(r-bar))
            {
                OLED_Clear();
                return;
            }
            OLED_DrawPoint(x-b,y+a,color);
            a++;
            di=a*a+b*b-con_r;
            if(di>0)
            {
                b--;
                a--;
            }
            OLED_Refresh_Gram();
        }
    }
#endif
}

開機動畫
      綜上所述,制作開機動畫。
void Boot_Animation(void)
{
    unsigned char i,num=0;
    for(i=64;i<64+20;i++)
    {
        OLED_DrawPoint(64-num,9+num,1);
        OLED_DrawPoint(64-num,32-9-num,1);  
        num++;
        OLED_Refresh_Gram();
        delay_ms(1);
    }
    OLED_DrawLine(46,4,83,4,1);
    OLED_DrawLine(83,28,46,28,1);
    OLED_Refresh_Gram();//更新顯示到OLED
}

總結
      個人筆記總結,若有問題,歡迎留言、批評指正!!!
若有興趣,歡迎關注公眾號“瀚林創客”,內有資料提取鏈接。



qrcode_for_gh_d8d03909d746_258.jpg

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:85865 發表于 2021-12-7 14:44 | 顯示全部樓層
來個視頻,看 看
回復

使用道具 舉報

ID:394949 發表于 2021-12-9 15:35 | 顯示全部樓層

想看哪個內容?
回復

使用道具 舉報

ID:983499 發表于 2021-12-13 10:30 來自手機 | 顯示全部樓層
我主頁有源碼可以直接用
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 狠狠操av | 国产精品一区在线 | 欧美一区二区三区在线观看 | 午夜网站视频 | 国产目拍亚洲精品99久久精品 | 四虎影院美女 | 做a视频| 最新国产福利在线 | 色视频免费 | 国产一区2区 | 亚洲成人av | 日韩欧美中文字幕在线视频 | 国产日产精品一区二区三区四区 | 成人特级毛片 | 热久久免费视频 | 人人操日日干 | 91精品国产综合久久小仙女图片 | av中文在线 | 国产日韩欧美精品一区二区 | 91精品国产91| 国内精品久久久久久 | 天天操天天天干 | 在线观看国产视频 | 一区网站 | 伊人一区 | 精品久久av | 久久国产精品精品国产色婷婷 | 亚洲欧美日韩电影 | 亚洲社区在线 | 久草欧美视频 | 精品综合网 | 在线观看亚洲精品 | 免费视频一区二区 | 国产精品自产拍 | 青青草一区二区 | av免费电影在线 | 欧美精品一二三区 | 一级黄色片网址 | 亚洲高清免费视频 | 91人人爽 | 欧美激情a∨在线视频播放 成人免费共享视频 |