1. 程式人生 > >【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗七:PS/2模組① — 鍵盤

【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗七:PS/2模組① — 鍵盤

實驗七:PS/2模組① — 鍵盤

實驗七依然也是熟爛的PS/2鍵盤。相較《建模篇》的PS/2鍵盤實驗,實驗七實除了實現基本的驅動以外,我們還要深入解PS/2時序,還有PS/2鍵盤的行為。不過,為了節省珍貴的頁數,怒筆者不再重複有關PS/2的基礎內容,那些不曉得的讀者請複習《建模篇》或者自行谷歌一下。

市場上常見的鍵盤都是應用第二套掃描碼,各種掃描碼如圖7.2所示。《建模篇》之際,筆者也只是擦邊一下PS/2鍵盤,簡單讀取單位元組通碼與斷碼而已。所謂單位元組通碼,就是有效的按下內容,例如 <A> 鍵被按下的時候會輸出 1C。所謂單位元組斷碼,就是有效的釋放內容,例如 <A> 鍵被釋放的時候會輸出 F0 1C。

除了單位元組的通碼以外,PS/2鍵盤也有雙位元組通碼與斷碼。所謂雙位元組通碼,例如 <R CTRL>鍵被按下時候會輸出 E0 14;反之,所謂雙位元組斷碼,例如 <R CTRL> 鍵被釋放時候會輸出 E0 F0 14。不管是單位元組還是雙位元組,斷碼都包含F0。

除了上述的要求以外,筆者還要實現雙組合鍵,例如 <Ctrl> + <A>。不僅而已,筆者也要實現三組合鍵,例如 <Ctrl> + <Alt > + <A>。常識上,這些任性的要求都是軟體的工作,然而這種認識也僅侷限小氣的腦袋而已。換做筆者,筆者就算霸王硬上弓,筆者也要使用Verilog實現這些任性的要求。

未進入實驗之前,筆者需要強調一下!Verilog究竟如何驅動PS/2裝置,然後又如何實現軟體的工作,這一切Verilog自有方法。不管C語言還有微控制器這對活寶,驅動PS/2裝置再怎麼神,它們也沒有資格在旁指指點點。讀者千萬也別嘗試用借用它們的思路去思考Verilog,否則後果只有撞牆而已。

clip_image002

圖7.1 PS/2鍵盤傳送資料(主機視角)。

PS/2傳輸協議與一般的傳輸協議一樣,除了主從之分之餘,它也有“讀寫”兩個訪問的方向。除非有特殊的需要,不然從機(FPGA)是不會訪問PS/2鍵盤的內部。換之,從機只要不停從PS/2鍵盤哪裡讀取資料即可 ... 換句話說,驅動PS/2鍵盤僅有讀資料這一環而已,然而PS/2鍵盤是主機,FPGA是從機。(主機的定義是時鐘訊號的擁有者)

不管是何種傳輸協議,只要協議當中存有時鐘訊號,那麼“什麼時鐘沿,怎樣對待資料”這個鐵則是不會改變的。如圖7.1所示,那是PS/2鍵盤傳送資料的時序圖,亦即上升沿設定資料(輸出資料)。根據主機視角,除了開始位以外,PS/2鍵盤一共利用10個上升沿輸出10位資料。

clip_image004

圖7.2 第二套鍵盤的掃描碼。

clip_image006

圖7.3 PS/2鍵盤傳送資料,FPGA讀取資料(從機視角)。

PS/2傳輸資料一般都是一幀一幀互相往來,一幀有11位資料。Bit 0位為拉低的開始位,Bit 1~8 是由低自高的資料位,Bit 9為校驗位,Bit 10為拉高的結束位。根據從機視角,如圖7.3所示,PS/2鍵盤在傳送資料的時候,FPGA是下降沿鎖存資料(讀取資料)。PS2_CLK訊號一共產生了11個下降沿,FPGA也根據這11次下降沿鎖存11位資料。

clip_image008

圖7.4 檢測PS2_CLK的電平變化。

為了察覺下降沿,我們可以借用F2~F1的力量,對此Verilog可以這樣表示:

reg F2,F1;
always @ ( posedge CLOCK )
    { F2,F1 } <= { F1,KEY }; 

然後下降沿宣告為即時:

wire isH2L = ( F2 == 1 && F1 == 0 );

那麼,從機接收1幀11位資料的操作可以這樣描述,結果如程式碼7.1所示:

1.        case( i )
2.    
3.            0:
4.            if(isH2L) i <= i + 1’b1; 
5.            1,2,3,4,5,6,7,8:
6.            if(isH2L) D1[i-1] <= PS2_DAT; i <= i + 1’b1; end
7.            9:
8.            if(isH2L) i <= i + 1’b1; 
9.            10:
10.            if(isH2L) i <= 4‘d0;
11.    
12.        endcase

程式碼7.1

不過,為了方便控制程式碼7.1,筆者設法將程式碼7.1設定為偽函式,結果如程式碼7.2所示:

1.       parameter RDFUNC = 4’d4;
2.        ......
3.        case( i )
4.            ......
5.            /*********************/
6.            4:
7.            if(isH2L) i <= i + 1’b1; 
8.            5,6,7,8,9,10,11,12:
9.            if(isH2L) D1[i-5] <= PS2_DAT; i <= i + 1’b1; end
10.            13:
11.            if(isH2L) i <= i + 1’b1; 
12.            14:
13.            if(isH2L) i <= Go;
14.    
15.        endcase

程式碼7.2

理解這些以後,我們就要開始認識PS/2鍵盤的按鍵行為了。

clip_image010

圖7.5 PS/2鍵盤,按一下又釋放。

假設筆者輕按一下<A>然後又釋放,如圖7.5所示,PS/2鍵盤先會發送一幀8’h1C的通碼,然後又傳送兩幀8’hF0 8’h1C的斷碼,這是PS/2鍵盤最常見的按鍵行為。

clip_image012

圖7.6 PS/2鍵盤,長按又釋放。

如果筆者長按 <A> 鍵不放,如圖7.6所示,PS/2鍵盤會不停傳送通碼,直至釋放才傳送斷碼。至於長按期間,通碼的傳送間隔大約是100ms,亦即1秒內傳送10個通碼。

clip_image014

圖7.7 PS/2鍵盤,有效通碼。

一般而言,我們都會選擇通碼放棄斷碼,為了表示一次性,而且也是有效性的通碼。每當一幀通碼完成接收,isDone就會產生一個高脈衝,以示一次性而且有效的通碼已經接收完畢。

clip_image016

圖7.8 實驗七的建模圖。

如圖7.8所示,那是實驗七的建模圖,其中名為 ps2_demo的組合模組,內容包含實驗六的 smg_basemod 以外,該組合模組也包含 ps2_funcmod。PS/2功能模組接收來PS/2鍵盤傳送過來的資料,然後再經由oData驅動smg_basemod的iData,最後並將通碼顯示在數碼管上。

ps2_funcmod.v

clip_image018

圖7.9 PS/2功能模組。

圖7.9是PS/2功能模組的建模圖,左方是PS2_CLK與PS2_DAT頂層訊號的輸入,右方則是1位oTrig與8位oData。具體內容,讓我們來瞧瞧程式碼:

1.    module ps2_funcmod
2.    (
3.         input CLOCK, RESET,
4.         input PS2_CLK, PS2_DAT,
5.         output oTrig,
6.         output [7:0]oData
7.    );
8.         parameter BREAK = 8'hF0;
9.         parameter FF_Read = 5'd4;

以上內容為相關的出入端宣告以及常量宣告。第8行是斷碼的常量宣告(第一幀),第9行則是偽函式的入口。

10.     
11.         /******************/ // sub
12.    
13.        reg F2,F1;
14.         
15.        always @ ( posedge CLOCK or negedge RESET )
16.             if( !RESET )
17.                  { F2,F1 } <= 2'b11;
18.              else
19.                  { F2, F1 } <= { F1, PS2_CLK };
20.    
21.         /******************/ // core
22.         
23.         wire isH2L = ( F2 == 1'b1 && F1 == 1'b0 );
24.         reg [7:0]D1;
25.         reg [4:0]i,Go;
26.         reg isDone;
27.         
28.         always @ ( posedge CLOCK or negedge RESET )
29.             if( !RESET )
30.                  begin
31.                         D1<= 8'd0;
32.                         i <= 5'd0;
33.                         Go <= 5'd0;
34.                         isDone <= 1'b0;
35.                    end
36.               else

