第四講 串口通信_第1頁
第四講 串口通信_第2頁
第四講 串口通信_第3頁
第四講 串口通信_第4頁
第四講 串口通信_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

上一講我們講解了串口的發(fā)送操作。這一講我們繼續(xù)講解串口的接收。在學習這個串口接收的過程中,我們要鞏固這個狀態(tài)機的寫法,也再熟悉熟悉前幾講講解的內容。首先回顧一下異步串口通信的數據格式:LS日 MSB_ I0/」5I5I"川SIQ/JIw」 p- 4*~~4*~~?岫位 裁據位 檢唉位停止位至閑位由于在空閑狀態(tài)時,傳送線為邏輯“1”狀態(tài),而數據的傳送總是以一個起始位“0”開始,所以當接收器檢測到一個從“1”向“0”的跳變時,便視為可能的起始位(要排除干擾引起的跳變);起始位被確認后,就知道發(fā)送器已開始發(fā)送,接收器就可以按這個數據通信格式接收后續(xù)的數據了;當檢測到停止位“1”后就表明一幀字符數據已發(fā)送完畢。關于接收器的設計最主要的一點是如何提高采樣的準確率,最好是保證采樣點處于被采樣數據的時間中間點。所以,在接收采樣時要用比數據波特率高皿倍(nN1)速率的時鐘對數據進行采樣。在本程序中用16倍波特率時鐘進行采樣。結合圖示,我們講解一下如何讓采樣時刻處于被采樣數據的時間中間點:TOC\o"1-5"\h\zW中*1早早早早 || |iiiiiiii \ \1J[j1Ij] 十卜 [心JihAkhhhhiuuuuuuuuinmuuuiiuuL】2345£7B9101112B1415LGI2)4G7??10啟動檢醐 勃隊肩劫俚 采樣故搟在t1時刻若檢測到低電平,就開始對這個低電平進行連續(xù)的檢測當檢測了8個時鐘周期后,到達t2,此刻,若前面的8個周期都是低電平,則認為檢測到了起始脈沖。否則就認為是干擾,重新檢測。在檢測到起始位后,再計數16個采樣時鐘周期就到達了第一個數據位的時間中間點t3,在此刻采樣數據并進行保存。然后再經過16個周期,就是第二個數據位的時間中間點,在此時刻進行采樣;然后,再經過16個周期,就是第三個數據位的時間中間點,在此時刻進行采樣…..一直這樣采樣,直到把所有的數據位采樣完畢。在理解完上面這個流程后,我們來按這個編制一下程序。串口接收模塊1itziraryieee;usei已已已.std_lugic_l164.all;useieee.st.d_1□giit.h.al1;usei已已已?std_1□gic_unsignecl.all;entityuart_risgeneric(fr;5ii[ilen:integer:=8);一一數才居為TramlHn—1purr.(bclkr.resetr.rxdr:instd_logic;--rx赤數據輸入腳r_ready:out.st.d_logic;rlziuf:out.st.cl_Ingitori:7duTiTnt.nu)14 一一);encluart.r;17 一archit.ect.urebehaveofuart_rist.ypestatesisi:iz_i匚11已,ir_sample_st.art_bit.rr_samp1e_dat.a_ljit.,r_st.□p:i;signalstate:states:=r_iLlle;signalrxd_syn:st.d_lugic;signa1siin_rxdr:st.cl_logic;242526272829cc?.IWS-rIH?cIVV?I7?384041424344454647cns-rC1?X>52beginprol: process(rxdr)--用DFF把數據輸入腳密:形下,防止干擾beginifrxdr='0'thenrxd_syn<='O';elserxd__syn<='1';endif;endprocess;pro2: process(bclkr,resetr,rxd_syn)variablecount:std_logic_vector(3dounto0);variablerent:integerrange0tofrarnlen:=0;variablerbufs:std_logic_vector(7dounto0);beginifresetr='1'thenstate<=r_idle;count:=,r0000,r;rent:=0;r__ready<='O';elsifrising_edge(bclkr)thencasestateis―j檢測是否是起始位whenr_idle=>ifrxd__syn='0'thenstate<=r_samplestart^bit;r_ready<='O'稅:測到起始位后才復位r_readytents:=0.coun^:=-0000--^這兒起始位為。已經有一個時鐘時間了elsestate<=r_idle;endif;5455when「samplestattbit=>--翰測起始位是否夠時間56iftxdsyn=1□1then57ifcount<rr0111rrthen一日個時鐘后/再采樣5Bcount:=count+lj595t:5it.F:-<=usjzUTiplestartbit;60else一起始位正通.寺始采樣數據位615tat&-=::=us:5iiTip1&databit;62count:=p,0000F,;63rent:=□;--開始接收數據位64endif;65else665t.:5l1Z.F:-<=Uidle;67count:=p,0000F,;68endif;6970wtienc_samp1e_data_toit=>712口皿匕<:="1口口「,then--玷個時鉀后再采樣72count:=coLint+l;73state<:=c_samp1e_data_toit;74else75ifrcnt=franilenthen765t.at.e<=r_st.op;77count;=l-,0000l,F;7Brent.:=0;79elseB0st.at.e<=r_samp1e_data_toitjB1count:=l-,0000l,F;B2rtoufs(rent):=rxd_5yn;——移入數據位B3rent:=rcnt+l;B4endif;B5endif;|86whenrstop=> 省略了對停止位的檢惻87rready<='1';—接受數據可讀了88rbuf<=rbufs; 更新輸出數柩89state<=ridle;90when□thers=>91state<=ridle;92endcase;93endif;94endprocess;endbehave;逐行解釋:11:bclk為波特率的16倍。這個同uart_t。12:一幀數據接收完畢信號,可以通知頂層模塊來提取數據。該信號在復位后為“0”,在接收完一幀數據后變高,然后直到下一次檢測到起始位后,即下一幀數據到來時才復位到“0”。頂層模塊可通過檢測該信號的上升沿來判斷一幀數據是否已經接收完畢。19:用type聲明一種枚舉類型,用來表示接收狀態(tài)機的狀態(tài)。共有五狀態(tài):r_idle——空閑狀態(tài),r_sample_start_bit——采樣起始位狀態(tài),r_sample_data_bit 采樣數據位狀態(tài),r_stop----采樣停止位狀態(tài)。24-31:通過一個D觸發(fā)器,先把串口的輸入信號整形一下,這樣可減少干擾引起的檢測誤判。D觸發(fā)器的原理的工作機制大家應該明白吧,這里就不再贅述了。33-35:定義一些變量。count為時鐘bclk的計數器,因為采用了16倍頻的時鐘,所以一個數據位會維持16個bclk時鐘周期,需要用count來計數。rcnt是對接收到的數據位進行計數。這個和串口的發(fā)送程序有點類似的。32-95:通過狀態(tài)機來接收一幀數據。37-41:系統復位。38:復位后狀態(tài)機設置為空閑狀態(tài)。39-40:清零計數器。41:置r_ready為0,表示數據還沒接收完畢。42-93:系統正常工作,通過狀態(tài)機的變化實現一幀數據的接收,用case語句實現狀態(tài)轉變。44-53:描述空閑狀態(tài)時的執(zhí)行動作。45-49:若傳送線上檢測到低電平則立即轉入r_sample_start_bit狀態(tài),并清零計數器。反之,若沒有檢測到低電平,則還是使系統處于r_idle狀態(tài),還需要不斷的去檢測傳送線的狀態(tài)。55-68:描述采樣到起始位后執(zhí)行的動作。68:假設在44-53句中檢測到的低電平是起始位,則這個低電平應該持續(xù)16個時鐘(因為是16倍頻采樣的)。在這16個時鐘周期內,若是干擾,則可能會在這16個時鐘的時間內檢測到高電平。若有,那么狀態(tài)機就回到x_idle狀態(tài),否則就認為已經檢測到了起始位。64:在檢測到起始位后的8個時鐘里總線若一直是低電平,則認為是檢測到了起始位,狀態(tài)機切換至r_sample_data_bit,并初始化一些計數器,準備開始采樣數據位。70-85:描述采樣數據位時執(zhí)行的動作。71-73:連續(xù)計數16個bclk時鐘85:當計數到16個阮蟲后,就開始采樣傳送線的電平狀態(tài)。78:在檢測傳送線數據前首先判斷是否已經接收完數據位,若是就使狀態(tài)機轉Ar_stop狀態(tài),并清零計數器。79-83:若數據位還沒有接收完畢,貝IJ80句,保持狀態(tài)機處于r_sample_data_bit狀態(tài),并清零count。82句,把當前傳送線的電平狀態(tài)送入到接收緩沖器rbufs,并通過83句將接收到的數據位計數器加1。86-89:描述采樣停止位時執(zhí)行的動作。在本程序中,我們省略了對停止位的采樣,這樣做對功能本身不會產生影響。87:置r_ready為1,通知外部數據接收完畢88:更新數據輸出緩沖器89:使狀態(tài)機重新會到x_idle狀態(tài),開始下一輪的接收檢測。90-91:描述狀態(tài)機處于其它狀態(tài)時的動作(假如狀態(tài)機跑飛)。在其它狀態(tài)時,將狀態(tài)機置為x_idle,使狀態(tài)機正常工作。以上只是編寫了一個串口接收的元件,現在編寫一個頂層調用模塊,調用這個接收元件來接收^^機上通過“串口調試助手”發(fā)送的數據,并根據接收到的數據點亮不同的LED。代碼如下:--頂層文件,倜用uart._r.vhd^gen_div.vhd文件1itoraryiⅇuseieee.std_logic_Ll64.all;■useieee.std_logic_arith.all;useieee.stdlogicunsigned.all;TOC\o"1-5"\h\z6 — —entitytopisport9 (cIkiiL^reset:instd_logic;--clkin=110IIrxd:instd_Log-ic;--串行榆入數據led:out5td_lQgic_vector(2downto0)--ledKSJ13 — —);endtop;16architectu.rebehaveoftoplbcoinponentgen_divis--分頻元件調用聲明generic(div_parain:integer:=130);--EE□分頻的'產生16*9600的時鐘port-21telk:instdLog'ic;beIk:outstd_logicjresetlo:inBt-d._logic);一endconiponent;27eoitiponentuart_ris--串口接收元件調用聲明port(tocllrrrresetrwdr:instd_logic:r_ready:outstd_logie;rbuf:outstdlogicvector(7downto0)34 ): 一一endeoitiponerLt;36 signalclk_u:std_logic;--1&倍的波特率時■鐘signaluevbuf:stdlogicvector(7downto□“——揍收數據緩沖區(qū)signaluevueady:stdlogic;——一幀數據揍收完畢標恙40 begii^uautbaud:gen_divpoutmap--分頻元件例化t_clk=>clkinruesetb=>uesetrbclk=>clku);—49 uaut_ueceive:--串口接收元件例化uautupoutrnapi:—bclku=>clk_u|I-ue3etu=>ue3etruxdu=>uxdir

56rread7=>trevtreads.57rbuf=>tevbut58):cq60OJL62accept_data:--根據摻收到的數據做動作63process(revready,,reset,,uevbut,,elkuj64begin65ifreset=111then——復位時■全滅661己日亡二社口口口1■七67eIse68ifrevre

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論