買了1塊SPI接口的OLED屏。
商家提供的51下的驅動代碼是軟件模擬SPI的方式實現的。
雖然速度上基本上可以達到應用的要求了,但是出于實驗的目的,周末研究了一下15系列硬件SPI,改寫了一下驅動,并且比較了利用軟硬兩種SPI之間的差距。發現利用硬件SPI至少可以提高顯示速度50%以上的效率。
看來以后在條件允許的情況下,多利用硬件SPI對程序的執行效率的提高是很有幫助的。
具體思路如下:
1.改寫驅動代碼
將往OLED屏寫入字節的函數改為硬件SPI方式寫入。
用_HARD_SPI_宏來切換軟硬SPI接口
- #ifdef _HARD_SPI_
- void OLED_WR_Byte(u8 dat, u8 cmd)
- {
- if(cmd)
- OLED_DC_Set();
- else
- OLED_DC_Clr();
- SPDAT = dat;
- while(!(SPSTAT&SPIF));
- SPSTAT = SPIF | WCOL;
- OLED_DC_Set();
- }
- #else
- void OLED_WR_Byte(u8 dat,u8 cmd)
- {
- u8 i;
- if(cmd)
- OLED_DC_Set();
- else
- OLED_DC_Clr();
- OLED_CS_Clr();
- for(i=0;i<8;i++)
- {
- OLED_SCLK_Clr();
- if(dat&0x80)
- {
- OLED_SDIN_Set();
- }
- else
- {
- OLED_SDIN_Clr();
- }
- OLED_SCLK_Set();
- dat<<=1;
- }
- OLED_CS_Set();
- OLED_DC_Set();
- }
- #endif
復制代碼 2.在main函數中對顯示函數調用10000次
在循環調用前清除計數器并打開定時中斷(定時器設定為1ms,晶振主頻為30M)
定時中斷負責計數。
10000次顯示結束后輸出定時中斷計數器的值。
以下是main.c
- #include "STC15W4Kxxs4.h"
- #include "__c_param__.h"
- #include "display.h"
- #include "resource.h"
- unsigned long ulCount = 0;
- void timer0_int (void) interrupt 1
- {
- ulCount++;
- }
- void Timer0Init(void) //1毫秒@30.000MHz
- {
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD &= 0xF0; //設置定時器模式
- TL0 = 0xD0; //設置定時初值
- TH0 = 0x8A; //設置定時初值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- }
- void main()
- {
- int i;
- unsigned char col,row;
-
- Timer0Init();
-
- initial_lcd();
-
- clear_screen();
- display_graphic_Nx8M(1,1, dabai, 0, 128, 8);
- ulCount = 0;
- EA = 1;
- ET0 = 1; //Timer0中斷允許
- //顯示10000次 17*32大小的數字
- for(i = 0; i < 10000; i++)
- {
- display_graphic_Nx8M((i%2)*FONT_LARGE_H+1,1, font17x32, i % FONT_LARGE_C, FONT_LARGE_W, FONT_LARGE_H);
- // display_graphic_Nx8M(1,1, dabai, 0, 128, 8);
- // display_graphic_Nx8M((i%8),1,font7x8, i % FONT_SMALL_C, FONT_SMALL_W, FONT_SMALL_H);
- }
- ET0 = 0; //Timer0中斷允許
- EA = 0;
-
- clear_screen();
- col = 1;
- row = 4;
- display_graphic_Nx8M(row,col, font11x24, (ulCount / 1000000) % 10, FONT_BIG_W, FONT_BIG_H);
- col += FONT_BIG_W;
- display_graphic_Nx8M(row,col, font11x24, (ulCount / 100000) % 10, FONT_BIG_W, FONT_BIG_H);
- col += FONT_BIG_W;
- display_graphic_Nx8M(row,col, font11x24, (ulCount / 10000) % 10, FONT_BIG_W, FONT_BIG_H);
- col += FONT_BIG_W;
- display_graphic_Nx8M(row,col, font11x24, (ulCount / 1000) % 10, FONT_BIG_W, FONT_BIG_H);
- col += FONT_BIG_W;
- display_graphic_Nx8M(row,col, font11x24, (ulCount / 100) % 10, FONT_BIG_W, FONT_BIG_H);
- col += FONT_BIG_W;
- display_graphic_Nx8M(row,col, font11x24, (ulCount / 10) % 10, FONT_BIG_W, FONT_BIG_H);
- col += FONT_BIG_W;
- display_graphic_Nx8M(row,col, font11x24, (ulCount) % 10, FONT_BIG_W, FONT_BIG_H);
-
- while(1);
- }
復制代碼 最后結果:
顯示17x32大小數字時 硬件SPI:3605ms 軟件SPI:8030ms 提高:56.3%
顯示128x64大小的圖像 硬件SPI:22458ms 軟件SPI:51544ms 提高:56.4%
顯示7x8大小的數字 硬件SPI:597ms 軟件SPI:1156ms 提高:48.4%
對比測試的視頻
彈來彈去的時間顯示。
|