99在线精品免费视频九九视-99在线精品视频-99在线精品视频免费观里-99在线精品视频在线观看-99在线免费播放

【案例】SPI接口設(shè)計(jì)

  發(fā)布時間:2023-10-19  |    作者:管理員  |  瀏覽量:1269

SPI(Serial Peripheral Interface--串行外設(shè)接口)總線系統(tǒng)是一種同步串行外設(shè)接口,它可以使MCU與各種外圍設(shè)備以串行方式進(jìn)行通信以交換信息。本項(xiàng)目我們通過SPI接口實(shí)現(xiàn)FPGA與EEPROM芯片——AT93C46的通信。示意圖如圖3-16

fpga就業(yè)

3-16 SPI接口傳輸結(jié)構(gòu)圖

先查閱AT93C46的datasheet,了解各引腳的作用
cs:從器件使能信號,由主器件控制;
sk:時鐘信號,由主器件產(chǎn)生;
do:主器件數(shù)據(jù)輸入,從器件數(shù)據(jù)輸出;
di:主器件數(shù)據(jù)輸出,從器件數(shù)據(jù)輸入。
再明確實(shí)現(xiàn)相互通信需要哪些操作。
1. 三種基本的操作


1EWEN時序(圖3-17

3-17 EWEN時序圖

EWEN可以理解為激活設(shè)備,寫、擦除(這里沒有用到,有興趣的讀者可以自行查閱datasheet)操作執(zhí)行之前必須要先執(zhí)行完EWEN操作。其操作過程為:
1.cs
在開始操作時拉高,等到讀操作完成,拉低;
2.sk在CS拉高時,產(chǎn)生10個脈沖,脈沖周期大于400ns;
3.di在SK的周期內(nèi)輸出數(shù)據(jù),前面輸出固定的指令“10011”,指示是EWEN操作,后面則繼續(xù)輸出5比特的“0”。

 (2)WRITE時序(圖3-18

3-18 WRITE時序圖

寫操作:
(1)cs先拉高一段時間,然后再拉低TCS時間,最后再拉高CS,直至檢測到DO為1,拉低;
(2)sk在CS第一段拉高時,產(chǎn)生18個脈沖,脈沖周期大于400ns;
(3)di在sk的周期內(nèi)輸出數(shù)據(jù),前面輸出固定的指令“101”,指示是寫操作,后面則繼續(xù)輸出地址“AN~A0”和數(shù)據(jù)“DN~D0”。

   (3READ時序(圖3-19

fpga就業(yè)前景

3-19 ERAD時序圖
(1)cs
在開始操作時拉高,等到讀操作完成,拉低;
(2)sk在cs第一段拉高時,產(chǎn)生18個脈沖,脈沖周期大于400ns;
(3)di在sk的周期內(nèi)輸出數(shù)據(jù),前面輸出固定的指令“110”,指示是讀操作,后面則繼續(xù)輸出地址“AN~A0”和固定的“0”;
(4)模塊從sk的第11個周期開始從do中讀取數(shù)據(jù),每個周期讀取1比特,共8比特。

實(shí)現(xiàn)一個AT93C46的接口,該接口能夠根據(jù)命令,實(shí)現(xiàn)EWEN、WRITE和READ功能。具體功能如下:
明德?lián)P在變化范圍內(nèi)取了1us作為tcs的值;AT93C46時鐘取1MHz。
上游模塊在rdy=1時,給出start命令,開始進(jìn)行EWEN、WRITE或者READ操作。在rdy=0期間,start命令無效。
當(dāng)
start有效時,如果mode=0表示進(jìn)行EWEN操作;mode=1表示進(jìn)行WRITE操作;mode=2表示進(jìn)行READ操作。
當(dāng)start有效時,addr和wdata有效。
當(dāng)進(jìn)行EWEN操作時,模塊將按at93c46 EWEN的要求,將addr寫入at93c46。
當(dāng)進(jìn)行WRITE操作時,模塊將按at93c46 WRITE的要求,將addr和wdata寫入at93c46。
當(dāng)進(jìn)行READ操作時,模塊將按at93c46 READ的要求,將addr寫入at93c46,并從at93c46讀到數(shù)據(jù),通過rdata和rdata_vld返回給上游模塊。


2. 設(shè)計(jì)過程

1明確功能

根據(jù)題目可以畫出設(shè)備與AT93C46之間的具體通信框圖如圖3-20

3-20 信號傳輸架構(gòu)圖

3.5 信號列表

至簡設(shè)計(jì)法

(2)輸出分析

cs:在WRITE操作時,寫入一個地址和數(shù)據(jù)后拉低,間隔tcs拉高,等待寫操作完成;READ操作和EWEN操作都是在操作期間為高,操作結(jié)束拉低。
sk:引入計(jì)數(shù)器,通過計(jì)數(shù)產(chǎn)生1MHz的芯片時鐘。
rdy:從操作開始到結(jié)束一直為低電平,其他時刻為高電平。
  di:根據(jù)操作的不同輸出相應(yīng)的值
rdata:僅在READ操作時do的值從高位到低位,一比特一比特地給rdata賦值。
rdata_vld:在rdata賦值結(jié)束后,拉高一個時鐘周期,表示此時rdata有效。


3狀態(tài)劃分

從EWEN、READ和WRITE的時序圖我們可以發(fā)現(xiàn)在不同操作中有很多階段是相似的,總結(jié)起來有4個狀態(tài):
IDLE:初始狀態(tài),模塊在等待start信號有效。
WR_RD:讀寫狀態(tài)。
TCS:片選信號拉低。
DO:等待寫入操作完成。


4)狀態(tài)轉(zhuǎn)移

狀態(tài)轉(zhuǎn)移圖請見3-21

至簡設(shè)計(jì)法

3-21 狀態(tài)轉(zhuǎn)移圖


5轉(zhuǎn)移條件

確定了狀態(tài)轉(zhuǎn)移圖后,我們需要明確狀態(tài)轉(zhuǎn)移條件:

wr_rd_start:在IDLE狀態(tài)下收到start有效。

tcs_start:在WR_RD狀態(tài)結(jié)束。

idle_start1:,處于EWEN或READ模式,在TCS狀態(tài)結(jié)束(1us)。

do_start:處于WRITE模式,在TCS結(jié)束(1us)。

idle_start2:處于WRITE模式,在TCS狀態(tài)下,收到do==1。


6完整性檢查

至簡設(shè)計(jì)法

7狀態(tài)機(jī)代碼

第二段,用組合邏輯描述狀態(tài)轉(zhuǎn)移條件。注意轉(zhuǎn)移條件用信號來表示,信號名要按明德?lián)P規(guī)則來命名。

 always  @(*)begin
 2     case(state_c)
 3         IDLE:begin
 4             if(idl2wrd_start)begin
 5                 state_n = WR_RD;
 6             end
 7             else begin
 8                 state_n = state_c;
 9             end
10         end
11         WR_RD:begin
12             if(wrd2tcs_start)begin
13                 state_n = TCS;
14             end
15             else begin
16                 state_n = state_c;
17             end
18         end
19         TCS:begin
20             if(tcs2do_start)begin
21                 state_n = DO;
22             end
23             else if(tcs2idl_start)begin
24                 state_n = IDLE;
25             end
26             else begin
27                 state_n = state_c;
28             end
29         end
30         DO:begin
31             if(do2idl_start)begin
32                 state_n = IDLE;
33             end
34             else begin
35                 state_n = state_c;
36             end
37         end
38         default:begin
39             state_n = IDLE;
40         end
41     endcase
42 end
43

第三段,用assign定義轉(zhuǎn)移條件。注意條件一定要加上現(xiàn)態(tài)。

assign idl2wrd_start = state_c == IDLE && start == 1;
assign wrd2tcs_start = state_c == WR_RD&& end_cnt1;
assign tcs2idl_start = state_c == TCS && end_cnt
                       && (mode_reg==EWEN||mode_reg==READ);
assign tcs2do_start = state_c == TCS && mode_reg == WRITE && end_cnt;
assign do2idl_start = state_c == DO && mode_reg == WRITE && do_ff1 == 1;

第四段,則是輸出信號設(shè)計(jì),在功能代碼部分。

8)功能代碼

  1 //根據(jù)第六步第1點(diǎn),寫出cnt的代碼
  2 always  @(posedge clk or negedge rst_n)begin
  3     if(rst_n==1'b0)begin
  4         cnt <= 0;
  5     end
  6     else if(add_cnt) begin
  7         if(end_cnt)
  8             cnt <= 0;
  9         else
 10             cnt <= cnt + 1;
 11     end
 12 end
 13 assign  add_cnt = state_c == WR_RD || state_c == TCS;
 14 assign  end_cnt = add_cnt && cnt==100 - 1 ;
 15
 16 //根據(jù)第六步第2點(diǎn),寫出cnt1的代碼
 17 always  @(posedge clk or negedge rst_n)begin
 18     if(rst_n==1'b0)begin
 19         cnt1<= 0;
 20     end
 21     else if(add_cnt1) begin
 22         if(end_cnt1)
 23             cnt1 <= 0;
 24         else
 25             cnt1 <= cnt1 + 1;
 26     end
 27 end
 28 assign  add_cnt1 = end_cnt;
 29 assign  end_cnt1 = add_cnt1 && cnt1==-1 ;
 30
 31 always  @(*)begin
 32     if(mode_reg == EWEN)begin
 33         x = 10;
 34     end
 35     else if(mode_reg == WRITE)begin
 36         x = 18;
 37     end
 38     else if(mode_reg == READ)begin
 39         x = 18;
 40     end
 41     else begin
 42         x = 0;
 43     end
 44 end
 45 //根據(jù)第六步第3點(diǎn),寫出do的代碼
 46 always  @(posedge clk or negedge rst_n)begin
 47     if(rst_n==1'b0)begin
 48         do_ff0<=0;
 49         do_ff1<=0;
 50     end
 51     else begin
 52         do_ff0<=d0;
 53         do_ff1<=do_ff0;
 54     end
 55 end
 56
 57 //根據(jù)第六步第4點(diǎn),寫出sk的代碼
 58 always  @(posedge clk or negedge rst_n)begin
 59     if(rst_n==1'b0)begin
 60         sk <= 0;
 61     end
 62     else if(sk_high)begin
 63         sk <= 1;
 64     end
 65     else if(sk_low)begin
 66         sk <= 0;
 67     end
 68 end
 69 assign sk_high = state_c == WR_RD && add_cnt && cnt == 50-1;
 70 assign sk_low = state_c == WR_RD && end_cnt;
 71
 72 //根據(jù)第六步第5點(diǎn),寫出di的代碼
 73 always  @(posedge clk or negedge rst_n)begin
 74     if(rst_n==1'b0)begin
 75         di <= 0;
 76     end
 77     else if(di_en)begin
 78         di <= dout[17-cnt1];
 79     end
 80 end
 81 assign di_en = cnt==0 && state_c == WR_RD;
 82
 83 //根據(jù)第六步第6點(diǎn),寫出cs的代碼
 84 always  @(posedge clk or negedge rst_n)begin
 85     if(rst_n==1'b0)begin
 86         cs <= 0;
 87     end
 88     else if(cs_high)begin
 89         cs <= 1;
 90     end
 91     else if(cs_low)begin
 92         cs <= 0;
 93     end
 94 end
 95 assign cs_high = idl2wrd_start || tcs2do_start;
 96 assign cs_low = wrd2tcs_start || do2idl_start; 
 97
 98 //根據(jù)第六步第7點(diǎn),寫出rdy的代碼
 99 always  @(*)begin
100     if(rdy_low)
101         rdy = 0;
102     else 
103         rdy = 1;
104 end
105 assign rdy_low = start || state_c != IDLE;  
106
107 //根據(jù)第六步第8點(diǎn),寫出rdata的代碼
108 always  @(posedge clk or negedge rst_n)begin
109     if(rst_n==1'b0)begin
110         rdata <= 0;
111     end
112     else if(rdata_en)begin
113         rdata <=  {rdata[6:0],do};
114     end
115 end
116 assign rdata_en = mode_reg == READ && state_c == WR_RD && end_cnt
117 && cnt1 >= 10 && cnt1 < 18;
118
119 //根據(jù)第六步第9點(diǎn),寫出rdata_vld的代碼
120 always  @(posedge clk or negedge rst_n)begin
121     if(rst_n==1'b0)begin
122         rdata_vld <= 0;
123     end
124     else if(rdata_vld_en)begin
125         rdata_vld <= 1;
126     end
127     else begin
128         rdata_vld <= 0;    
129     end
130 end
131 assign rdata_vld_en = mode_reg == READ && wrd2tcs_start;
132
133 //根據(jù)第六步第10點(diǎn),寫出dout的代碼
134 always  @(posedge clk or negedge rst_n)begin
135     if(rst_n==1'b0)begin
136         dout <= 0;
137     end
138     else if(start && mode==0)begin
139         dout <= {3'b100,2’b11,13'b0};
140     end
141     else if(start && mode==1)begin
142         dout <= {3'b101,addr,wdata};
143     end
144     else if(start && mode==2)begin
145         dout <= {3'b110,addr,8'b0};
146     end
147 end
148

149 always  @(posedge clk or negedge rst_n)begin
150     if(rst_n==1'b0)begin
151         mode_reg <= 0;
152     end
153     else if(start && mode==0)begin
154         mode_reg <= EWEN;
155     end
156     else if(start && mode==1)begin
157         mode_reg <= WRITE;
158     end
159     else if(start && mode==2)begin
160         mode_reg <= READ;
161     end
162 end

163



溫馨提示:明德?lián)P2023推出了全新課程——邏輯設(shè)計(jì)基本功修煉課,降低學(xué)習(xí)FPGA門檻的同時,增加了學(xué)習(xí)的趣味性,并組織了考試贏積分活動

http://m.cqqtmy.cn/ffkc/415.html

(點(diǎn)擊→了解課程詳情?)感興趣請聯(lián)系易老師:13112063618(微信同步)




本文TAG:

Copyright ? 2012-2023 版權(quán)所有:深圳明德?lián)P科技教育有限公司

主站蜘蛛池模板: 另类图片成人偷拍 | 久久免费精品视频在线观看 | 三级黄色在线免费观看 | 三级国产在线观看 | 日韩免费无砖专区2020狼 | 午夜精品福利视频 | 久久青青草原国产精品免费 | 久久综合婷婷香五月 | 狠狠色丁香久久婷婷综合五月 | 小明看片成人永久在线观看 | 99久久精彩视频 | 日本欧美做爰全免费的视频 | 二区视频在线 | 尤物视频网站在线 | 一级毛片免费观看不卡的 | 在线视频一区二区三区四区 | 51国产午夜精品免费视频 | 午夜在线视频一区二区三区 | 亚洲精品国产网红在线 | 欧美啪| 国产午夜不卡在线观看视频666 | 特级aa一级欧美毛片 | 亚洲国产日韩精品 | 亚洲欧洲日韩综合 | 一级黄色片毛片 | 伊人久久精品成人网 | 国产伦一区二区三区高清 | 国产在线乱码在线视频 | 国产大片91精品免费观看男同 | 最新的国产成人精品2022 | 8小8x免费观看2020麻豆 | 中国黄色录像 | 在线欧美色 | 美美女高清毛片视频黄的一免费 | 欧美一级久久久久久久大 | 欧美高清在线不卡免费观看 | 国产男人午夜视频在线观看 | 国产一区二区fc2ppv在线播放 | 8888四色奇米在线观看免费看 | 国产精品麻豆综合在线 | 国产成人亚洲精品无广告 |