文章地址:https://www.cnblogs.com/jqdy/p/12665430.html
1. 硬件連接
1.1 64引腳的STC8A8K64S4A12
使用的是最小核心板,所以引腳皆引出可供使用。其他接口只有USB口,起到供電及下載燒寫的作用。
1.2 12864液晶模塊
店家提供的使用說明較為雜亂,后續除模塊信息外,關於控制芯片的內容均參考ST7920手冊。
- 顯示控制芯片使用的是ST7920
- 模塊有20個外接引腳(見圖2)
- PCB背板有選擇串口和並口的兩組焊點,短接后可分別選擇串口和並口
- 背板有一個可調電阻,用以調節對比度
1.3 連接方式
因為還有其他幾個外接模塊,顯示模塊采用並口會占用過多I/O口,所以采用SPI串口連接方式,連接示意圖及照片圖1、圖2所示。
圖1:連接示意圖
圖2:照片示意圖
其中有幾點需要特別說明:
1.3.1 模塊的RST復位引腳是否需要連接
模塊手冊上明確說明上電后模塊自動復位,開始將RST連接到GND沒有發現問題,但在調試過程中發現,如果上一次程序跑飛,液晶模塊顯示滿屏“雪花”(注意不是亂碼),下次燒寫后無論程序對錯,屏幕基本上保持原樣,會影響到思路判斷,還以為是程序仍然沒有調試正確。估計其原因是ST7920被跑飛的程序置於某種狀態,不再接收正確的指令了。
因此,在調試過程中還是要連上此腳加上復位功能。即便是正式發布的程序,在系統無斷電機會時,為了避免潛在Bug的影響,還是加上復位控制為好。
ST7920手冊記載,RST為低電平復位,保持時間在10us以上。
1.3.2 ST7920片選引腳是否連接
如果只有一個外設使用SPI總線,可以不用將CS連接到單片機,直接將CS連接到Vcc即可,CS高電平有效。SPI總線上的設備超過一個時,就需要單片機控制CS信號了。
1.3.3 單片機SPI接口的SS腳如何處理
SPI控制寄存器SPCTL的B7位SSIG明確了SS的功能。SSIG英文全稱應該是Selected Slave Ignore(杜撰),字面意思是“忽略被選為從機的信號”,即STC8是否允許其他設備通過拉低SS腳電平把自己作為從機,SSIG=0代表允許,SSIG=1代表不允許。因此,在STC8總是作為主機的情況下,可以不用連接SS腳,軟件配置上有兩種選擇
- SSIG=1,忽略SS腳信號的控制作用。這種情況下,SS腳是否能做他用有待驗證。
- SSIG=0,配合SPCTL的B4位MSTR=1來保持主機地位。
ST7920就是被動接收信息,不會作為主機控制SPI總線,模塊也沒有提供響應的引腳,因此就ST7920而言不用連接SS腳。但是我計划SPI總線上還有其他設備有可能以主機身份存在,因此SS腳暫時懸空,程序中仍然配置SSIG=0。
1.3.4 電源電壓問題
模塊手冊明確使用電壓3.3-5.3V,實際接到5V電源時背光明亮,3V時柔和舒適,除此之外還需要調整一下PCB背板上的對比度可調電阻,否則字跡顯示不清楚。
2. STC8A8K64S4A12的SPI接口配置及操作
該芯片使用SPI接口需要4個步驟,之后就可傳輸數據了。可根據實際情況省略前兩個步驟:
- 選擇I/O口
- 選擇I/O口工作模式
- 配置SPI控制寄存器
- 中斷使能
2.1 接口配置
2.1.1 選擇I/O口
該芯片可將SPI功能腳配置到四組不同的I/O口,可以根據需要進行選擇,外設端口切換寄存器1“P_SW1”的B3和B2位SPI_S[1:0] (SPI_Select)就起到這個作用,詳情見表1和表2。
因為P7口的復用功能比較少,我先將SPI配置到P7上,即SPI_S=10。這兩位的上電復位默認值為“00”,若忽略選擇I/O口這一步,SPI的I/O口將被定位在P1的4個口上。
表1:SPI端口切換寄存器(表中第二個)
表2 SPI功能腳選擇位
2.1.2 選擇I/O口工作模式
該芯片所有I/O口都有四種工作模式:准雙向口、推挽輸出、高阻輸入和開漏輸出,可根據需要進行選擇。需要配置寄存器是P0M1、P0M0 – P7M1、P7M0,共8對分別對應P0~P7。這些端口上電復位值均為0,如果忽略該步驟,所有I/O口均工作在准雙向模式。我的方案就是省略該步驟采用默認值,也就是說SPI的四個口都工作在准雙向模式。
P0~P7(P4沒有4.5~4.7口)每個端口都有兩個端口模式寄存器,例如:P0口的B7~B0位對應的兩個模式寄存器是P0M1和P0M0的B7~B0位,這一對寄存器用來確定對應的I/O口工作在四種模式中的哪一種。PnM1.x和 PnM0.x(n=1~7)分別為:
- 00:准雙向口:灌電流20mA,拉電流270~150uA。可見准雙向口提供的驅動能力是有較大差異的,某個口為0時可容納20mA電流流入,為1時輸出電流要小約100倍(74-133倍)
- 01:推挽輸出:向上拉輸出,可達20mA,要加限流電阻
- 10:高阻輸入:電流既不能流入,也不能流出,需要配合外部電路實現0、1的功能
- 11:開漏輸出:外加上拉電阻時,即可輸入也可輸出,否則讀不到外部狀態,也對外輸不出高電平
2.1.3 配置SPI控制寄存器SPCTL(SPI Control Register)
該寄存器的配置是操作SPI總線的重頭戲,該寄存器的結構如表3所示。因為不用考慮兼容8051,SPI的所有控制位都集中到這個寄存器中。
表3 SPI三個寄存器的結構
SPCTL共8個位,可以實現SPI總線7個方面的功能控制,為便於理解,下面盡可能用通俗的語言進行描述。
2.1.3.1 [B7]SSIG(Selected Slave Ignore)
英文直譯的意思是“忽略從設備選擇信號”,芯片手冊上稱之為“SS引腳功能控制位”,但這個叫法不太容易理解,實際上就如本文1.1.3所言,其功能就是“是否允許其他設備通過拉低SS腳電平把自己作為從機”。
SSIG的兩種狀態通俗的講,就是話語權的問題,理解了這一點對“單主單從”、“互為主從”、“一主多從”的設置很關鍵:
- 0:允許其他設備占主動權,若想將本機作為從機,其他設備將本機SS腳電平拉低就可實現這個目的。
- 1:我永遠占主動權,是主是從你們說了不算,我說了才算。讓你們是從機的時候,你們就是從機,這時B4位MSTR=1,即表示我是主機,你們是從機;讓你們是主機的時候,你們才能是主機,這時B4位MSTR=0,表示我是從機。
2.1.3.2 [B6]SPEN(SPI Enable)
SPI使能控制位,0=關閉SPI功能,1=使能。
2.1.3.3 [B5]DORD(Data Order)
數據位收發時的順序,0=先高位MSB,1=先低位(LSB)。ST7920要求先高后低,因此該位應該設為0。
2.1.3.4 MSTR(Master)
MSTR:器件主/從模式選擇位,SSIG章節已經掰嗤清楚了,這里不說了,抄手冊。
設置主機模式:
- 若 SSIG=0,則 SS 管腳必須為高電平且設置 MSTR 為 1
- 若 SSIG=1,則只需要設置 MSTR 為 1(忽略 SS 管腳的電平)
設置從機模式:
- 若 SSIG=0,則 SS 管腳必須為低電平(與 MSTR 位無關)
- 若 SSIG=1,則只需要設置 MSTR 為 0(忽略 SS 管腳的電平)
2.1.3.5 [B3] CPOL(Clock Polarity,SPI時鍾極性控制)與[B2] CPHA(Clock Phase,SPI時鍾相位控制)
CPOL:SPI 時鍾極性控制。
- 0:SCLK 空閑時為低電平,SCLK 的前時鍾沿為上升沿,后時鍾沿為下降沿
- 1:SCLK 空閑時為高電平,SCLK 的前時鍾沿為下降沿,后時鍾沿為上升沿
CPHA:SPI 時鍾相位控制
- 0:數據 SS 管腳為低電平驅動第一位數據並在 SCLK 的后時鍾沿改變數據,前時鍾沿采樣數據(必 須 SSIG=0)
- 1:數據在 SCLK 的前時鍾沿驅動,后時鍾沿采樣
手冊中給出的描述很簡單,但是理解起來很是困難,有一篇帖子說的再明白不過了,摘抄了一張圖稍作修改(圖3),原文鏈接:高手帶你理解SPI中的極性CPOL和相位CPHA。
圖3:SPI時鍾極性與相位示意圖
我在這里遇到理解障礙主要有兩點,對於判斷這兩位的高低十分重要。
- 手冊中說的SCLK空閑時間指的是什么時間?
答:指的是SPI總線啟動前的時間。以ST7920為例,其時序圖如圖4所示,圖中的時間是我根據手冊數據加上去的。傳輸數據之前SCLK處於高電平狀態,即極性CPOL=1。可恨的是手冊寫的水平不高,也可能是我理解能力有限,手冊還給出了一張圖(圖5),正好擰着,好坑人。
圖4:ST7920串口時序圖
圖5:坑人的另一張圖
2. 哪里算作SCLK的開始時間?
明確開始時間,才能搞清楚哪里是第一個時鍾沿,哪里是第二個時鍾沿。搞清楚第一個問題后,這個問題就十分容易了。不難看出ST7920要求相位CPHA = 1。
2.1.3.6 SPR[1:0]
英文應該是SPI Rate,即SPI時鍾的波特率,占B1和B0兩個位。手冊給出的數值為:
- 00:SYSclk÷4
- 01:SYSclk÷8
- 10:SYSclk÷16
- 11:SYSclk÷32
由此可見,在該單片機系統時鍾固定的情況下,SPI時鍾的波特率只有4種選擇,分別是系統時鍾的4、8、16、32分頻。如果想使用其他頻率,就必須調整系統時鍾頻率了。
我選擇的系統時鍾頻率是22.1184MHz,應該選擇哪個分頻還需要看ST7920的要求,ST7920在兩種電壓下對時鍾周期的要求是不同的,見表4和表5。可見在工作電壓越低,ST7920的工作速度越慢,在2.7V條件下的時鍾周期Tscyc最小為600ns,在4.5V時最小為400ns。STC8A8K64S4A12的工作電壓我選擇的是3V,因此按照2.7V的600ns來計算肯定可以滿足ST7920的要求。
1秒÷600納秒=1.67MHz,這是ST7920要求的頻率上限。
有了這個數就好辦了,一一計算22.1184MHz的四種分頻,不難得出選擇16分頻為佳,22.1184 MHz÷16 = 1.3824MHz。因此SPR[1:0]的這兩位選擇10。
表4:ST7920在4.5V條件下的時間要求
表5:ST7920在2.7V條件下的時間要求
2.2 SPI中斷的使能操作
使能操作要簡單的多,SPI的使能位在IE2的B1位------ESPI,見表6。先將ESPI=1,再打開總中斷EA=1,就完成了SPI的使能操作。
表6:中斷使能寄存器 IE2
2.3 SPI傳輸數據操作
使用SPI傳輸數據涉及兩個寄存器,就是表1中的狀態寄存器SPSTAT(SPI Status Register)和數據寄存器SPDAT(SPI Data Register)。
這里只有兩點需要說明:
1. 按說可以利用SPI中斷自動實現SPI的數據傳輸,可我反復嘗試最終失敗了,還是選擇了常規的發送數據后,等待中斷產生,手工清除狀態寄存器的方式。有可能是STC8手冊《A.2 關於使用CLR指令關閉EA的重要說明》提到“使用4級流水線”的原因。
2. 狀態寄存器標識位的清零需要寫1(SPSTAT = 0xc0),不能使用常規的清零方法(SPSTAT = 0)。
3. ST7920的操作
SPI串口設置好了,就可以根據ST7920手冊要求順利操作了,網上的例子也多。
這里需要說明的是:
1、 選擇串口方式,需要將背板上的“S”點,用焊錫短接,見圖6。這一點根據模塊不同可能有不同的方式。
圖6 模塊PCB背板局部
2 、網上的例子中每次操作ST7920配的延時時間各不相同,我嘗試了一下,各種操作只要保證手冊要求的72us即可(清屏操作需等待1.6ms)。這有可能與采用的顯示控制芯片有關。
3 、串口方式向ST7920發送命令或數據的步驟
發送每個命令或數據都要發送三個字節的信息:
- 第一個字節:啟動字節。若后面跟的是命令,啟動字節=0xf8;后面跟的是數據啟動字節=0xfa。
- 第二、三個字節:要發送的命令或數據。原本命令或數據都是一個字節8位的,發送時需要拆成兩次發送,第二個字節的高4位是命令或數據字節的高4位,第三個字節的高4位是命令或數據字節的低4位,空出來的位均為0。
4 、關於DDRAM地址與屏幕坐標的關系
這一點手冊中說的也不太清楚,用表格表示一下,見表7。表中的數字均為16進制,例如80表示0x80;每個地址應該是個16位數,以0x80為例說明,高8位表中用80.H表示,低8位表中用80.L表示。
表7 屏幕坐標和DDRAM地址的對應關系
4 主要程序
因為我使用Visual Studio 2019作為編輯器,所以使用了更多的VS習慣,以便更多的利用VS的自動提示功能。如何在VS中編輯,在Keil中調試請見:如何發揮Visual Studio 2019強大的編輯功能輕松編輯Keil項目。
1 //SPI配置 2 #include <STC8.H> 3 #include "System.h" //主要定義了unsigned char為u8等等 4 5 /// <summary> 6 /// SPI單主多從模式的主機初始化 7 /// </summary> 8 /// <param name="dataOrder">傳輸字節哪頭優先</param> 9 /// <param name="clockPolarity">時鍾極性控制</param> 10 /// <param name="clockPhase">時鍾相位控制</param> 11 /// <param name="spiSpeed">時鍾頻率</param> 12 /// <param name="pinSelect">功能腳組別選擇</param> 13 /// <returns></returns> 14 void STC8_SPI_One_Master_Many_Slave_Init(u8 dataOrder, u8 clockPolarity, u8 clockPhase, u8 spiSpeed, u8 pinSelect ) 15 { 16 // 第一步:選擇輸出腳 17 P_SW1 &= 0xf3; // P_SW1同時還負責着串口1、CCP的管腳選擇,注意不能覆蓋 18 P_SW1 |= pinSelect; 19 //第二步:配置IO腳工作模式為准雙向口/弱上拉,即處於00 20 //第三步:控制寄存器配置 21 SPCTL = 0x50; 22 SPCTL |= (dataOrder | clockPolarity | clockPhase | spiSpeed); 23 SPSTAT = 0xc0; //寫1清零 24 IE2 |= ESPI; //使能SPI中斷 25 EA = 1; 26 }
上邊程序片段用的到幾個宏在包含文件中:

#include "System.h" #define STC8_SPI_PIN_P12_P13_P14_P15 0x00 // SPI輸出腳按順序分別是SS/MOSI/MISO/SCLK #define STC8_SPI_PIN_P22_P23_P24_P25 0x04 // SPI輸出腳按順序分別是SS/MOSI/MISO/SCLK #define STC8_SPI_PIN_P74_P75_P76_P77 0x08 // SPI輸出腳按順序分別是SS/MOSI/MISO/SCLK #define STC8_SPI_PIN_P35_P34_P33_P32 0x0c // SPI輸出腳按順序分別是SS/MOSI/MISO/SCLK #define STC8_SPI_DATA_ORDER_MSB_FIRST 0x00 // SPI傳送字節高位在先,0000 0000 #define STC8_SPI_DATA_ORDER_LSB_FIRST 0x20 // SPI傳送字節低位在先,0010 0000 #define STC8_SPI_POLARITY_IDLE_LOW 0x00 // SPI時鍾空閑時低電平,0000 0000 #define STC8_SPI_POLARITY_IDLE_HIGH 0x08 // SPI時鍾空閑時高電平,0000 1000 #define STC8_SPI_PHASE_SAMPLING_FIRST_EDGE 0x00 // 在第一個時鍾沿采樣 ,0000 0000 #define STC8_SPI_PHASE_SAMPLING_SECOND_EDGE 0x04 // 在第二個時鍾沿采樣,0000 0100 #define STC8_SPI_SPEED_SYSCLOCK_DIVIDE_4 0x00 // SCLK頻率為SYSclk 4分頻,0000 0000 #define STC8_SPI_SPEED_SYSCLOCK_DIVIDE_8 0x01 // SCLK頻率為SYSclk 8分頻,0000 0001 #define STC8_SPI_SPEED_SYSCLOCK_DIVIDE_16 0x02 // SCLK頻率為SYSclk 16分頻,0000 0010 #define STC8_SPI_SPEED_SYSCLOCK_DIVIDE_32 0x03 // SCLK頻率為SYSclk 32分頻,0000 0011 /// <summary> /// SPI單主多從模式的主機初始化 /// </summary> /// <param name="dataOrder">傳輸字節哪頭優先</param> /// <param name="clockPolarity">時鍾極性控制</param> /// <param name="clockPhase">時鍾相位控制</param> /// <param name="spiSpeed">時鍾頻率</param> /// <param name="pinSelect">功能腳組別選擇</param> /// <returns></returns> void STC8_SPI_One_Master_Many_Slave_Init(u8 dataOrder, u8 clockPolarity, u8 clockPhase, u8 spiSpeed, u8 pinSelect);
ST7920的主要部分:

1 #include <STC8.H> 2 #include "System.h" 3 #include "Common.h" //主要定義了延時函數 4 5 #define COMMAND_CODE 0xf8 // 命令首字節 6 #define DATA_CODE 0xfa //數據首字節 7 8 #define CSEN 1 //ST7920片選有效為高電平 9 #define CSDS 0 10 11 #define DELAY_TIME 72 // 除Clear外所有命令都需要72us延時,專門定義宏,需要時好調整 12 13 sbit rst = P7 ^ 2; //12864復位信號,復位低電平有效,持續時間10us 14 sbit cs = P7 ^ 3; //12864片選定義在P7.3 15 16 /// <summary> 17 /// ST7920硬復位 18 /// </summary> 19 /// <returns></returns> 20 void ST7920_Reset() 21 { 22 rst = 0; 23 DelayUs_1T_221184(10); 24 rst = 1; 25 DelayMs_1T_221184(40); //復位40毫秒后系統可用 26 } 27 28 void wrt_byte(u8 byte) 29 { 30 cs = CSEN; 31 IE2 &= 0xfd; //關SPI中斷 32 SPDAT = byte; 33 while (!(SPSTAT & 0x80)); 34 SPSTAT = 0xc0; //寫1清零 35 IE2 |= ESPI; //STC8.H定義ESPI = 0x02 36 cs = CSDS; 37 } 38 39 /// <summary> 40 /// 向ST7920發送命令字節 41 /// </summary> 42 /// <param name="cmd">命令字節</param> 43 /// <returns></returns> 44 void ST7920_SendCommand(u8 cmd) 45 { 46 wrt_byte(COMMAND_CODE);//命令首字節 47 wrt_byte(cmd & 0xf0);//命令字節高4位 48 wrt_byte(cmd << 4); //命令字節低4位 49 DelayUs_1T_221184(DELAY_TIME);//7920要求72us 50 } 51 52 /// <summary> 53 /// 向ST7920發送數據字節 54 /// </summary> 55 /// <param name="cmd">數據字節</param> 56 /// <returns></returns> 57 void ST7920_SendData(u8 data_) 58 { 59 wrt_byte(DATA_CODE);//數據首字節 60 wrt_byte(data_ & 0xf0); //數據字節高4位 61 wrt_byte(data_ << 4); //數據字節低4位 62 DelayUs_1T_221184(DELAY_TIME);//7920要求72us 63 } 64 65 66 /// <summary> 67 /// 功能同ST7920_SetDDRAMAddrss(),只是把類似於0x80的地址轉變成行和列,基本指令集 68 /// </summary> 69 /// <param name="row">行數(0-3)</param> 70 /// <param name="col">列數(0-15)</param> 71 /// <returns></returns> 72 void ST7920_SetDisplayPosition(u8 row, u8 col) 73 { 74 u8 address; 75 if (row == 0x00) address = 0x80; 76 if (row == 0x01) address = 0x90; 77 if (row == 0x02) address = 0x88; 78 if (row == 0x03) address = 0x98; 79 address += col; 80 ST7920_SendCommand(address); 81 } 82 83 /// <summary> 84 /// 寫16×16點陣全寬字形(CGRAM:0000H、0002H、0004H、0006H;CGROM:A1A0H-F7FFH(GB)或A140H-D75FH(BIG5) ) 85 /// </summary> 86 /// <param name="hByte">高8位字形編碼</param> 87 /// <param name="lByte">低8位字形編碼</param> 88 /// <returns></returns> 89 void ST7920_DisplayChar_16_16(u8 hByte, u8 lByte) 90 { 91 ST7920_SendData(hByte); 92 ST7920_SendData(lByte); 93 } 94 95 void ST7920_DisplayString_16_16(u8 * str, u8 lenth) 96 { 97 u8 i = 0; 98 for (; i < lenth; i += 2) 99 { 100 ST7920_SendData(str[i]); 101 ST7920_SendData(str[i + 1]); 102 } 103 }
上面代碼用的的包含文件:

1 #include "System.h" 2 #include "Common.h" 3 4 /// <summary> 5 /// ST7920硬復位 6 /// </summary> 7 /// <returns></returns> 8 void ST7920_Reset(); 9 10 /// <summary> 11 /// 發送命令 12 /// </summary> 13 /// <param name="data_">要發送的命令</param> 14 /// <returns></returns> 15 void ST7920_SendCommand(u8 cmd); 16 17 /// <summary> 18 /// 發送數據到內部 RAM ( DDRAM/CGRAM/IRAM/GRAM) 19 /// </summary> 20 /// <param name="data_">要發送的數據</param> 21 /// <returns></returns> 22 void ST7920_SendData(u8 data_); 23 24 //基本指令集 25 #define ST7920_Clear() do{ST7920_SendCommand(0x01);DelayMs_1T_221184(2);}while(0) // 清屏,7920要求延時1.6ms(基本指令集) 26 #define ST7920_HOME 0x02 // 地址歸位,基本指令集,DDRAM的地址計數器AC到00H 27 #define ST7920_DISPLAY_NORMAL 0x0c // 整體顯示開,游標關,反白關(基本指令集),總功能:0000 1D(1/0,總體顯示開/關)C(1/0,游標開/關)B(1/0,游標位置反白開/關) 28 #define ST7920_ENTRY_NORMAL 0x06 // 游標及顯示右移一次(基本指令集) 29 #define ST7920_XX 0x10 // 不理解,待后續試驗觀察 30 #define ST7920_BASIC_INSTRUCTION 0x30 // 選擇8位數據接口的基本指令集 31 #define ST7920_EXTENDED_INSTRUCTION 0x34 // 選擇8位數據接口的擴展指令集 32 #define ST7920_SetCGRAMAddress(address) do{ST7920_SendCommand(0x40+address);}while(0) //設定CGRAM地址 33 #define ST7920_SetDDRAMAddress(address) do{ST7920_SendCommand(address);}while(0) //將顯存DDRAM地址設置到地址計數器AC,基本指令集。范圍:第1行:80H-8FH,第2行:90H-9FH,第3行:A0H-AFH,第4行:B0H-BFH 34 #define ST7920_DisplayChar_16_8(char_) do{ST7920_SendData(char_);}while(0) //寫16×8半寬字形(HCGROM:02H-7FH) 35 36 /// <summary> 37 /// 功能同ST7920_Set_DDRAM_Addrss(),只是把類似於0x80的地址轉變成行和列,基本指令集 38 /// </summary> 39 /// <param name="row">行數(0-3)</param> 40 /// <param name="col">列數(0-15)</param> 41 /// <returns></returns> 42 void ST7920_SetDisplayPosition(u8 row, u8 col); 43 44 /// <summary> 45 /// 寫16×16點陣全寬字形(CGRAM:0000H、0002H、0004H、0006H;CGROM:A1A0H-F7FFH(GB)或A140H-D75FH(BIG5) ) 46 /// </summary> 47 /// <param name="hByte">高8位字形編碼</param> 48 /// <param name="lByte">低8位字形編碼</param> 49 /// <returns></returns> 50 void ST7920_DisplayChar_16_16(u8 hByte, u8 lByte); 51 52 /// <summary> 53 /// 寫16×16點陣全寬字形字符串(CGRAM:0000H、0002H、0004H、0006H;CGROM:A1A0H-F7FFH(GB)或A140H-D75FH(BIG5) ) 54 /// </summary> 55 /// <param name="str">字符串指針</param> 56 /// <param name="lenth">字符串長度(一個全寬字形長度為2)</param> 57 /// <returns></returns> 58 void ST7920_DisplayString_16_16(u8 *str, u8 lenth);
主程序:

1 #include "system.h" 2 #include "STC8_SPI.h" 3 #include "st7920.h" 4 #include "Common.h" 5 6 /// <summary> 7 /// ST7920初始化 8 /// </summary> 9 /// <returns></returns> 10 void ST7920_Init() 11 { 12 DelayMs_1T_221184(50);//該顯示模塊要求上電后延遲40ms 13 ST7920_SendCommand(ST7920_BASIC_INSTRUCTION); //基本指令集 14 ST7920_SendCommand(ST7920_DISPLAY_NORMAL);//顯示開,游標關,反白關 15 ST7920_Clear(); // 用空格清屏 16 ST7920_SendCommand(ST7920_ENTRY_NORMAL); // 讀寫后游標及顯示右移 17 } 18 19 unsigned char str[] = "配置接口"; 20 21 void main() 22 { 23 STC8_SPI_One_Master_Many_Slave_Init( //配置ST7920SPI接口 24 STC8_SPI_DATA_ORDER_MSB_FIRST, 25 STC8_SPI_POLARITY_IDLE_HIGH, 26 STC8_SPI_PHASE_SAMPLING_SECOND_EDGE, 27 STC8_SPI_SPEED_SYSCLOCK_DIVIDE_16, 28 STC8_SPI_PIN_P74_P75_P76_P77); 29 ST7920_Init(); 30 ST7920_SetDisplayPosition(0, 0); 31 ST7920_DisplayString_16_16("要以熱愛祖國為榮", 16); 32 ST7920_SetDisplayPosition(1, 0); 33 ST7920_DisplayString_16_16("祖國就是我們母親", 16); 34 ST7920_SetDisplayPosition(2, 0); 35 ST7920_DisplayString_16_16("無私奉獻報效祖國", 16); 36 ST7920_SetDisplayPosition(3, 0); 37 ST7920_DisplayString_16_16("這是每個公民責任", 16); 38 while (1); 39 } 40 //SPI中斷 41 void SPI_Interrup() interrupt 9 42 { 43 SPSTAT = 0xc0; //寫1清零 44 }
View Code
5 顯示效果