以上內容是周邊操作以及相關暫存器宣告,還有它們的復位操作。周邊操作主要用來檢測PS2_CLK的電平變化。第23行是下降沿的即時宣告。第24~26行是相關的暫存器宣告,第30~34行則是這些暫存器的復位操作。

37.                    case( i )
38.                     
39.                          0:
40.                          begin i <= FF_Read; Go <= i + 1'b1; end
41.                      
42.                          1:
43.                          if( D1 == BREAK ) begin i <= FF_Read; Go <= 5'd0; end
44.                          else i <= i + 1'b1;
45.                          
46.                          2:
47.                          begin isDone <= 1'b1; i <= i + 1'b1; end
48.                          
49.                          3:
50.                          begin isDone <= 1'b0; i <= 5'd0; end
51.                          
52.                          /*************/ // PS2 read function
53.                          
54.                          4:  // Start bit
55.                          if( isH2L ) i <= i + 1'b1; 
56.                          
57.                          5,6,7,8,9,10,11,12:  // Data byte
58.                          if( isH2L ) begin D1[ i-5 ] <= PS2_DAT; i <= i + 1'b1; end
59.                          
60.                          13: // Parity bit
61.                          if( isH2L ) i <= i + 1'b1;
62.                          
63.                          14: // Stop bit
64.                          if( isH2L ) i <= Go;
65.    
66.                     endcase

以上內容為核心操作。其中步驟4~14(第54~64行)是讀取1幀資料的偽函式,入口地址是4。步驟0~3則是主要操作,過程如下:

步驟0,進入偽函式準備讀取第一幀資料。讀完第一幀資料以後便返回步驟1。

步驟1,判斷第一幀資料是否為斷碼?是,進入偽函式,完整第二幀資料的讀取,然後返回步驟指向為0。否,繼續步驟。

步驟2~3,產生完成的觸發訊號,然後返回步驟0。

67.                     
68.        /************************************/
69.         
70.         assign oTrig = isDone;
71.         assign oData = D1;
72.         
73.         /*************************************/
74.      
75.    endmodule

以上內容為輸出驅動的宣告。

ps2_demo.v

組合模組 ps2_demo的聯絡部署請複習圖7.8。

