STC8A8K64S4A12通過SPI接口操作基於ST7920的LCD12864液晶模塊


文章地址: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. STC8A8K64S4A12SPI接口配置及操作

  該芯片使用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控制寄存器SPCTLSPI Control Register

  該寄存器的配置是操作SPI總線的重頭戲,該寄存器的結構如表3所示。因為不用考慮兼容8051,SPI的所有控制位都集中到這個寄存器中。

   表3 SPI三個寄存器的結構

  SPCTL共8個位,可以實現SPI總線7個方面的功能控制,為便於理解,下面盡可能用通俗的語言進行描述。

2.1.3.1 [B7]SSIGSelected Slave Ignore

  英文直譯的意思是“忽略從設備選擇信號”,芯片手冊上稱之為“SS引腳功能控制位”,但這個叫法不太容易理解,實際上就如本文1.1.3所言,其功能就是“是否允許其他設備通過拉低SS腳電平把自己作為從機”。

  SSIG的兩種狀態通俗的講,就是話語權的問題,理解了這一點對“單主單從”、“互為主從”、“一主多從”的設置很關鍵:

  • 0:允許其他設備占主動權,若想將本機作為從機,其他設備將本機SS腳電平拉低就可實現這個目的。
  • 1:我永遠占主動權,是主是從你們說了不算,我說了才算。讓你們是從機的時候,你們就是從機,這時B4位MSTR=1,即表示我是主機,你們是從機;讓你們是主機的時候,你們才能是主機,這時B4位MSTR=0,表示我是從機。

 2.1.3.2 [B6]SPENSPI Enable

  SPI使能控制位,0=關閉SPI功能,1=使能。

2.1.3.3 [B5]DORDData Order

  數據位收發時的順序,0=先高位MSB,1=先低位(LSB)。ST7920要求先高后低,因此該位應該設為0。

2.1.3.4 MSTRMaster

  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] CPOLClock PolaritySPI時鍾極性控制)與[B2] CPHAClock PhaseSPI時鍾相位控制)

  CPOL:SPI 時鍾極性控制。

  • 0:SCLK 空閑時為低電平,SCLK 的前時鍾沿為上升沿,后時鍾沿為下降沿
  • 1:SCLK 空閑時為高電平,SCLK 的前時鍾沿為下降沿,后時鍾沿為上升沿

  CPHA:SPI 時鍾相位控制

  • 0:數據 SS 管腳為低電平驅動第一位數據並在 SCLK 的后時鍾沿改變數據,前時鍾沿采樣數據(必 須 SSIG=0)
  • 1:數據在 SCLK 的前時鍾沿驅動,后時鍾沿采樣

  手冊中給出的描述很簡單,但是理解起來很是困難,有一篇帖子說的再明白不過了,摘抄了一張圖稍作修改(圖3),原文鏈接:高手帶你理解SPI中的極性CPOL和相位CPHA

   圖3:SPI時鍾極性與相位示意圖

  我在這里遇到理解障礙主要有兩點,對於判斷這兩位的高低十分重要。

  1. 手冊中說的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時鍾的波特率,占B1B0兩個位。手冊給出的數值為:

  • 00:SYSclk÷4
  • 01:SYSclk÷8
  • 10SYSclk÷16
  • 11SYSclk÷32

   由此可見,在該單片機系統時鍾固定的情況下,SPI時鍾的波特率只有4種選擇,分別是系統時鍾的481632分頻。如果想使用其他頻率,就必須調整系統時鍾頻率了。

   我選擇的系統時鍾頻率是22.1184MHz,應該選擇哪個分頻還需要看ST7920的要求,ST7920在兩種電壓下對時鍾周期的要求是不同的,見表4和表5。可見在工作電壓越低,ST7920的工作速度越慢,在2.7V條件下的時鍾周期Tscyc最小為600ns,在4.5V時最小為400nsSTC8A8K64S4A12的工作電壓我選擇的是3V,因此按照2.7V600ns來計算肯定可以滿足ST7920的要求。

1秒÷600納秒=1.67MHz,這是ST7920要求的頻率上限。

   有了這個數就好辦了,一一計算22.1184MHz的四種分頻,不難得出選擇16分頻為佳,22.1184 MHz÷16 = 1.3824MHz。因此SPR[1:0]的這兩位選擇10

 4ST79204.5V條件下的時間要求

 

 表5ST79202.7V條件下的時間要求

2.2 SPI中斷的使能操作

   使能操作要簡單的多,SPI的使能位在IE2B1------ESPI,見表6。先將ESPI=1,再打開總中斷EA=1,就完成了SPI的使能操作。

 

   6:中斷使能寄存器 IE2

2.3 SPI傳輸數據操作

   使用SPI傳輸數據涉及兩個寄存器,就是表1中的狀態寄存器SPSTATSPI Status Register)和數據寄存器SPDATSPI Data Register)。

   這里只有兩點需要說明:

   1.       按說可以利用SPI中斷自動實現SPI的數據傳輸,可我反復嘗試最終失敗了,還是選擇了常規的發送數據后,等待中斷產生,手工清除狀態寄存器的方式。有可能是STC8手冊《A.2 關於使用CLR指令關閉EA的重要說明》提到“使用4級流水線”的原因。

   2.       狀態寄存器標識位的清零需要寫1SPSTAT = 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);
View Code

  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 }
View Code

  上面代碼用的的包含文件:

 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);
View Code

  主程序:

 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 顯示效果

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM