找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 10088|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

STC15系列單片機利用硬件SPI可以提高顯示速度一倍

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:328014 發(fā)表于 2018-8-9 03:28 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
買了1塊SPI接口的OLED屏。
商家提供的51下的驅(qū)動代碼是軟件模擬SPI的方式實現(xiàn)的。
雖然速度上基本上可以達到應(yīng)用的要求了,但是出于實驗的目的,周末研究了一下15系列硬件SPI,改寫了一下驅(qū)動,并且比較了利用軟硬兩種SPI之間的差距。發(fā)現(xiàn)利用硬件SPI至少可以提高顯示速度50%以上的效率。

看來以后在條件允許的情況下,多利用硬件SPI對程序的執(zhí)行效率的提高是很有幫助的。

具體思路如下:
1.改寫驅(qū)動代碼
將往OLED屏寫入字節(jié)的函數(shù)改為硬件SPI方式寫入。
用_HARD_SPI_宏來切換軟硬SPI接口
  1.     #ifdef    _HARD_SPI_
  2.     void OLED_WR_Byte(u8 dat, u8 cmd)
  3.     {
  4.         if(cmd)
  5.             OLED_DC_Set();
  6.         else
  7.             OLED_DC_Clr();
  8.         SPDAT = dat;
  9.         while(!(SPSTAT&SPIF));
  10.         SPSTAT = SPIF | WCOL;
  11.         OLED_DC_Set();        
  12.     }
  13.     #else
  14.     void OLED_WR_Byte(u8 dat,u8 cmd)
  15.     {
  16.         u8 i;
  17.         if(cmd)
  18.             OLED_DC_Set();
  19.         else
  20.             OLED_DC_Clr();
  21.         OLED_CS_Clr();
  22.         for(i=0;i<8;i++)
  23.         {              
  24.             OLED_SCLK_Clr();
  25.             if(dat&0x80)
  26.             {
  27.                 OLED_SDIN_Set();
  28.             }
  29.             else
  30.             {
  31.                 OLED_SDIN_Clr();
  32.             }
  33.             OLED_SCLK_Set();
  34.             dat<<=1;  
  35.         }
  36.         OLED_CS_Set();
  37.         OLED_DC_Set();        
  38.     }
  39.     #endif
復(fù)制代碼
2.在main函數(shù)中對顯示函數(shù)調(diào)用10000次
在循環(huán)調(diào)用前清除計數(shù)器并打開定時中斷(定時器設(shè)定為1ms,晶振主頻為30M)
定時中斷負責計數(shù)。
10000次顯示結(jié)束后輸出定時中斷計數(shù)器的值。
以下是main.c
  1.     #include "STC15W4Kxxs4.h"
  2.     #include "__c_param__.h"
  3.     #include "display.h"
  4.     #include "resource.h"
  5.     unsigned long ulCount = 0;
  6.     void timer0_int (void) interrupt 1
  7.     {
  8.        ulCount++;
  9.     }
  10.     void Timer0Init(void)        //1毫秒@30.000MHz
  11.     {
  12.         AUXR |= 0x80;        //定時器時鐘1T模式
  13.         TMOD &= 0xF0;        //設(shè)置定時器模式
  14.         TL0 = 0xD0;        //設(shè)置定時初值
  15.         TH0 = 0x8A;        //設(shè)置定時初值
  16.         TF0 = 0;        //清除TF0標志
  17.         TR0 = 1;        //定時器0開始計時
  18.     }
  19.     void main()
  20.     {
  21.         int    i;
  22.         unsigned char    col,row;
  23.         
  24.         Timer0Init();
  25.         
  26.         initial_lcd();
  27.         
  28.         clear_screen();
  29.         display_graphic_Nx8M(1,1, dabai, 0, 128, 8);
  30.         ulCount = 0;
  31.         EA = 1;
  32.         ET0 = 1;                 //Timer0中斷允許
  33.         //顯示10000次 17*32大小的數(shù)字
  34.         for(i = 0; i < 10000; i++)
  35.         {
  36.             display_graphic_Nx8M((i%2)*FONT_LARGE_H+1,1, font17x32, i % FONT_LARGE_C, FONT_LARGE_W, FONT_LARGE_H);
  37.     //        display_graphic_Nx8M(1,1, dabai, 0, 128, 8);
  38.     //        display_graphic_Nx8M((i%8),1,font7x8, i % FONT_SMALL_C, FONT_SMALL_W, FONT_SMALL_H);
  39.         }
  40.         ET0 = 0;                 //Timer0中斷允許
  41.         EA = 0;
  42.         
  43.         clear_screen();
  44.         col = 1;
  45.         row = 4;
  46.         display_graphic_Nx8M(row,col, font11x24, (ulCount / 1000000) % 10, FONT_BIG_W, FONT_BIG_H);
  47.         col += FONT_BIG_W;
  48.         display_graphic_Nx8M(row,col, font11x24, (ulCount / 100000) % 10, FONT_BIG_W, FONT_BIG_H);
  49.         col += FONT_BIG_W;
  50.         display_graphic_Nx8M(row,col, font11x24, (ulCount / 10000) % 10, FONT_BIG_W, FONT_BIG_H);
  51.         col += FONT_BIG_W;
  52.         display_graphic_Nx8M(row,col, font11x24, (ulCount / 1000) % 10, FONT_BIG_W, FONT_BIG_H);
  53.         col += FONT_BIG_W;
  54.         display_graphic_Nx8M(row,col, font11x24, (ulCount / 100) % 10, FONT_BIG_W, FONT_BIG_H);
  55.         col += FONT_BIG_W;
  56.         display_graphic_Nx8M(row,col, font11x24, (ulCount / 10) % 10, FONT_BIG_W, FONT_BIG_H);
  57.         col += FONT_BIG_W;
  58.         display_graphic_Nx8M(row,col, font11x24, (ulCount) % 10, FONT_BIG_W, FONT_BIG_H);
  59.         
  60.         while(1);
  61.     }
復(fù)制代碼
最后結(jié)果:
顯示17x32大小數(shù)字時       硬件SPI:3605ms          軟件SPI:8030ms         提高:56.3%
顯示128x64大小的圖像     硬件SPI:22458ms        軟件SPI:51544ms       提高:56.4%
顯示7x8大小的數(shù)字           硬件SPI:597ms            軟件SPI:1156ms         提高:48.4%

對比測試的視頻


彈來彈去的時間顯示。



評分

參與人數(shù) 1黑幣 +10 收起 理由
NPC-1024 + 10 很給力!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:371423 發(fā)表于 2018-8-15 10:57 | 只看該作者
有機會我也要學習一下硬件控制器
回復(fù)

使用道具 舉報

板凳
ID:223707 發(fā)表于 2019-2-21 14:51 | 只看該作者
TFT_KMRTM24024: 2.4寸TFT觸摸屏,4線SPI,
刷屏6次,軟件SPI:7032ms, 硬件SPI:1920ms
差別很大
回復(fù)

使用道具 舉報

地板
ID:419072 發(fā)表于 2019-6-6 17:30 | 只看該作者
正在學習硬件spi,和cs5530通信程序。
回復(fù)

使用道具 舉報

5#
ID:292359 發(fā)表于 2019-12-2 11:52 | 只看該作者
最近無聊正在研究一塊OLED小屏
回復(fù)

使用道具 舉報

6#
ID:655943 發(fā)表于 2020-4-16 21:09 | 只看該作者
請教,帶字庫的TFT或OLCD有兩處片選,但共用其它三個腳,怎么設(shè)置??
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表