本(běn)文(wén)为(wèi)明(míng)德揚原創及(jí)录(lù)用(yòng)文(wén)章(zhāng),轉(zhuǎn)载請注明(míng)出(chū)处!
1.1 總(zǒng)體(tǐ)設計(jì)
1.1.1 概述
在(zài)鍵盤中(zhōng)按鍵數量(liàng)較多(duō)时(shí),为(wèi)了(le)減少(shǎo)I/O口(kǒu)的(de)占用(yòng),通(tòng)常将按鍵排列成(chéng)矩阵(zhèn)形式。在(zài)矩阵(zhèn)式鍵盤中(zhōng),每条(tiáo)水(shuǐ)平線(xiàn)和(hé)垂直(zhí)線(xiàn)在(zài)交叉(chā)处不(bù)直(zhí)接連(lián)通(tòng),而(ér)是(shì)通(tòng)过(guò)一(yī)个(gè)按鍵加以(yǐ)連(lián)接。这(zhè)樣(yàng),一(yī)个(gè)端口(kǒu)(如(rú)P1口(kǒu))就(jiù)可(kě)以(yǐ)構成(chéng)4*4=16个(gè)按鍵,比之直(zhí)接将端口(kǒu)線(xiàn)用(yòng)于(yú)鍵盤多(duō)出(chū)了(le)一(yī)倍,而(ér)且線(xiàn)數越多(duō),區(qū)别越明(míng)顯,比如(rú)再多(duō)加一(yī)条(tiáo)線(xiàn)就(jiù)可(kě)以(yǐ)構成(chéng)20鍵的(de)鍵盤,而(ér)直(zhí)接用(yòng)端口(kǒu)線(xiàn)則只(zhī)能(néng)多(duō)出(chū)一(yī)鍵(9鍵)。由(yóu)此(cǐ)可(kě)見(jiàn),在(zài)需要(yào)的(de)鍵數比較多(duō)时(shí),采用(yòng)矩阵(zhèn)法来(lái)做鍵盤是(shì)合理的(de)。
1.1.2 設計(jì)目标(biāo)
完成(chéng)矩阵(zhèn)鍵盤的(de)掃描檢测程序,具體(tǐ)功能(néng)要(yào)求如(rú)下(xià):
1. 運用(yòng)逐行掃描的(de)方(fāng)法進(jìn)行按鍵監测;
2. 每行掃描的(de)时(shí)間(jiān)不(bù)少(shǎo)于(yú) 20ms,濾除抖動(dòng);
3. 檢测到(dào)有(yǒu)按鍵按下(xià)之後(hòu),消抖时(shí)間(jiān) 20ms;
4. 輸出(chū)信(xìn)号(hào) key_vld 持(chí)續一(yī)拍即可(kě);
5. 輸出(chū)信(xìn)号(hào)key_out表(biǎo)示16 个(gè)按鍵,并在(zài)數碼管(guǎn)上(shàng)顯示对(duì)應(yìng)數值;
1.1.3 系(xì)統結構框图(tú)
系(xì)統結構框图(tú)如(rú)下(xià)图(tú)一(yī)所(suǒ)示:

图(tú)一(yī)
1.1.4 模块(kuài)功能(néng)
Ø 矩阵(zhèn)鍵盤模块(kuài)实現(xiàn)功能(néng)
1、将外(wài)来(lái)异(yì)步信(xìn)号(hào)打(dǎ)两(liǎng)拍处理,将异(yì)步信(xìn)号(hào)同(tóng)步化(huà)。
2、实現(xiàn)20ms按鍵消抖功能(néng)。
3、实現(xiàn)矩阵(zhèn)鍵盤的(de)按鍵檢测功能(néng),并輸出(chū)有(yǒu)效按鍵信(xìn)号(hào)。
Ø 數碼管(guǎn)顯示模块(kuài)实現(xiàn)功能(néng)
1、 对(duì)接收(shōu)到(dào)的(de)按鍵數據(jù)進(jìn)行譯碼并顯示。
1.1.5 頂层信(xìn)号(hào)

1.1.6 參考代(dài)碼
下(xià)面(miàn)是(shì)使用(yòng)工程的(de)頂层代(dài)碼:
1. module top(
2. clk ,
3. rst_n ,
4. key_col ,
5. key_row ,
6. segment ,
7. seg_sel
8. );
9.
10. parameter DATA_W = 4;
11.
12. input clk ;
13. input rst_n ;
14. input [3:0] key_col;
15.
16. output [3:0] key_row;
17. output [7:0] segment;
18. output [1:0] seg_sel;
19.
20. wire [3:0] key_row;
21. wire [7:0] segment;
22. wire [1:0] seg_sel;
23.
24. wire [DATA_W-1:0] key_out ;
25. wire key_vld ;
26. wire [DATA_W-1:0] segment_data ;
27.
28. key_scan u1(
29. .clk ( clk ),
30. .rst_n ( rst_n ),
31. .key_col ( key_col ),
32. .key_row ( key_row ),
33. .key_out ( key_out ),
34. .key_vld ( key_vld )
35. );
36.
37. seg_disp u3(
38. .clk ( clk ),
39. .rst_n ( rst_n ),
40. .data_in ( key_out ),
41. .key_en ( key_vld ),
42. .segment ( segment ),
43. .seg_sel ( seg_sel )
44. );
45.
46. endmodule
1.2 矩阵(zhèn)鍵盤模块(kuài)設計(jì)
1.2.1 接口(kǒu)信(xìn)号(hào)

1.2.2 設計(jì)思(sī)路(lù)
Ø 行掃描法原理
開(kāi)發(fà)板上(shàng)为(wèi) 4*4 矩阵(zhèn)鍵盤:默認 4 条(tiáo)列線(xiàn)上(shàng)来(lái)高(gāo)電(diàn)平,4 条(tiáo)行線(xiàn)默認接高(gāo)電(diàn)平。列線(xiàn) KEY_C1 ~ KEY_C4分(fēn)别接有(yǒu)4个(gè)上(shàng)拉電(diàn)阻到(dào)正(zhèng)電(diàn)源 +3.3 V,并把列線(xiàn) KEY_C1~KEY_C4設置为(wèi)輸入(rù)線(xiàn),行線(xiàn) KEY_R1~KEY_R4設置为(wèi)輸出(chū)線(xiàn)。4根(gēn)行線(xiàn)和(hé)4根(gēn)列線(xiàn)形成(chéng)16个(gè)相交點(diǎn)。
如(rú)下(xià)图(tú)所(suǒ)示:

确認矩阵(zhèn)鍵盤上(shàng)哪个(gè)按鍵被(bèi)按下(xià)有(yǒu)多(duō)同(tóng)方(fāng)法,其中(zhōng)行掃描法又稱为(wèi)逐行(或(huò)列)掃描查詢法,是(shì)一(yī)種(zhǒng)最(zuì)常用(yòng)的(de)按鍵識别方(fāng)法。
1. 判斷鍵盤中(zhōng)有(yǒu)无鍵按下(xià):将全(quán)部(bù)行線(xiàn) KEY_R1~KEY_R4 置低電(diàn)平,然後(hòu)檢测列線(xiàn) KEY_C1~KEY_C4 的(de)狀态。只(zhī)要(yào)有(yǒu)一(yī)列的(de)電(diàn)平为(wèi)低,則表(biǎo)示鍵盤中(zhōng)有(yǒu)鍵被(bèi)按下(xià),而(ér)且閉合的(de)鍵位于(yú)低電(diàn)平線(xiàn)與(yǔ) 4根(gēn)行線(xiàn)相交叉(chā)的(de) 4 个(gè)按鍵之中(zhōng)。若所(suǒ)有(yǒu)列線(xiàn)均为(wèi)高(gāo)電(diàn)平,則鍵盤中(zhōng)无鍵按下(xià)。
2. 判斷閉合鍵所(suǒ)在(zài)的(de)位置:在(zài)确認有(yǒu)鍵按下(xià)後(hòu),即可(kě)進(jìn)入(rù)确定(dìng)具體(tǐ)閉合鍵的(de)过(guò)程。其方(fāng)法是(shì):依次(cì)将行線(xiàn)置为(wèi)低電(diàn)平,即在(zài)置某根(gēn)行線(xiàn)为(wèi)低電(diàn)平时(shí),其它(tā)線(xiàn)为(wèi)高(gāo)電(diàn)平。在(zài)确定(dìng)某根(gēn)行線(xiàn)位置为(wèi)低電(diàn)平後(hòu),再逐行檢测各(gè)列線(xiàn)的(de)電(diàn)平狀态。若某列为(wèi)低,則該列線(xiàn)與(yǔ)置为(wèi)低電(diàn)平的(de)行線(xiàn)交叉(chā)处的(de)按鍵就(jiù)是(shì)閉合的(de)按鍵。
Ø 打(dǎ)拍操作
輸入(rù)的(de)key_col是(shì)异(yì)步信(xìn)号(hào),所(suǒ)以(yǐ)要(yào)進(jìn)行打(dǎ)两(liǎng)拍操作,将异(yì)步信(xìn)号(hào)key_col同(tóng)步化(huà),并防止亞稳态。
設計(jì)代(dài)碼如(rú)下(xià):
1. input [3:0] key_col ;
2.
3. reg [3:0] key_col_ff0 ;
4. reg [3:0] key_col_ff1 ;
5.
6. always @(posedge clk or negedge rst_n)begin
7. if(rst_n==1'b0)begin
8. key_col_ff0 <= 4'b1111;
9. key_col_ff1 <= 4'b1111;
10. end
11. else begin
12. key_col_ff0 <= key_col ;
13. key_col_ff1 <= key_col_ff0;
14. end
15. end
Ø 按鍵消抖
对(duì)于(yú)按鍵和(hé)觸摸屏等機(jī)械設備来(lái)说(shuō),都存在(zài)一(yī)个(gè)固有(yǒu)問(wèn)題(tí),那(nà)就(jiù)是(shì)“抖動(dòng)”,按鍵從最(zuì)初接通(tòng)到(dào)稳定(dìng)接通(tòng)要(yào)經(jīng)过(guò)數毫(háo)秒(miǎo),其間(jiān)可(kě)能(néng)發(fà)生(shēng)多(duō)次(cì)“接通(tòng)-斷開(kāi)”这(zhè)樣(yàng)的(de)毛(máo)刺。如(rú)果(guǒ)不(bù)進(jìn)行处理,会(huì)使系(xì)統識别到(dào)抖動(dòng)信(xìn)号(hào)而(ér)進(jìn)行不(bù)必要(yào)的(de)反(fǎn)應(yìng),導致(zhì)模块(kuài)功能(néng)不(bù)正(zhèng)常,为(wèi)了(le)避免这(zhè)種(zhǒng)現(xiàn)象(xiàng)的(de)産生(shēng),需要(yào)進(jìn)行按鍵消抖的(de)操作。
软(ruǎn)件(jiàn)方(fāng)法消抖,即檢测出(chū)鍵閉合後(hòu)執行一(yī)个(gè)延时(shí)程序,抖動(dòng)时(shí)間(jiān)的(de)长短(duǎn)由(yóu)按鍵的(de)機(jī)械特(tè)性(xìng)決定(dìng),一(yī)般为(wèi)5ms~20ms,讓前(qián)沿抖動(dòng)消失後(hòu)再一(yī)次(cì)檢测鍵的(de)狀态,如(rú)果(guǒ)仍保持(chí)閉合狀态電(diàn)平,則确認按下(xià)按鍵操作有(yǒu)效。當檢测到(dào)按鍵釋放(fàng)後(hòu),也(yě)要(yào)給(gěi)5ms~20ms的(de)延时(shí),待後(hòu)沿抖動(dòng)消失後(hòu)才能(néng)轉(zhuǎn)入(rù)該鍵的(de)处理程序。

由(yóu)于(yú)按鍵按下(xià)去(qù)的(de)时(shí)間(jiān)一(yī)般都会(huì)大于(yú)20ms,为(wèi)了(le)达(dá)到(dào)不(bù)管(guǎn)按鍵按下(xià)多(duō)久,都視为(wèi)按下(xià)一(yī)次(cì)的(de)效果(guǒ),提(tí)出(chū)以(yǐ)下(xià)計(jì)數器架構,如(rú)下(xià)图(tú)所(suǒ)示:

消抖計(jì)數器shake_cnt:用(yòng)于(yú)計(jì)算20ms的(de)时(shí)間(jiān),加一(yī)条(tiáo)件(jiàn)为(wèi)key_col_ff1 != 4'hf || key_row_check==1,表(biǎo)示當某个(gè)按鍵按下(xià)或(huò)者(zhě)進(jìn)行行掃描时(shí)就(jiù)開(kāi)始計(jì)數;數到(dào)1,000,000下(xià),表(biǎo)示數到(dào)20ms就(jiù)結束(shù)。
行掃描計(jì)數器row_index:用(yòng)于(yú)區(qū)分(fēn)掃描的(de)行,加一(yī)条(tiáo)件(jiàn)为(wèi)key_row_check && end_shake_cnt,表(biǎo)示當处于(yú)行掃描狀态并且每行消抖20ms後(hòu),開(kāi)始掃描下(xià)一(yī)行;數到(dào)4下(xià),表(biǎo)示4行按鍵掃描完了(le)。
按鍵:表(biǎo)示有(yǒu)无按鍵按下(xià),沒(méi)被(bèi)按下(xià)时(shí)为(wèi)高(gāo)電(diàn)平,按下(xià)後(hòu)为(wèi)低電(diàn)平。
行掃描指示信(xìn)号(hào)key_row_check:該信(xìn)号(hào)为(wèi)高(gāo)電(diàn)平,指示當前(qián)处于(yú)行掃描狀态。
矩阵(zhèn)鍵盤列信(xìn)号(hào)key_col_ff1:4bit位宽(kuān)的(de)矩阵(zhèn)鍵盤列信(xìn)号(hào),最(zuì)高(gāo)位表(biǎo)示矩阵(zhèn)鍵盤往右(yòu)數第(dì)四(sì)列,默認信(xìn)号(hào)为(wèi)key_col_ff1 = 4'hf,否則表(biǎo)示該信(xìn)号(hào)低電(diàn)平对(duì)應(yìng)位的(de)列有(yǒu)按鍵按下(xià)。
1.2.3 參考代(dài)碼
16. module key_scan(
17. clk ,
18. rst_n ,
19. key_col,
20. key_row,
21. key_out,
22. key_vld
23. );
24.
25. parameter DATA_W = 4 ;
26. parameter TIME_20MS = 1_000_000 ;
27.
28. input clk ;
29. input rst_n ;
30. input [3:0] key_col ;
31.
32. output [3:0] key_row ;
33. output key_vld ;
34. output [DATA_W-1:0] key_out ;
35.
36. reg [3:0] key_row ;
37. reg key_vld ;
38. reg [DATA_W-1:0] key_out ;
39.
40. reg [3:0] key_col_ff0 ;
41. reg [3:0] key_col_ff1 ;
42. reg key_col_check ;
43. reg [21:0] shake_cnt ;
44. wire add_shake_cnt ;
45. wire end_shake_cnt ;
46. reg [1:0] key_col_get ;
47. reg key_row_check ;
48. reg [1:0] row_index ;
49. wire add_row_index ;
50. wire end_row_index ;
51.
52.
53. always @(posedge clk or negedge rst_n)begin
54. if(rst_n==1'b0)begin
55. key_col_ff0 <= 4'b1111;
56. key_col_ff1 <= 4'b1111;
57. end
58. else begin
59. key_col_ff0 <= key_col ;
60. key_col_ff1 <= key_col_ff0;
61. end
62. end
63.
64. always @(posedge clk or negedge rst_n)begin
65. if(rst_n==1'b0)begin
66. key_col_check <= 1'b0;
67. end
68. else if(key_col_ff1 !=4'hf && end_shake_cnt)begin
69. key_col_check <= 1'b1;
70. end
71. else if(key_col_ff1==4'hf)begin
72. key_col_check <= 1'b0;
73. end
74. end
75.
76.
77. always @(posedge clk or negedge rst_n) begin
78. if (rst_n==0) begin
79. shake_cnt <= 0;
80. end
81. else if(add_shake_cnt) begin
82. if(end_shake_cnt)
83. shake_cnt <= 0;
84. else
85. shake_cnt <= shake_cnt+1 ;
86. end
87. end
88. assign add_shake_cnt = key_col_ff1 !=4'hf || key_row_check==1;
89. assign end_shake_cnt = add_shake_cnt && shake_cnt == TIME_20MS-1 ;
90.
91.
92. always @(posedge clk or negedge rst_n)begin
93. if(rst_n==1'b0)begin
94. key_col_get <= 0;
95. end
96. else if(key_col_check) begin
97. if(key_col_ff1==4'b1110)
98. key_col_get <= 0;
99. else if(key_col_ff1==4'b1101)
100. key_col_get <= 1;
101. else if(key_col_ff1==4'b1011)
102. key_col_get <= 2;
103. else if(key_col_ff1==4'b0111)
104. key_col_get <= 3;
105. end
106. end
107.
108. always @(posedge clk or negedge rst_n)begin
109. if(rst_n==1'b0)begin
110. key_row_check <= 0;
111. end
112. else if(key_col_check)begin
113. key_row_check <= 1;
114. end
115. else if(key_vld)begin
116. key_row_check <= 0;
117. end
118. end
119.
120.
121. always @(posedge clk or negedge rst_n) begin
122. if (rst_n==0) begin
123. row_index <= 0;
124. end
125. else if(add_row_index) begin
126. if(end_row_index)
127. row_index <= 0;
128. else
129. row_index <= row_index+1 ;
130. end
131. end
132. assign add_row_index = key_row_check && end_shake_cnt;
133. assign end_row_index = add_row_index && row_index == 4-1 ;
134.
135.
136. always @(posedge clk or negedge rst_n)begin
137. if(rst_n==1'b0)begin
138. key_row = 4'b0;
139. end
140. else if(key_row_check)begin
141. key_row = ~(4'b0001 << row_index);
142. end
143. else begin
144. key_row = 4'b0;
145. end
146. end
147.
148.
149. always @(posedge clk or negedge rst_n)begin
150. if(rst_n==1'b0)begin
151. key_vld <= 1'b0;
152. end
153. else if(key_row_check && key_col_ff1[key_col_get]==1'b0 && key_col_check==0 )begin
154. key_vld <= 1'b1;
155. end
156. else begin
157. key_vld <= 1'b0;
158. end
159. end
160.
161.
162. always @(posedge clk or negedge rst_n)begin
163. if(rst_n==1'b0)begin
164. key_out <= 4'd0;
165. end
166. else if(key_vld)begin
167. key_out <= {row_index,key_col_get};
168. end
169. else begin
170. key_out <= 4'd0;
171. end
172. end
173.
174. endmodule
1.3 數碼管(guǎn)顯示模块(kuài)設計(jì)
1.3.1 接口(kǒu)信(xìn)号(hào)

1.3.2 設計(jì)思(sī)路(lù)
在(zài)前(qián)面(miàn)的(de)案(àn)例中(zhōng)已經(jīng)有(yǒu)數碼管(guǎn)顯示的(de)介紹,所(suǒ)以(yǐ)这(zhè)里(lǐ)不(bù)在(zài)过(guò)多(duō)介紹,詳细(xì)介紹請看(kàn)下(xià)方(fāng)鍊(liàn)接:
http://fpgabbs.com/forum.php?mod=viewthread&tid=399
1.3.3 參考代(dài)碼
1. module seg_disp(
2. clk ,
3. rst_n ,
4. data_in ,
5. key_en ,
6. segment ,
7. seg_sel
8. );
9.
10. parameter ZERO = 8'b0000_0011 ;
11. parameter ONE = 8'b1001_1111 ;
12. parameter TWO = 8'b0010_0101 ;
13. parameter THREE = 8'b0000_1101 ;
14. parameter FOUR = 8'b1001_1001 ;
15. parameter FIVE = 8'b0100_1001 ;
16. parameter SIX = 8'b0100_0001 ;
17. parameter SEVEN = 8'b0001_1111 ;
18. parameter EIGHT = 8'b0000_0001 ;
19. parameter NINE = 8'b0000_1001 ;
20.
21. input clk ;
22. input rst_n ;
23. input [3:0] data_in ;
24. input key_en ;
25. output [7:0 ] segment ;
26. output [1:0 ] seg_sel ;
27.
28. reg [7:0 ] segment ;
29. reg [1:0 ] seg_sel ;
30. reg [10:0] delay ;
31. reg [1:0 ] delay_time ;
32. wire add_delay_time ;
33. wire end_delay_time ;
34. wire add_delay ;
35. wire end_delay ;
36. reg [4:0 ] segment_tmp ;
37. reg [3:0 ] segment_data ;
38.
39.
40. always @(posedge clk or negedge rst_n) begin
41. if (rst_n==0) begin
42. delay <= 0;
43. end
44. else if(add_delay) begin
45. if(end_delay)
46. delay <= 0;
47. else
48. delay <= delay+1 ;
49. end
50. end
51. assign add_delay = 1;
52. assign end_delay = add_delay && delay == 2000-1 ;
53.
54.
55. always @(posedge clk or negedge rst_n) begin
56. if (rst_n==0) begin
57. delay_time <= 0;
58. end
59. else if(add_delay_time) begin
60. if(end_delay_time)
61. delay_time <= 0;
62. else
63. delay_time <= delay_time+1 ;
64. end
65. end
66. assign add_delay_time = end_delay;
67. assign end_delay_time = add_delay_time && delay_time == 2-1 ;
68.
69.
70. always @(posedge clk or negedge rst_n)begin
71. if(rst_n==1'b0)begin
72. segment_data <= 4'd0;
73. end
74. else if(key_en)begin
75. segment_data <= data_in;
76. end
77. end
78.
79. always @(posedge clk or negedge rst_n)begin
80. if(rst_n==1'b0)begin
81. segment_tmp <= 4'd0;
82. end
83. else if(add_delay_time && delay_time == 1-1)begin
84. segment_tmp <= (segment_data+1)%10;
85. end
86. else if(end_delay_time)begin
87. segment_tmp <= (segment_data+1)/10;
88. end
89. end
90.
91.
92. always @(posedge clk or negedge rst_n)begin
93. if(rst_n==1'b0)begin
94. segment <= ZERO;
95. end
96. else begin
97. case(segment_tmp)
98. 4'd0:segment <= ZERO;
99. 4'd1:segment <= ONE ;
100. 4'd2:segment <= TWO ;
101. 4'd3:segment <= THREE;
102. 4'd4:segment <= FOUR ;
103. 4'd5:segment <= FIVE ;
104. 4'd6:segment <= SIX ;
105. 4'd7:segment <= SEVEN;
106. 4'd8:segment <= EIGHT;
107. 4'd9:segment <= NINE ;
108. default:begin
109. segment <= segment;
110. end
111. endcase
112. end
113. end
114.
115.
116. always @(posedge clk or negedge rst_n)begin
117. if(rst_n==1'b0)begin
118. seg_sel <= 2'b11;
119. end
120. else begin
121. seg_sel <= ~(2'b1<<delay_time);
122. end
123. end
124.
125.
126. endmodule
1.4 效果(guǒ)和(hé)總(zǒng)結
Ø 下(xià)图(tú)是(shì)該工程在(zài)db603開(kāi)發(fà)板上(shàng)的(de)現(xiàn)象(xiàng)——按下(xià)按鍵s7

Ø 下(xià)图(tú)是(shì)該工程在(zài)ms980試验(yàn)箱上(shàng)的(de)現(xiàn)象(xiàng)——按下(xià)按鍵s13

由(yóu)于(yú)該項目的(de)上(shàng)板現(xiàn)象(xiàng)是(shì)按下(xià)矩阵(zhèn)按鍵,數碼管(guǎn)顯示对(duì)應(yìng)的(de)按鍵号(hào),想(xiǎng)观看(kàn)完整現(xiàn)象(xiàng)的(de)朋友可(kě)以(yǐ)看(kàn)一(yī)下(xià)現(xiàn)象(xiàng)演示的(de)視頻。
設計(jì)視頻教程、工程源代(dài)碼請移步明(míng)德揚論壇观看(kàn)下(xià)载。
感(gǎn)興趣的(de)朋友也(yě)可(kě)以(yǐ)訪問(wèn)明(míng)德揚論壇(www.fpgabbs.cn)進(jìn)行FPGA相關(guān)工程設計(jì)学習,也(yě)欢迎大家(jiā)在(zài)評論進(jìn)行讨論!
温(wēn)馨提(tí)示:明(míng)德揚2023推出(chū)了(le)全(quán)新課程——邏輯設計(jì)基本(běn)功修煉課,降低学習FPGA門(mén)檻的(de)同(tóng)时(shí),增加了(le)学習的(de)趣味性(xìng),并組織了(le)考試赢積分(fēn)活動(dòng)
http://www.minyingyiyuan.com/ffkc/415.html
(點(diǎn)擊→了(le)解(jiě)課程詳情(qíng)☝)感(gǎn)興趣請聯系(xì)易老(lǎo)师(shī):13112063618(微信(xìn)同(tóng)步)