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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 12872|回復(fù): 28
收起左側(cè)

原創(chuàng):0.96寸單色OLED繪制電子鐘表盤的實現(xiàn)

  [復(fù)制鏈接]
ID:351097 發(fā)表于 2020-2-27 11:55 | 顯示全部樓層 |閱讀模式
    一般很多人做電子鐘都是那種純數(shù)字顯示的,這種比較容易實現(xiàn),而且51黑電子論壇也有很多例子借鑒,重復(fù)去實現(xiàn)也沒有什么新意。我花了2天的時間,寫程序?qū)崿F(xiàn)一個像樣的電子鐘表盤的制作,再加上DS3231時鐘芯片之后,就實現(xiàn)一個電子鐘的制作。 白色.gif
    接下來,我就詳細(xì)講解一下電子鐘盤的實現(xiàn)過程。
    鐘表是由圓形的鐘盤和三條指針構(gòu)成,要在OLED上實現(xiàn)繪制,需要用到畫點函數(shù)、取點函數(shù)、畫線函數(shù)、畫圓函數(shù)、刷新函數(shù)。那首先講一下OLED的圖形驅(qū)動部分。
    一般我們要操作OLED顯示內(nèi)容,都是直接將往OLED的某行某頁寫數(shù)據(jù),這種方法簡單直接,效率比較高。但是,對于像素的細(xì)致操作是很不友好的。比如無法通過SPI讀取某個像素點的狀態(tài),那就無法實現(xiàn)部分自定義像素點的反轉(zhuǎn)。為了更方便操作像素點,這里用使用了一個1024字節(jié)的大數(shù)組來作為OLED的顯存,每個字節(jié)可以操控8個像素點,總共可以操控1024×8=8192個像素點,剛好對應(yīng)0.96寸OLED的128×64的分辨率。實現(xiàn)顯存的好處是方便修改操作像素點,每個像素點的狀態(tài)都一目了然。修改好顯存的內(nèi)容后,直接將顯存的數(shù)據(jù)傳到OLED就可以刷新畫面了。顯存數(shù)組的定義如下:
    uint8 OLED_DISPLAY[8][128]; //顯示緩沖數(shù)組(總共可以表示8192個像素點)
    為了方便定位和操作像素點,使用坐標(biāo)軸的思想,引入x軸和y軸,其中x軸的范圍為0-127(128個像素點),y軸的范圍為0-63(64個像素點)。畫點函數(shù)實現(xiàn)如下:
/**************************************************************************************************
*@函數(shù)            OLED_SetPixel
*
*@簡述            OLED設(shè)置坐標(biāo)像素點狀態(tài)
*
*@輸入?yún)?shù)        x - x坐標(biāo)
*                y - y坐標(biāo)
*                PixelValue - 像素點狀態(tài)(1:填充,0:清空)
*
*@參數(shù)            無
*
*輸出參數(shù)
*
*無
*
*@返回     無
*說明:規(guī)定OLED顯示區(qū)域左上角頂點處為坐標(biāo)原點(0,0),
*      x坐標(biāo)增長方向:向右→
*      y坐標(biāo)增長方向:向下↓
*      坐標(biāo)原點(0,0)對應(yīng)OLED_DISPLAY[0][0],即第零頁第一個像素點
*      坐標(biāo)(127,63)為OLED屏幕又下角頂點
**************************************************************************************************
*/
void OLED_SetPixel(int32 x, int32 y, int32 PixelValue)
{
    int32 pos,bx,temp=0;

    pos = y/8;//計算y坐標(biāo)所在頁
    bx = y%8;//計算位偏移
    temp = 1<<bx;
    if(PixelValue)
    {
        OLED_DISPLAY[pos][x]|=temp;
    }
    else
    {
        OLED_DISPLAY[pos][x]&=~temp;          
    }
}

    很容易看出,OLED_SetPixel函數(shù)操作的對象就是顯存數(shù)組,要點亮某個點,就是將顯存的某個字節(jié)某個位置1。當(dāng)然,由于只是修改顯存的內(nèi)容,還沒有將顯存更新到OLED中,所以不會在OLED不會顯示點亮某個點。有畫點函數(shù),那肯定也要有取點函數(shù)。取點函數(shù),實際上就是讀取顯存的某個字節(jié)某個位的狀態(tài)。取點函數(shù)的實現(xiàn)如下所示:
/**************************************************************************************************
*@函數(shù)            OLED_GetPixel
*
*@簡述            獲取坐標(biāo)像素點狀態(tài)
*
*@輸入?yún)?shù)        x - x坐標(biāo)
*                y - y坐標(biāo)
*
*@參數(shù)            無
*
*輸出參數(shù)
*
*無
*
*@返回          PixelValue - 像素點狀態(tài)
**************************************************************************************************
*/
int32 OLED_GetPixel(int32 x, int32 y)
{
    int32 pos,bx,temp=0;

    pos = y/8;//計算y坐標(biāo)所在頁
    bx = y%8;//計算位偏移
    temp = 1<<bx;

    if(OLED_DISPLAY[pos][x] & temp)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

    接下來是刷新函數(shù),刷新函數(shù)是將顯存的數(shù)據(jù)傳輸?shù)絆LED中,以便實現(xiàn)OLED畫面的更新。刷新函數(shù)和實現(xiàn)如下所示:
/**************************************************************************************************
*@函數(shù)            OLED_Refresh_Display
*
*@簡述            OLED更新顯示
*
*@輸入?yún)?shù)  
*
*@參數(shù)            無
*
*輸出參數(shù)
*
*無
*
*@返回     無
**************************************************************************************************
*/
void OLED_Refresh_Display(void)
{
    uint8 *value;
    value = (uint8*)OLED_DISPLAY;//二級指針轉(zhuǎn)為一級指針
    OLED_WR_Byte (0xb0,OLED_CMD);//開始頁:0
    OLED_WR_Byte (0x00,OLED_CMD); //開始列低地址為0
    OLED_WR_Byte (0x10,OLED_CMD); //開始列高地址為0
    OLED_WR_Bytes(value,1024);
}

    先設(shè)定好起始頁和起始列地址,然后一次性將1024個字節(jié)寫入到OLED中。由于OLED_DISPLAY為二維指針,需要強制轉(zhuǎn)成一維指針才能傳入OLED_WR_Bytes。接下來是畫線函數(shù),這里的畫線函數(shù)涉及到了計算機圖形學(xué)的內(nèi)容,采用Bresenham直線算法思想。畫線函數(shù)的實現(xiàn)如下:
/**************************************************************************************************
*@函數(shù)            OLED_DrawLine
*
*@簡述            OLED畫一條線
*
*@輸入?yún)?shù)        iStartX - 起點x坐標(biāo)
*                iStartY - 起點y坐標(biāo)
*                iEndX - 終點x坐標(biāo)
*                iEndY - 終點y坐標(biāo)
*                fill - 填充(0:不填充,1:填充)
*
*@參數(shù)            無
*
*輸出參數(shù)
*
*無
*
*@返回     無
**************************************************************************************************
*/
void OLED_DrawLine(int16 iStartX, int16 iStartY, int16 iEndX, int16 iEndY, int16 fill)
{
    /*----------------------------------*/
    /* Variable Declaration                                */
    /*----------------------------------*/
    int16  iDx, iDy;
    int16  iIncX, iIncY;
    int16  iErrX = 0, iErrY = 0;
    int16  iDs;
    int16  iCurrentPosX, iCurrentPosY;

    /*----------------------------------*/
    /* Initialize                                                */
    /*----------------------------------*/
    iErrX = 0;
    iErrY = 0;
    iDx = iEndX - iStartX; //X軸差值
    iDy = iEndY - iStartY; //Y軸差值
    iCurrentPosX = iStartX;
    iCurrentPosY = iStartY;

    if(iDx > 0) //X軸差值大于0
    {
        iIncX = 1;
    }
    else
    {
        if(iDx == 0) //X軸差值等于0
        {
            iIncX = 0;
        }
        else   //X軸差值小于0
        {
            iIncX = -1;
            iDx = -iDx; //iDx取反
        }
    }

    if(iDy > 0) //Y軸差值大于0
    {
        iIncY = 1;
    }
    else
    {
        if(iDy == 0) //Y軸差值等于0
        {
            iIncY = 0;
        }
        else    //Y軸差值小于0
        {
            iIncY = -1;
            iDy = -iDy;
        }
    }

    if(iDx > iDy) //斜率小于45°
    {
        iDs = iDx;
    }
    else     //斜率大于等于45°
    {
        iDs = iDy;
    }

    /*----------------------------------*/
    /* Process                                                        */
    /*----------------------------------*/
    for(uint8 i = 0; i <= iDs+1; i++)
    {
        OLED_SetPixel(iCurrentPosX,iCurrentPosY, fill);//當(dāng)前位置畫點
        iErrX += iDx; //X軸偏移
        if(iErrX > iDs)
        {
            iErrX -= iDs;
            iCurrentPosX += iIncX;
        }
        iErrY += iDy; //Y軸偏移
        if(iErrY > iDs)
        {
            iErrY -= iDs;
            iCurrentPosY += iIncY;
        }
    }
}

    Bresenham直線算法實現(xiàn)直線的繪制只用到了簡單的加法運算,計算機可以快速生成直線。這里不花篇幅講解Bresenham直線算法,感興趣的可以百度查詢。OLED_DrawLine函數(shù)只要傳入起點、終點和填充狀態(tài)就可以繪制一條實線或者空線。鐘表盤指針的顯現(xiàn)和消除就可以用這個函來實現(xiàn)。 接下來是畫圓函數(shù),畫圓函數(shù)是基于中點畫圓法思想實現(xiàn)的,畫圓函數(shù)實現(xiàn)如下所示:
/**************************************************************************************************
*@函數(shù)            OLED_DrawCircle
*
*@簡述            OLED畫圓
*
*@輸入?yún)?shù)        uiCx - 圓心x坐標(biāo)
*                uiCy - 圓心y坐標(biāo)
*                uiRadius - 半徑
*                eEdgeColor - 邊緣填充(0:不填充,1:填充)
*                eFillColor - 圓內(nèi)區(qū)域填充(0:不填充,1:填充)
*
*@參數(shù)            無
*
*輸出參數(shù)
*
*無
*
*@返回     無
**************************************************************************************************
*/
void OLED_DrawCircle(uint8 uiCx, uint8 uiCy, uint8 uiRadius, uint8 eEdgeColor, uint8 eFillColor)
{
     /*----------------------------------*/
    /* Variable Declaration                                */
    /*----------------------------------*/
    uint8 uiPosXOffset, uiPosYOffset;
    int16 uiPosXOffset_Old, uiPosYOffset_Old;
    int16 iXChange, iYChange, iRadiusError;

    /*----------------------------------*/
    /* Initialize                                                */
    /*----------------------------------*/
    uiPosXOffset                                = uiRadius;
    uiPosYOffset                                = 0;
    uiPosXOffset_Old                        = 0xFFFF;
    uiPosYOffset_Old                        = 0xFFFF;
    iXChange                                        = 1 - 2 * uiRadius;
    iYChange                                        = 1;
    iRadiusError                                = 0;

    /*----------------------------------*/
    /* Process                                                        */
    /*----------------------------------*/
    if(uiRadius < 1) //半徑小于1
    {
        OLED_SetPixel(uiCx, uiCy, eEdgeColor);
    }
    else
    {
        while(uiPosXOffset >= uiPosYOffset)
        {
            if((uiPosXOffset_Old != uiPosXOffset) || (uiPosYOffset_Old != uiPosYOffset) )
            {
                // Fill the circle 填充圈圈
                if((uiRadius > 1) && (eFillColor != 2) && (uiPosXOffset_Old != uiPosXOffset))
                {

                    OLED_DrawLine(uiCx-uiPosXOffset, uiCy-uiPosYOffset+1, uiCx-uiPosXOffset, uiCy+uiPosYOffset-1, eFillColor);
                    OLED_DrawLine(uiCx+uiPosXOffset, uiCy-uiPosYOffset+1, uiCx+uiPosXOffset, uiCy+uiPosYOffset-1, eFillColor);
                    uiPosXOffset_Old = uiPosXOffset;
                }
                OLED_DrawLine(uiCx-uiPosYOffset, uiCy-uiPosXOffset+1, uiCx-uiPosYOffset, uiCy+uiPosXOffset-1, eFillColor);
                OLED_DrawLine(uiCx+uiPosYOffset, uiCy-uiPosXOffset+1, uiCx+uiPosYOffset, uiCy+uiPosXOffset-1, eFillColor);
                uiPosYOffset_Old = uiPosYOffset;

                // Draw edge.
                OLED_SetPixel(uiCx+uiPosXOffset, uiCy+uiPosYOffset, eEdgeColor);
                OLED_SetPixel(uiCx-uiPosXOffset, uiCy+uiPosYOffset, eEdgeColor);
                OLED_SetPixel(uiCx-uiPosXOffset, uiCy-uiPosYOffset, eEdgeColor);
                OLED_SetPixel(uiCx+uiPosXOffset, uiCy-uiPosYOffset, eEdgeColor);
                OLED_SetPixel(uiCx+uiPosYOffset, uiCy+uiPosXOffset, eEdgeColor);
                OLED_SetPixel(uiCx-uiPosYOffset, uiCy+uiPosXOffset, eEdgeColor);
                OLED_SetPixel(uiCx-uiPosYOffset, uiCy-uiPosXOffset, eEdgeColor);
                OLED_SetPixel(uiCx+uiPosYOffset, uiCy-uiPosXOffset, eEdgeColor);
            }
            uiPosYOffset++;
            iRadiusError += iYChange;
            iYChange += 2;
            if ((2 * iRadiusError + iXChange) > 0)
            {
                uiPosXOffset--;
                iRadiusError += iXChange;
                iXChange += 2;
            }
        }
    }
}

    這個畫圓函數(shù)也只是用到簡單的加法運算,不涉及到浮點運算,不依賴于<math.h>數(shù)學(xué)庫。除了可以畫圓圈的邊緣線,還可以填充圓形內(nèi)部區(qū)域?梢杂卯媹A函數(shù)繪制鐘表盤的外形。
    上面介紹了OLED圖形驅(qū)動的幾個基本圖形操作函數(shù),接下來就利用上面的函數(shù)來制作電子鐘表盤。電子鐘表盤的制作難點是指針的位置處理,兩點可以確定一條直線,指針的一端是轉(zhuǎn)軸,另一端指向刻度點的方向。轉(zhuǎn)軸的坐標(biāo)是保持不變的,要實現(xiàn)指針的轉(zhuǎn)動,需要將指針的另一端指向一下一個刻度點的坐標(biāo)。鐘表有60個刻度點,只要找出60個刻度點對應(yīng)的坐標(biāo),就能實現(xiàn)指針的轉(zhuǎn)動。圓是上下左右對稱的,只要找出四分之一圓區(qū)域的15個刻度點,就不難算出其他45個刻度點,F(xiàn)在的問題是如何計算出這15個刻度點的坐標(biāo)?
    很容易想到聯(lián)立直線方程和圓方向就可以交點計算出來。直線方程有15條,每條傾斜角度相差6°,直線斜率可以用tanθ表示,將查表后記錄到數(shù)組中方便查詢:
uint32 angle_tan[] = {
//0°  6°  12°  18°  24°  30°  36°  42°  48°   54°    60°  66°   72°   78°   84°    90°
  0,1051,2126,3249,4452,5773,7265,9004,11106,13763,17320,22460,30776,47046,95143,0xffffffff
};//tanθ擴大1000倍

    通過調(diào)用OLED_DrawCircle函數(shù),可以將圓形繪制出來,然后調(diào)用OLED_GetPixel函數(shù),遍歷顯存的數(shù)據(jù),可以把構(gòu)成圓形的像素點的坐標(biāo)找出來。只要將像素點的坐標(biāo)帶入到直線方程,就能確定哪個像素點可以作為刻度點。直線點斜式方程y=kx+b,為了消除b常量方便計算,將圓心定為坐標(biāo)原點。那么直線方程就是正比例函數(shù)y=kx,其中斜率k可用tanθ表示。尋找刻度點的實現(xiàn)如下所示:
/**************************************************************************************************
*@函數(shù)            clock_calculate_coordinate
*
*@簡述            計算針軌跡右下部數(shù)字15-30的坐標(biāo)
*
*@輸入?yún)?shù)        clock_hand - 類別:時針、分針、秒針
*                length - 指針長度
*
*@參數(shù)            無
*
*@返回     
**************************************************************************************************
*/
static void clock_calculate_coordinate(uint8 clock_hand,uint8 length)
{
    uint8 x,y;
    uint8 rad = 0;
    uint16 *coordinate_array;
    double value = 0;
    double angel = 0;
    double cal_x,cal_y;
    double all_value;

    OLED_Clear_Ram();//清顯存

    OLED_DrawCircle(CIRCLE_X,CIRCLE_Y,length,1,0);//繪制軌跡
    rad = length;

    switch(clock_hand) //判斷指針類型
    {
        case SECOND_HAND:  //秒針
          coordinate_array = second_coordinate;
          break;
        case MINUTE_HAND: //分針
          coordinate_array = minute_coordinate;
          break;
        case HOUR_HAND:  //時針
          coordinate_array = hour_coordinate;
          break;
        default:
          break;
    }

    for(uint8 k = 0; k < 16; k++) //計算軌跡右下部15-30的坐標(biāo)
    {
       angel = angle_tan[k];
       all_value = 977889999;
       for(uint8 i = CIRCLE_X - 1; i <= CIRCLE_X + rad; i++)
       {
          for(uint8 j = CIRCLE_Y - 1; j <= CIRCLE_Y + rad; j++)
          {
              if(OLED_GetPixel(i,j)) //掃描針的軌跡
              {              
                  cal_x = i-CIRCLE_X;
                  cal_y = j-CIRCLE_Y;
                  value =cal_y*10000 - angel*cal_x;
                  if(value < 0)//負(fù)數(shù)處理
                  {
                      value = -value;
                  }
                  if(all_value - value> 0) //尋找最合適的坐標(biāo)
                  {
                      all_value = value;
                      x = i;
                      y = j;                           
                  }                                                
              }
          }
       }
      coordinate_array[k] = y;  //記錄y坐標(biāo)
      coordinate_array[k] <<= 8;
      coordinate_array[k] |= x; //記錄x坐標(biāo)
    }
    OLED_Clear_Ram();//清顯存
}   

    選擇計算數(shù)字15-30的坐標(biāo)的原因主要是這個區(qū)域坐標(biāo)x和坐標(biāo)y都是正數(shù),比較好處理。程序分別計算了不同長度的秒針、分針和時針的刻度點坐標(biāo),后面就可以根據(jù)刻度點來實現(xiàn)秒針、分針和時針的轉(zhuǎn)動。接下來是根據(jù)計算保持的刻度點坐標(biāo),計算出剩下45個刻度點坐標(biāo)。區(qū)域指圓形的四個扇形區(qū)域,鐘表上就是0-15、15-30、30-45、45-60這四個區(qū)域。對傳入的數(shù)字先做區(qū)域標(biāo)記,再轉(zhuǎn)成15-30之間的數(shù),這樣方便對應(yīng)刻度點坐標(biāo)。再根據(jù)區(qū)域,將刻度點坐標(biāo)做對稱換算即可。
    下面動圖測試了一下秒針,可以看到可以360°旋轉(zhuǎn)。說明刻度點坐標(biāo)都在圓形邊沿。
測試1.gif

    圓形主要是顯示秒針跑的軌跡而特意繪制出來的,實際在計算出15個坐標(biāo)后,可以把圓形軌跡刪除。分針和時針也是類似的操作,只是軌跡是不同半徑的圓而已?梢酝ㄟ^修改如下定義的宏:
#define SECOND_HAND_LENGTH   28    //秒針長度
#define MINUTE_HAND_LENGTH   27    //分針長度
#define HOUR_HAND_LENGTH     18    //時針長度

  再根據(jù)秒針、時針和分針的簡單關(guān)系,程序?qū)崿F(xiàn)如下:
/**************************************************************************************************
*@函數(shù)            clock_show_time
*
*@簡述            表盤顯示時間函數(shù)
*
*@輸入?yún)?shù)         time - 時間結(jié)構(gòu)體
*                 state - 狀態(tài)
*               
*@參數(shù)            無
*
*輸出參數(shù)         無
*
*@返回     
**************************************************************************************************
*/
void clock_show_time(clock_time time,uint8 state)
{
    uint8 x,y;

    if(time.hours > 12) //如果為24小時
    {
      time.hours -= 12;//轉(zhuǎn)為12小時制
    }

    if(state)
    {
        OLED_ShowChar(CIRCLE_X-5,2,'1',12); //數(shù)字1
        OLED_ShowChar(CIRCLE_X,2,'2',12); //數(shù)字2
        OLED_ShowChar(CIRCLE_X-2,50,'6',12);//數(shù)字6
        OLED_ShowChar(CIRCLE_X+24,25,'3',12);//數(shù)字3
        OLED_ShowChar(CIRCLE_X-29,25,'9',12);//數(shù)字9

        OLED_DrawCircle(CIRCLE_X,CIRCLE_Y,2,1,1);//繪制轉(zhuǎn)軸
    }

    clock_get_coordinate(time.hours*5+time.minutes/12,HOUR_HAND,&x,&y);
    OLED_DrawLine(CIRCLE_X,CIRCLE_Y,x,y,state); //繪制時針

    clock_get_coordinate(time.minutes,MINUTE_HAND,&x,&y);
    OLED_DrawLine(CIRCLE_X,CIRCLE_Y,x,y,state); //繪制分針

    clock_get_coordinate(time.seconds,SECOND_HAND,&x,&y);
    OLED_DrawLine(CIRCLE_X,CIRCLE_Y,x,y,state); //繪制秒針
}

    clock_show_time可以根據(jù)所傳入的時間結(jié)構(gòu)體來繪制三條指針,參數(shù)state是繪制和擦除指針用的。下面是時鐘運行函數(shù):
/**************************************************************************************************
*@函數(shù)            clock_run
*
*@簡述            運行表盤函數(shù)
*
*@輸入?yún)?shù)         time - 時間結(jié)構(gòu)體
*               
*@參數(shù)            無
*
*輸出參數(shù)         無
*
*@返回     
**************************************************************************************************
*/
void clock_run(clock_time time)
{
    clock_show_time(pre_time,0);//擦除前一次時間軌跡
    clock_show_time(time,1);//顯示當(dāng)前時間
    pre_time = time;//記錄最新時間
}

    定義一個全局結(jié)構(gòu)體變量pre_time 來記錄上次時間。每次更新時間前,會先把上次的指針軌跡擦除,再繪制新的指針軌跡。下面的動圖是秒針、分針和時針的運行過程。
測試2.gif

    外圍有12個小點,分別代表數(shù)字1-數(shù)字12,其中4個小點被數(shù)字擋住了。要生成這12個小點,也是比較簡單。先將其看成指針的軌跡來生成計算坐標(biāo),再從60個坐標(biāo)中取出數(shù)字1-12數(shù)字這12個坐標(biāo)點,把12個坐標(biāo)點畫上,就可以了。效果如下圖所示:
刻度盤.jpg

    鐘表盤的制作基本算完成了,再加上DS3231時鐘芯片,就可以實時顯示時間了。效果如下圖所示:
成品圖.jpg





回復(fù)

使用道具 舉報

ID:351097 發(fā)表于 2020-6-1 15:20 | 顯示全部樓層
工程是基于IAR for 8051,完整的工程已經(jīng)上傳到github,鏈接地址:github.com/sms-wyt/OLED_CLOCK,如果有需要的,可以自行g(shù)it clone下來。
回復(fù)

使用道具 舉報

ID:156220 發(fā)表于 2020-2-28 10:07 | 顯示全部樓層
謝謝樓主的經(jīng)驗分享,學(xué)習(xí)了,
回復(fù)

使用道具 舉報

