標(biāo)題: STC15系列單片機(jī)利用硬件SPI可以提高顯示速度一倍 [打印本頁]

作者: 51hei團(tuán)團(tuán)    時間: 2018-8-9 03:28
標(biāo)題: STC15系列單片機(jī)利用硬件SPI可以提高顯示速度一倍
買了1塊SPI接口的OLED屏。
商家提供的51下的驅(qū)動代碼是軟件模擬SPI的方式實現(xiàn)的。
雖然速度上基本上可以達(dá)到應(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)
定時中斷負(fù)責(zé)計數(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標(biāo)志
  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%

對比測試的視頻
http://v.youku.com/v_show/id_XMTQ3Nzg4ODcwOA==.html

彈來彈去的時間顯示。
http://v.youku.com/v_show/id_XMTQ3ODIwMDA1Ng==.html



作者: NPC-1024    時間: 2018-8-15 10:57
有機(jī)會我也要學(xué)習(xí)一下硬件控制器
作者: cqt5001    時間: 2019-2-21 14:51
TFT_KMRTM24024: 2.4寸TFT觸摸屏,4線SPI,
刷屏6次,軟件SPI:7032ms, 硬件SPI:1920ms
差別很大
作者: miyuhao    時間: 2019-6-6 17:30
正在學(xué)習(xí)硬件spi,和cs5530通信程序。
作者: a4umi001    時間: 2019-12-2 11:52
最近無聊正在研究一塊OLED小屏
作者: 老電子    時間: 2020-4-16 21:09
請教,帶字庫的TFT或OLCD有兩處片選,但共用其它三個腳,怎么設(shè)置??




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1