1.    module ps2_demo
2.    (
3.         input CLOCK, RESET,
4.         input PS2_CLK, PS2_DAT,
5.         output [7:0]DIG,
6.         output [5:0]SEL
7.    );
8.    
9.         wire [7:0]DataU1;
10.    
11.         ps2_funcmod U1
12.         (
13.             .CLOCK( CLOCK ),
14.              .RESET( RESET ),
15.              .PS2_CLK( PS2_CLK ), // < top
16.              .PS2_DAT( PS2_DAT ), // < top
17.              .oData( DataU1 ),  // > U2
18.              .oTrig()
19.         );
20.         
21.       smg_basemod U2
22.        (
23.            .CLOCK( CLOCK ),
24.            .RESET( RESET ),
25.            .DIG( DIG ),  // > top
26.            .SEL( SEL ),  // > top
27.            .iData( { 16'h0000, DataU1 } ) // < U1
28.        );
29.                 
30.    endmodule

上述程式碼沒有什麼特別,除了第18行,無視觸發訊號的輸出以外,還有第27行其 16’h0000 則表示數碼管的前四位皆為0,後兩位則是通碼。編譯完後便下載程式。

如果筆者按下 <A> 鍵,數碼管便會顯示1C;如果筆者釋放 <A> 鍵,數碼管也是顯示1C,期間也會發生一絲的閃耀。由於ps2_funcmod的暫存空間D直切驅動oData,所以數碼管事實反映ps2_funcmod的讀取狀況。從演示上來看的確如此,不過在時序身上,唯有通碼讀取成功以後,才會產生觸發訊號。

細節一:主操作與偽函式的距離

1.    case( i )
2.                     
3.        0:
4.        begin i <= FF_Read; Go <= i + 1'b1; end      
5.        1:
6.        if( D1 == BREAK ) begin i <= FF_Read; Go <= 5'd0; end
7.        else i <= i + 1'b1;      
8.        2:
9.        begin isDone <= 1'b1; i <= i + 1'b1; end  
10.        3:
11.        begin isDone <= 1'b0; i <= 5'd0; end
12.        /*************/ // PS2 read function 
13.        4:  // Start bit
14.        if( isH2L ) i <= i + 1'b1; 
15.        5,6,7,8,9,10,11,12:  // Data byte
16.        if( isH2L ) begin D1[ i-5 ] <= PS2_DAT; i <= i + 1'b1; end
17.        13: // Parity bit
18.        if( isH2L ) i <= i + 1'b1;                  
19.        14: // Stop bit
20.        if( isH2L ) i <= Go;
21.    
22.    endcase

程式碼7.3

如程式碼7.3所示,步驟0~3是主操作,步驟4~14則是偽函式,期間主操作的下任步驟直接連線偽函式的入口。一般而言,如果模組的核心操作是小功能的話,這樣做倒沒有什麼問題。反之,如果遇上覆雜功能的核心操作,主操作與偽函式之間必須隔空一段距離。根據筆者的習慣,預設下都會設為16或者32,不過也有例外的情況。

23.    case( i )
24.                     
25.        0:
26.        begin i <= FF_Read; Go <= i + 1'b1; end      
27.        1:
28.        if( D1 == BREAK ) begin i <= FF_Read; Go <= 5'd0; end
29.        else i <= i + 1'b1;      
30.        2:
31.        begin isDone <= 1'b1; i <= i + 1'b1; end  
32.        3:
33.        begin isDone <= 1'b0; i <= 5'd0; end
34.        /*************/ // PS2 read function 
35.        16:  // Start bit
36.        if( isH2L ) i <= i + 1'b1; 
37.        17,18,19,20,21,22,23,24:  // Data byte
38.        if( isH2L ) begin D1[ i-5 ] <= PS2_DAT; i <= i + 1'b1; end
39.        25: // Parity bit
40.        if( isH2L ) i <= i + 1'b1;                  
41.        26: // Stop bit
42.        if( isH2L ) i <= Go;
43.    
44.    endcase

程式碼7.4

如程式碼7.4所示,偽函式的入口地址已經設為16,為此主操作與偽函式之間有16個步驟的距離。如此一來,主操作擁有更多的步驟空間。

細節二:完整的個體模組

clip_image020

圖7.10 PS/2鍵盤功能模組。

圖7.10是PS/2鍵盤功能模組,內容基本上與PS/2功能模組一模一樣,至於區別就是穿上其它馬甲而已,所以怒筆者不再重複貼上了。

相關推薦

黑金原創教程FPGA那些事兒-驅動I 實驗流水燈模組

實驗一:流水燈模組 對於發展商而言,動土儀式無疑是最重要的任務。為此,流水燈實驗作為低階建模II的動土儀式再適合不過了。廢話少說,我們還是開始實驗吧。 圖1.1 實驗一建模圖。 如圖1.1 所示,實驗一有名為 led_funcmod的功能模組。如果無視環境訊號(時鐘訊號還有復位訊號),該功能模組只有

黑金原創教程FPGA那些事兒-驅動I 連載導讀

前言: 無數晝夜的來回輪替以後,這本《驅動篇I》終於編輯完畢了,筆者真的感動到連鼻涕也流下來。所謂驅動就是認識硬體,還有前期建模。雖然《驅動篇I》的硬體都是我們熟悉的老友記,例如UART,VGA等,但是《驅動篇I》貴就貴在建模技巧的昇華,亦即低階建模II。 話說低階建模II,讀過《建模篇》的朋友多少也會面

黑金原創教程FPGA那些事兒-驅動I 實驗按鍵模組② — 點選與長點選

實驗三:按鍵模組② — 點選與長點選 實驗二我們學過按鍵功能模組的基礎內容,其中我們知道按鍵功能模組有如下操作: l 電平變化檢測; l 過濾抖動; l 產生有效按鍵。 實驗三我們也會z執行同樣的事情,不過卻是產生不一樣的有效按鍵: l 按下有效(點選); l 長按下有效(長點選)。 圖3

黑金原創教程FPGA那些事兒-驅動I 實驗按鍵模組

實驗二:按鍵模組① - 消抖 按鍵消抖實驗可謂是經典中的經典,按鍵消抖實驗雖曾在《建模篇》出現過,而且還惹來一堆麻煩。事實上,筆者這是在刁難各位同學,好讓對方的慣性思維短路一下,但是慘遭口水攻擊 ... 面對它,筆者宛如被甩的男人,對它又愛又恨。不管怎麼樣,如今 I’ll be back,筆者再也不會重複一

黑金原創教程FPGA那些事兒-驅動I 實驗數碼管模組

實驗六:數碼管模組 有關數碼管的驅動,想必讀者已經學爛了 ... 不過,作為學習的新儀式,再爛的東西也要溫故知新,不然學習就會不健全。黑金開發板上的數碼管資源,由始至終都沒有改變過,筆者因此由身懷念。為了點亮多位數碼管從而顯示數字,一般都會採用動態掃描,然而有關動態掃描的資訊請怒筆者不再重複。在此,同樣也是

黑金原創教程FPGA那些事兒-驅動I 實驗按鍵模組③ — 單擊與雙擊

實驗四:按鍵模組③ — 單擊與雙擊 實驗三我們建立了“點選”還有“長點選”等有效按鍵的多功能按鍵模組。在此,實驗四同樣也是建立多功能按鍵模組,不過卻有不同的有效按鍵。實驗四的按鍵功能模組有以下兩項有效按鍵: l 單擊(按下有效); l 雙擊(連續按下兩下有效)。 圖4.1 單擊有效按鍵,時序示意圖

黑金原創教程FPGA那些事兒-驅動I 實驗按鍵模組④ — 點選,長點選,雙擊

實驗五:按鍵模組④ — 點選,長點選,雙擊 實驗二至實驗四,我們一共完成如下有效按鍵: l 點選(按下有效) l 點選(釋放有效) l 長擊(長按下有效) l 雙擊(連續按下有效) 然而,不管哪個實驗都是隻有兩項“功能”的按鍵模組而已,如今我們要建立三項“功能”的按鍵模組,亦即點選(按下有效),長

黑金原創教程FPGA那些事兒-驅動I 原創教程連載導讀連載完成,共二十九章

前言: 無數晝夜的來回輪替以後,這本《驅動篇I》終於編輯完畢了,筆者真的感動到連鼻涕也流下來。所謂驅動就是認識硬體,還有前期建模。雖然《驅動篇I》的硬體都是我們熟悉的老友記,例如UART,VGA等,但是《驅動篇I》貴就貴在建模技巧的昇華,亦即低階建模II。 話說低階建模II,讀過《建模篇》的朋友多少也會面

黑金原創教程FPGA那些事兒-驅動I 實驗二十一SDRAM模組④ — 頁讀寫 β

實驗二十一:SDRAM模組④ — 頁讀寫 β 未進入主題之前,讓我們先來談談一些重要的體外話。《整合篇》之際,筆者曾經比擬Verilog如何模仿for迴圈,我們知道for迴圈是順序語言的產物,如果Verilog要實現屬於自己的for迴圈,那麼它要考慮的東西除了步驟以外,還有非常關鍵的時鐘。 for(

黑金原創教程FPGA那些事兒-驅動I 實驗PS/2模組④ — 普通滑鼠

實驗十:PS/2模組④ — 普通滑鼠 學習PS/2鍵盤以後,接下來就要學習 PS/2 滑鼠。PS/2滑鼠相較PS/2鍵盤,驅動難度稍微高了一點點,因為FPGA(從機)不僅僅是從PS/2滑鼠哪裡讀取資料,FPGA還要往滑鼠裡寫資料 ... 反之,FPGA只要對PS/2鍵盤讀取資料即可。然而,最傷腦筋的地方就在

黑金原創教程FPGA那些事兒-驅動I 實驗十八SDRAM模組① — 單字讀寫

實驗十八:SDRAM模組① — 單字讀寫 筆者與SDRAM有段不短的孽緣,它作為冤魂日夜不斷糾纏筆者。筆者嘗試過許多方法將其退散,不過屢試屢敗的筆者,最終心情像橘子一樣橙。《整合篇》之際,筆者曾經大戰幾回兒,不過內容都是點到即止。最近它破蠱而出,日夜不停:“好~痛苦!好~痛苦!”地呻吟著,嚇得筆者不敢半夜如

黑金原創教程FPGA那些事兒-驅動I 實驗二十TFT模組

實驗二十七:TFT模組 - 顯示 所謂TFT(Thin Film Transistor)就是眾多LCD當中,其中一種支援顏色的LCD,相較古老的點陣LCD(12864笑),它可謂高階了。黑金的TFT LCD除了320×240大小以外,內建SSD1289控制器,同時也是獨立模組。事實上,無論是驅動點陣LCD還

黑金原創教程FPGA那些事兒-驅動I 實驗十三串列埠模組② — 接收

實驗十三:串列埠模組② — 接收 我們在實驗十二實現了串列埠傳送,然而這章實驗則要實現串列埠接收 ... 在此,筆者也會使用其它思路實現串列埠接收。 圖13.1 模組之間的資料傳輸。 假設我們不考慮波特率,而且一幀資料之間的傳輸也只是發生在FPGA之間,即兩隻模組之間互轉,並且兩塊模組都使用相同的時

黑金原創教程FPGA那些事兒-驅動I 實驗PS/2模組① — 鍵盤

實驗七:PS/2模組① — 鍵盤 實驗七依然也是熟爛的PS/2鍵盤。相較《建模篇》的PS/2鍵盤實驗,實驗七實除了實現基本的驅動以外,我們還要深入解PS/2時序,還有PS/2鍵盤的行為。不過,為了節省珍貴的頁數,怒筆者不再重複有關PS/2的基礎內容,那些不曉得的讀者請複習《建模篇》或者自行谷歌一下。 市場

黑金原創教程FPGA那些事兒-驅動I 實驗PS/2模組③ — 鍵盤與多組合鍵

實驗九:PS/2模組③ — 鍵盤與多組合鍵 筆者曾經說過,通碼除了單位元組以外,也有雙位元組通碼,而且雙位元組通碼都是 8’hE0開頭,別名又是 E0按鍵。常見的的E0按鍵有,<↑>,<↓>,<←>,<→>,<HOME>,<PRTSC>

黑金原創教程FPGA那些事兒-驅動I 實驗二十五SDHC模組

實驗二十五:SDHC模組 筆者曾經說過,SD卡發展至今已經衍生許多版本,實驗二十四就是針對版本SDV1.×的SD卡。實驗二十四也說過,CMD24還有CMD17會故意偏移地址29,讓原本範圍指向從原本的232 變成 223,原因是SD卡讀寫一次都有512個位元組。為此我們可以這樣計算: SDV1.x = 2

黑金原創教程FPGA那些事兒-驅動I 實驗二十SDRAM模組③ — 頁讀寫 α

實驗二十:SDRAM模組③ — 頁讀寫 α 完成單字讀寫與多字讀寫以後,接下來我們要實驗頁讀寫。醜話當前,實驗二十的頁讀寫只是實驗性質的東西,其中不存在任何實用價值,筆者希望讀者可以把它當成頁讀寫的熱身運動。 表示20.1 Mode Register的內容。 Mode Register

黑金原創教程FPGA那些事兒-驅動I 實驗二十八TFT模組

實驗二十八:TFT模組 - 觸屏 讀者在上一個實驗所玩弄過的 TFT LCD模組,除了顯示大小為 320 × 240,顏色為16位RGB的影象資訊以外,它還支援觸屏。所謂觸屏就是滑鼠還有鍵盤以外的輸入手段,例如現在流行平板還有智慧手機,觸屏輸入對我們來說,已經成為日常的一部分。描述語言一門偏向硬體的語言

黑金原創教程FPGA那些事兒-驅動I 實驗二十二SDRAM模組⑤ — FIFO讀寫

經過漫長的戰鬥以後,我們終於來到最後。對於普通人而言,頁讀寫就是一名戰士的墓碑(最終戰役) ... 然而,怕死的筆者想透過這個實驗告訴讀者,旅程的終點就是旅程的起點。一直以來,筆者都在煩惱“SDRAM是否應該成為儲存類?”SDRAM作為一介儲存資源(儲存器),它的好處就是大容量空間,壞處則就是麻煩的控制規

黑金原創教程FPGA那些事兒-驅動I 實驗十四儲存模組

實驗十四比起動手筆者更加註重原理,因為實驗十四要討論的東西,不是其它而是低階建模II之一的模組類,即儲存模組。接觸順序語言之際,“儲存”不禁讓人聯想到變數或者陣列,結果它們好比資料的暫存空間。 1. int main() 2. { 3. int VarA; 4.