ID:476527 發(fā)表于 2020-2-28 13:45 | 顯示全部樓層
我前些日子正有這個想法,沒想到樓主已經(jīng)實現(xiàn)了,馬克一下,有時間再看
回復(fù)

使用道具 舉報

ID:207943 發(fā)表于 2020-2-28 15:38 | 顯示全部樓層
謝謝樓主無私分享,時鐘很不錯,喜歡,學(xué)習(xí)了!
回復(fù)

使用道具 舉報

ID:71535 發(fā)表于 2020-2-28 16:06 | 顯示全部樓層
這個要頂,雖然還不太明白,要好好學(xué)習(xí)。
回復(fù)

使用道具 舉報

ID:631668 發(fā)表于 2020-3-6 11:31 | 顯示全部樓層
感謝樓主,最近在愁這個
回復(fù)

使用道具 舉報

ID:35873 發(fā)表于 2020-3-6 11:59 | 顯示全部樓層
贊  不錯  對玩屏的新手大有幫助   
回復(fù)

使用道具 舉報

ID:686739 發(fā)表于 2020-3-6 12:10 來自手機 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報

ID:706822 發(fā)表于 2020-3-12 10:09 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報

ID:715893 發(fā)表于 2020-4-16 21:49 | 顯示全部樓層
請問有OLED_DISPLAY這些函數(shù)的介紹嘛,想看整個代碼 可以嘛。想學(xué)一下顯存的使用方法
回復(fù)

使用道具 舉報

ID:351097 發(fā)表于 2020-4-18 13:06 | 顯示全部樓層
大神666666 發(fā)表于 2020-4-16 21:49
請問有OLED_DISPLAY這些函數(shù)的介紹嘛,想看整個代碼 可以嘛。想學(xué)一下顯存的使用方法

關(guān)于OLED的顯示基本操作代碼都在上面羅列出來了。OLED_DISPLAY是一個1k大小的數(shù)組,也就是顯存。對顯存的基本操作,只要看OLED_SetPixel、OLED_GetPixel、 OLED_Refresh_Display這三個函數(shù)即可。多看幾次就明白了。
回復(fù)

使用道具 舉報

ID:715893 發(fā)表于 2020-4-19 14:06 | 顯示全部樓層
沒有你 發(fā)表于 2020-4-18 13:06
關(guān)于OLED的顯示基本操作代碼都在上面羅列出來了。OLED_DISPLAY是一個1k大小的數(shù)組,也就是顯存。對顯存的 ...

OLED_WR_Bytes這些還是不懂,主要想學(xué)習(xí)顯存的使用方法
回復(fù)

使用道具 舉報

ID:394719 發(fā)表于 2020-5-15 10:11 | 顯示全部樓層
樓主,請問能把全部代碼文件分享一下嗎?
回復(fù)

使用道具 舉報

ID:88256 發(fā)表于 2020-5-29 10:46 | 顯示全部樓層
謝謝分享!學(xué)習(xí)一下
回復(fù)

使用道具 舉報

ID:138443 發(fā)表于 2020-5-31 09:24 | 顯示全部樓層
怎么不上傳整套源碼呢???
回復(fù)

使用道具 舉報

ID:283908 發(fā)表于 2020-5-31 10:45 | 顯示全部樓層
學(xué)習(xí)了,論壇有你更精彩,感謝分享。
回復(fù)

使用道具 舉報

ID:428114 發(fā)表于 2020-5-31 16:16 | 顯示全部樓層
樓主很給力啊
回復(fù)

使用道具 舉報

ID:351097 發(fā)表于 2020-6-1 16:31 | 顯示全部樓層
lizhendong 發(fā)表于 2020-5-31 09:24
怎么不上傳整套源碼呢???

看第一條置頂評論
回復(fù)

使用道具 舉報

ID:628703 發(fā)表于 2020-6-2 16:15 | 顯示全部樓層
好東西,謝謝樓主分享!
回復(fù)

使用道具 舉報

ID:740383 發(fā)表于 2020-6-3 11:26 | 顯示全部樓層
好資源
回復(fù)

使用道具 舉報

ID:361734 發(fā)表于 2020-6-19 11:24 | 顯示全部樓層
樓主請問下是用的什么型號的單片機, 有那么大的RAM供使用的 ;
回復(fù)

使用道具 舉報

ID:117310 發(fā)表于 2020-6-19 20:02 | 顯示全部樓層
感謝分享! 對于OLED畫線問題也是困擾了我很久,代碼下載了研究研究,先謝謝!
回復(fù)

使用道具 舉報

ID:351097 發(fā)表于 2020-6-21 14:31 | 顯示全部樓層
starv 發(fā)表于 2020-6-19 11:24
樓主請問下是用的什么型號的單片機, 有那么大的RAM供使用的 ;

用STC8A8K64S4
回復(fù)

使用道具 舉報

ID:272269 發(fā)表于 2021-7-23 14:44 | 顯示全部樓層
樓主請問一下關(guān)于更新的問題  如果一只表針落在 6 這個數(shù)字上 到下一次跑動 這一只表針就會向前跑 現(xiàn)在問題來了 在上一次的表針的位置通常來說都是算法消失處理 但是 現(xiàn)在落在6上 這樣子 常規(guī)處理就會把6這個數(shù)字給消失一點  請問這個問題你是這么克服的  請問是周期性的 更新那個表盤 呢 還是有其他方法可以解決這個問題  我也做過這個實驗 使用stc12c做的
回復(fù)

使用道具 舉報

ID:351097 發(fā)表于 2021-7-23 17:23 | 顯示全部樓層
jizi 發(fā)表于 2021-7-23 14:44
樓主請問一下關(guān)于更新的問題  如果一只表針落在 6 這個數(shù)字上 到下一次跑動 這一只表針就會向前跑 現(xiàn)在問題 ...

如果圖省事,每次指針移動都更新表盤。如果要細(xì)致處理,比如指針覆蓋到數(shù)字6的情況,則要先重繪制數(shù)字6,再繪制指針。
回復(fù)

使用道具 舉報

ID:79094 發(fā)表于 2024-3-30 00:32 | 顯示全部樓層
看起來 很厲害   大神很多啊
回復(fù)

使用道具 舉報

ID:961114 發(fā)表于 2024-6-12 17:11 | 顯示全部樓層
一個神奇的鬧鐘, 郭天祥老師的
=== @STC8H4K64TL-40MHz-LQFP48 實現(xiàn)
=== MCU 自帶【觸摸按鍵】,
         MCU 自帶【80mA大電流LED數(shù)碼管自動刷新驅(qū)動】顯示,
         MCU 自帶【RTC】
51hei截圖20240612171025.png
回復(fù)

使用道具 舉報

ID:608729 發(fā)表于 2024-6-13 11:39 | 顯示全部樓層

謝謝樓主無私分享,時鐘很不錯,喜歡,學(xué)習(xí)了!
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 91成人在线| 蜜桃传媒一区二区 | 日韩二三区 | 国产精品视频一区二区三区 | 中文字幕精品视频 | 一区二区三区四区国产精品 | 精品国产第一区二区三区 | 中文成人无字幕乱码精品 | 国产国产精品久久久久 | www.yw193.com| 精品日韩一区 | 欧美日韩亚洲一区 | 久久精品成人一区 | 国产激情91久久精品导航 | 久久国产成人 | 精品久久久久久国产 | 密室大逃脱第六季大神版在线观看 | 国产精品日韩欧美一区二区 | 蜜桃在线播放 | 91在线观看 | 亚洲精色 | 91资源在线 | 国产精品永久免费视频 | 国产精品美女在线观看 | 久久91av | 天天爽夜夜爽精品视频婷婷 | 亚洲久久 | 综合久久av | 成年人网站在线观看视频 | 日韩精品一区二区三区中文在线 | 午夜在线免费观看视频 | 人妖av| aaa综合国产 | 日韩在线不卡 | 日日干干 | 亚洲精品久久久久avwww潮水 | 欧美freesex黑人又粗又大 | 国产精品欧美日韩 | 色综合久久久久 | 免费激情网站 | 亚洲 欧美 日韩在线 |