《微控制器原理及應用技術》課件第8章_第1頁
《微控制器原理及應用技術》課件第8章_第2頁
《微控制器原理及應用技術》課件第8章_第3頁
《微控制器原理及應用技術》課件第8章_第4頁
《微控制器原理及應用技術》課件第8章_第5頁
已閱讀5頁,還剩156頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第8章基于MCS51的典型串行總線設計8.1概述

8.2RS485總線

8.3SPI總線8.4I2C總線教學提示:單片機應用系統(tǒng)涉及到外部設備的接口與擴展。早期單片機系統(tǒng)大都采用并行總線結構,隨著電子和計算機技術的發(fā)展,出現(xiàn)了很多新型的串行數(shù)據(jù)傳輸總線。相應地,許多新型外圍器件都支持這些總線接口。串行總線接口靈活,占用單片機資源少,系統(tǒng)結構簡化,極易形成用戶的模塊化結構?,F(xiàn)代單片機應用系統(tǒng)廣泛采用串行總線接口技術。

教學要求:本章主要介紹SPI、I2C總線和RS485的工作原理,重點掌握利用MCS51單片機和相關接口芯片實現(xiàn)SPI、I2C和RS485總線的硬件電路設計和軟件設計方法。

微型計算機、單片機系統(tǒng)大都采用總線結構。這種結構是采用一組公共的信號線作為微型計算機各部件之間的通信線,這組公共信號線就稱為總線。單片機的常用總線有并行總線與串行總線。8.1概述早期的單片機著力于將CPU與外圍功能單元的集成,完善并行三總線結構,以滿足應用系統(tǒng)的構成與擴展。隨著單片機技術的發(fā)展,越來越多的采用串行外設接口技術。串行外設接線靈活,系統(tǒng)結構簡單,極易形成用戶的模塊化結構,對于縮短產品開發(fā)周期,增加硬件構成的靈活性,具有重要的意義。

串行總線可以顯著減少引腳數(shù)量,簡化系統(tǒng)結構。隨著外圍器件串行接口的發(fā)展,單片機串行接口的普遍化和高速化使得并行擴展接口技術日漸衰退,推出了刪去并行總線的非總線單片微機,需要外擴器件(存儲器、I/O等)時,采用串行擴展總線,甚至用軟件虛擬串行總線來實現(xiàn)。

各大半導體公司生產的四線SPI接口、三線Microwire接口、二線I2C和一線1Wire等接口芯片充滿了電子市場。這些接口主要完成單片機系統(tǒng)內部的設備連接,主要用于系統(tǒng)內芯片之間的數(shù)據(jù)傳輸;還有一些串行總線技術如RS232、CAN、RS485,主要完成微機系統(tǒng)之間的連接,稱為外部串行總線,它們是系統(tǒng)之間的通信用總線。本章主要介紹SPI、I2C和RS485總線的原理。

通用的微處理器都集成有1路或多路硬件UART通道,可以非常方便地實現(xiàn)串行通信。在工業(yè)控制、電力通訊、智能儀表等領域中,也常常使用簡便易用的串行通訊方式作為數(shù)據(jù)交換的手段。8.2RS485總線但是,在工業(yè)控制等環(huán)境中,常會有電氣噪聲干擾傳輸線路,使用RS232通信時經常因外界的電氣干擾而導致信號傳輸錯誤;另外,RS232通信的最大傳輸距離在不增加緩沖器的情況下只可以達到15米。為了解決上述問題,RS485通信方式就應運而生了。8.2.1RS485電氣特性

電子工業(yè)協(xié)會(EIA)于1983年制訂并發(fā)布RS485標準,并經通訊工業(yè)協(xié)會(TIA)修訂后命名為TIA/EIA485A,習慣地稱之為RS485標準。RS485標準是為彌補RS232通信距離短、速率低等缺點而產生的。RS485標準只規(guī)定了平衡發(fā)送器和接收器的電特性,而沒有規(guī)定接插件、傳輸電纜和應用層通信協(xié)議。RS485標準與RS232不一樣,其數(shù)據(jù)信號采用差分傳輸方式(DifferentialDriverMode),也稱為平衡傳輸,它使用一對雙絞線,將其中一線定義為A,另一線定義為B,如圖8.1所示。

圖8.1RS485發(fā)送器的示意圖通常情況下,發(fā)送發(fā)送器A、B之間的正電平在+2~+6V范圍內,是一個邏輯狀態(tài);負電平在-2~-6V范圍內,是另一個邏輯狀態(tài)。另有一個信號地C。在RS485器件中,一般還有一個“使能”控制信號?!笆鼓堋毙盘栍糜诳刂瓢l(fā)送發(fā)送器與傳輸線的切斷與連接。當“使能”端起作用時,發(fā)送發(fā)送器處于高阻狀態(tài),稱為“第三態(tài)”,它是有別于邏輯“1”與“0”的第三種狀態(tài)。

對于接收發(fā)送器,也作出與發(fā)送發(fā)送器相對的規(guī)定,收、發(fā)端通過平衡雙絞線將AA與BB對應相連。當在接收端AB之間有大于+200mV的電平時,輸出為正邏輯電平;小于-200mV時,輸出為負邏輯電平。在接收發(fā)送器的接收平衡線上,電平范圍通常在200mV~6V之間,參見圖8.2所示。

圖8.2RS485接收器的示意圖定義邏輯1(正邏輯電平)為B>A的狀態(tài),邏輯0(負邏輯電平)為A>B的狀態(tài),A、B之間的壓差不小于200mV。TIA/EIA485串行通信標準的性能如表8.1所示。表8.1TIA/EIA485串行通信標準的性能

RS485標準的最大傳輸距離約為1219米,最大傳輸速率為10Mb/s。通常,RS485網絡采用平衡雙絞線作為傳輸媒體。平衡雙絞線的長度與傳輸速率成反比,只有在20kb/s速率以下,才可能使用規(guī)定最長的電纜長度。只有在很短的距離下才能獲得最高速率傳輸。一般來說,15米長雙絞線的最大傳輸速率僅為1Mb/s。這里需要注意的是,并不是所有的RS485收發(fā)器都能夠支持高達10Mb/s的通信速率。如果采用光電隔離方式,則通信速率一般還會受到光電隔離器件響應速度的限制。RS485網絡采用直線拓樸結構,需要安裝2個終端匹配電阻,其阻值要求等于傳輸電纜的特性阻抗(一般取值為120Ω)。在短距離或低波特率波數(shù)據(jù)傳輸時可不需終端匹配電阻,即一般在300m、19200b/s以下不需終端匹配電阻。終端匹配電阻安裝在RS485傳輸網絡的兩個端點,并聯(lián)連接在AB引腳之間。

RS485標準通常被用作為一種相對經濟、具有相當高噪聲抑制、相對高的傳輸速率、傳輸距離遠、寬共模范圍的通信平臺。同時,RS485電路具有控制方便、成本低廉等優(yōu)點。在過去的20年時間里,建議性標準RS485作為一種多點差分數(shù)據(jù)傳輸?shù)碾姎庖?guī)范,被應用在許多不同的領域,作為數(shù)據(jù)傳輸鏈路。目前,在我國應用的現(xiàn)場網絡中,RS485半雙工異步通信總線也是被各個研發(fā)機構廣泛使用的數(shù)據(jù)通信總線。但是基于在RS485總線上任一時刻只能存在一個主機的特點,它往往應用在集中控制樞紐與分散控制單元之間。8.2.2RS485總線節(jié)點數(shù)和通信方式

1.節(jié)點數(shù)

所謂節(jié)點數(shù),即每個RS485接口芯片的驅動器能驅動多少個標準RS485負載。根據(jù)規(guī)定,標準RS485接口的輸入阻抗大于等于12kΩ,相應的標準驅動節(jié)點數(shù)為32。為適應更多節(jié)點的通信場合,有些芯片的輸入阻抗設計成1/2負載(≥24kΩ)、1/4負載(≥48kΩ),甚至1/8負載(≥96kΩ),相應的節(jié)點數(shù)可增加到64、128和256。表8.2為一些常見芯片的節(jié)點數(shù)。表8.2常見芯片的節(jié)點數(shù)

2.通信方式

RS485總線接口可連接成半雙工和全雙工兩種通信方式,分別如圖8.3和圖8.4所示。半雙工通信的芯片有SN75176、SN75276、SN75LBC184、MAX485、MAX1487、MAX3082、MAX1483等;全雙工通信的芯片有SN75179、SN75180、MAX488~MAX491、MAX1482等。

圖8.3RS485總線的半雙工通信

圖8.4RS485總線的全雙工通信8.2.3RS485總線收發(fā)器與單片機接口電路的設計

當單片機系統(tǒng)使用RS485串行總線進行多機通信時,首先必須將單片機的串行口和RS485總線收發(fā)器相連。為了提高整個RS485串行總線網絡的可靠性,每個通信節(jié)點中單片機和收發(fā)器以及總線的接口電路都需要仔細設計。圖8.5為一個帶有總線保護的光電隔離的RS485通信節(jié)點的接口電路。

圖8.5RS485應用典型電路在圖8.5所示的電路中,RS485的A、B引腳分別進行上拉和下拉,以確保即使節(jié)點未連到總線上。A、B引腳上的電壓差仍能使RO輸出為高,避免因總線上的干擾信號引起單片機串行口的誤接收。電路中R4和R5為保護電阻,其作用是隔離本節(jié)點的A、B引腳和總線,這樣即使本節(jié)點的A、B引腳對地擊穿,也不會因此拉低總線,影響其他節(jié)點的通信。R2為匹配電阻,用于匹配線路阻抗,吸收反射信號。由于該電阻接入總線將引起驅動器功耗增加,一般只有當總線較長或者環(huán)境中干擾較強時使用,否則可以不接。P1.0為芯片控制信號,用來控制半雙工通信中數(shù)據(jù)的收發(fā)方向。為了防止節(jié)點和總線之間的干擾,RS485與單片機之間則采用了光電隔離驅動方式,且單片機和RS485之間的電源也需要進行隔離。具體的供電隔離措施應根據(jù)環(huán)境合理選擇。例如,當應用環(huán)境的干擾非常強時,可選擇兩組相互獨立的電源對單片機和總線收發(fā)器部分供電;如果環(huán)境干擾不是很強時,可將單片機系統(tǒng)供電串接一個電感后給收發(fā)器供電,接地部分可以同樣處理。另外,當多個節(jié)點接入RS485總線時,這些節(jié)點的收發(fā)器的地線應該連接在一起,以避免節(jié)點之間的共模電壓過大導致收發(fā)器工作不穩(wěn)定甚至損壞。如果工作環(huán)境非常惡劣,例如戶外應用場合,應考慮在A、B線之間增加浪涌保護器件,并將器件更換為具有抗雷擊功能的器件,如SN75176。

在上述電路中,單片機復位后,P1.0為高電平,相應的光耦不導通,RE/DE引腳保持為低,處于數(shù)據(jù)接收狀態(tài),不會對總線上其他節(jié)點的通信造成影響。RO端輸出的數(shù)據(jù)通過光耦輸入到單片機的RXD引腳。當節(jié)點需要發(fā)送數(shù)據(jù)時,首先置P1.0為低電平,相應的光耦為高電平,此時TXD端口出現(xiàn)數(shù)據(jù)通過光耦輸入DI,驅動總線發(fā)送數(shù)據(jù)。

當串行口通信速率不是很高時,上述電路中的P1.0可以直接用TXD取代,這樣發(fā)送數(shù)據(jù)時,就不必先控制P1.0=0,簡化了控制流程。這種控制方式下串行口的最高通信速率和光耦的導通延遲時間有關,常見的光耦如TLP521、4N25和PC817等,導通延遲時間一般在幾微秒,能可靠地應用于9600b/s以下的串行通信場合。如果需要進行更高速率的串行通信則可選擇導通延遲時間更小的光耦,如6N137等。當RS485總線連接的多個節(jié)點之間距離很近,干擾也小,例如安裝在一個機箱之內,這時可以不用光耦進行隔離,直接將單片機的TXD接DI、RXD接DO,通信方向控制端口接RE/DE即可。也可用TXD控制RE/DE,但此時需先將TXD反相后再連接到RE/DE端。下面以基于單片機AT89C52的RS485總線現(xiàn)場監(jiān)測系統(tǒng)為例來學習RS485總線的工作原理。8.2.4基于單片機節(jié)點的RS485總線的工作原理

1)MAX485介紹

MAX485接口芯片是MAXIM公司的一種RS485芯片,采用單一電源+5V工作,額定電流為300μA,采用半雙工通訊方式。其引腳結構圖如圖8.6所示。從圖中可以看出,MAX485芯片的結構和引腳都非常簡單,

圖8.6MAX485芯片管腳圖內部含有一個驅動器和接收器。RO和DI端分別為接收器的輸出和驅動器的輸入端,與單片機連接時只需分別與單片機的RXD和TXD相連即可;RE和DE端分別為接收和發(fā)送的使能端,當RE為邏輯0時,器件處于接收狀態(tài);當DE為邏輯1時,器件處于發(fā)送狀態(tài),因為MAX485工作在半雙工狀態(tài),所以只需用單片機的一個管腳控制這兩個引腳即可;A端和B端分別為接收和發(fā)送的差分信號端,當A引腳的電平高于B時,代表發(fā)送的數(shù)據(jù)為1;當A的電平低于B端時,代表發(fā)送的數(shù)據(jù)為0。在與單片機連接時接線非常簡單,只需要一個信號控制MAX485的接收和發(fā)送即可,同時在A和B端之間加匹配電阻,一般可選120Ω的電阻。表8.3為MAX485引腳功能說明。表8.3MAX485引腳功能說明

2)單片機多機串行通信系統(tǒng)控制位

單片機采用串行通信來組成多機通信。當串行口工作在方式2或方式3接收數(shù)據(jù)時,串行口控制器SCON中的SM2位可以作為多機通信控制位。當SM2=1時,單片機串行口從串行總線上接收一個字節(jié)數(shù)據(jù)后,只有當緊接該字節(jié)的第9位數(shù)據(jù)RB8為1時,該數(shù)據(jù)字節(jié)才會被裝入SBUF,并置RI為1,表明接收數(shù)據(jù)有效,向CPU申請中斷。如果接收到的第9位數(shù)據(jù)為0,則認為該數(shù)據(jù)無效,不置位RI,CPU也不會做任何處理。當SM2=0時,單片機的串行口在接收到一個字節(jié)的數(shù)據(jù)后,不管緊隨其后的第9位數(shù)據(jù)RB8是0還是1,均將該字節(jié)裝入SBUF中,并置RI為1,表明接收數(shù)據(jù)有效,向CPU申請中斷。利用單片機的上述特性就可以采用RS485總線技術組成網絡實現(xiàn)主從式多機通信。

3)RS485通信網絡構成和原理

在采用RS485組成的多機通信網絡系統(tǒng)中,假設各個單片機都是通過如圖8.5所示接口電路接入網絡,每個單片機輸出的數(shù)據(jù)都可以被除該單片機之外的其他單片機收到。每個單片機都有一個唯一的地址,用于主機對其尋址。各從機上電后都將其串行口初始化為9位異步通信接口方式(方式2或者方式3),并置多機通信位SM2為1,同時允許接收串行數(shù)據(jù)和允許串行口中斷。

通信是由主機發(fā)起。當主機需要和某個從機通信時,首先發(fā)出尋址命令,當從機響應命令并給出回復后才能進行正式的通信(見圖8.7),具體通信過程描述如下。圖8.7MAX485實現(xiàn)的半雙工485總線現(xiàn)場監(jiān)測系統(tǒng)

(1)主機首先發(fā)出尋址命令,通知從機準備進行通信時,主機設置串行口的第9位數(shù)據(jù)TB8為1,發(fā)送的字節(jié)為被尋址的從機地址。由于各從機收到RB8為1,且SM2也為1,故所有從機在接收到這幀信息后,都會置中斷標志RI為1,CPU響應中斷接收該地址字節(jié)。

(2)各從機判斷接收的地址字節(jié)是否與本機地址一致。若和本機地址相符,則將本機的SM2置0,做好接收數(shù)據(jù)的準備,如果需要,可按通信協(xié)議回答主機“從機已做好通信準備”;若地址不符合,則從機保持SM2為1,繼續(xù)等待地址字節(jié),不與主機進行通信。

(3)主機發(fā)送完地址幀后或當主機收到一個從機(只能是一個)的回答后,就可以根據(jù)通信協(xié)議向從機發(fā)送命令、數(shù)據(jù)。主機發(fā)送完畢后,如果需要采集從機的數(shù)據(jù),從機可根據(jù)通信協(xié)議再向主機回送數(shù)據(jù)、狀態(tài)和應答信息等。在通信過程中,主機發(fā)送的數(shù)據(jù)幀中第9位數(shù)據(jù)TB8為0,各從機收到的RB8也都為0。由于只有一個被尋址的從機SM2為0(其他從機的SM2都為1),所以只有剛才被尋址的的從機才會收到主機后續(xù)的命令和數(shù)據(jù),并置標志RI為1,通知CPU對接收到的數(shù)據(jù)進行處理。其他的從機由于SM2保持為1,所接收的數(shù)據(jù)幀無效,對主機的通信命令或數(shù)據(jù)不會做任何反應。這樣便實現(xiàn)主機和從機之間的一對一通信。當一次通信結束以后,從機的SM2再次設置為1,主機可以發(fā)送新的尋址幀,開始新的一次通信。由于是半雙工通信,所以主機發(fā)送與接收需要分開獨立運行,從機也是如此。A腳既是接收器的非反向輸入端也是驅動器的非反向輸出端,B腳既是接收器的反向輸入端也是驅動器的反向輸出端,DE和RE引腳電平共同控制發(fā)送和接收的切換。這在后面的硬件、軟件設計中均有體現(xiàn)。

4)基于RS485的單片機主從多機通信系統(tǒng)

圖8.8所示的是基于RS485總線的多機通信,由1個主機和8個從機通過RS485總線連接在一起。主從機之間為半雙工通信,由主機負責發(fā)起和管理通信過程。主機和從機都使用P3.4的反相信號控制MAX485的收發(fā)。通信協(xié)議為:主機輪流和各從機通信,主機首先發(fā)送一個字節(jié)的地址碼來尋址從機,然后緊接著發(fā)送16字節(jié)的控制數(shù)據(jù)包。通信系統(tǒng)的幀結構如表8.4所示。

圖8.8RS485總線通信電路圖表8.4通信系統(tǒng)的幀結構其中,校驗和為發(fā)送機地址字段和控制數(shù)據(jù)字段按字節(jié)計算的累加和,不計進位。主機的控制數(shù)據(jù)包發(fā)送完成后,被尋址的從機再向主機發(fā)送16字節(jié)的采集數(shù)據(jù)包,其結構和控制數(shù)據(jù)包一致。至此,一次通信過程結束。不考慮數(shù)據(jù)的具體內容及數(shù)據(jù)組織的過程,使用C51編寫程序實現(xiàn)上述通信協(xié)議。設主機地址為0x0F,從機地址為0xF0~0xF7,所有單片機的晶振頻率均設為11.0592MHz,串行口設置為9600b/s,8位數(shù)據(jù)位,1停止位,無校驗,收發(fā)均為中斷方式。主機和從機的程序流程圖如圖8.9和圖8.10所示。根據(jù)通信協(xié)議,在主機和從機的程序中都涉及由多個字節(jié)構成的數(shù)據(jù)包的收發(fā)。而且為了提高程序的處理效率,收發(fā)都采用中斷方式進行,因此在主程序和中斷服務程序之間就需要有一種同步的機制來協(xié)調數(shù)據(jù)收發(fā)的過程。

圖8.9主機程序流程圖

圖8.10從機程序流程圖以主機程序代碼為例,按協(xié)議的要求,主機首先要發(fā)送地址幀,使被尋址的從機從等待地址幀的狀態(tài)轉換到接收數(shù)據(jù)的狀態(tài)。緊接著主機需要發(fā)送16字節(jié)的控制數(shù)據(jù)包給被尋址從機,這16個字節(jié)的發(fā)送都是通過串行口中斷服務程序完成的??刂茢?shù)據(jù)包發(fā)完后,主機要馬上轉入接收狀態(tài),接收該從機發(fā)回的16字節(jié)的數(shù)據(jù)采集信息包,這些數(shù)據(jù)的接收也要在串行口中斷服務程序中完成。根據(jù)對通信過程的分析,從流程圖可以看出,主機中的主程序只負責尋址字節(jié)的發(fā)送,控制數(shù)據(jù)包什么時候發(fā)送完畢是由串行口中斷服務程序判斷的,沒有發(fā)送完控制數(shù)據(jù)包,就不能接收從機的數(shù)據(jù)采集信息包。為了達到此目的,主機程序中設置了一個全局變量SendOK,用于主程序和串行口之間針對是否發(fā)送完控制數(shù)據(jù)包的同步。主程序在發(fā)送尋址幀前,置SendOK=0,表示控制數(shù)據(jù)包沒發(fā)完,然后主程序循環(huán)判斷SendOK是否為1,不為1表示數(shù)據(jù)沒發(fā)完,主程序一直等待;串行口中斷服務程序則在發(fā)生發(fā)送中斷時執(zhí)行,每次發(fā)送一個字節(jié)。如果在某次執(zhí)行時發(fā)現(xiàn)已經完成控制數(shù)據(jù)包16字節(jié)的發(fā)送,則置SendOK=1,表示已發(fā)完。接收過程也使用了同樣的機制在主程序和串行口中斷服務程序之間進行同步。下面是采用上述協(xié)議的主機和從機的代碼。****************************************

Host.c

****************************************

#include<reg51.h>

//用宏定義設置系統(tǒng)常數(shù),以方便統(tǒng)一修改

#defineHSTADDR0x0f

#defineSLVADDR0xf0

#defineSLVCNT8

#defineBUFSIZE16

#defineOSC

#defineBAUDRATE9600

//定義接收、發(fā)送緩沖區(qū)以及它們的操作指針、操作完成狀態(tài)位。它們是全局變量,本文件

//所有函數(shù)都可以訪問。一般程序中用于控制各函數(shù)協(xié)同工作的同步標識等都使用全局變量

unsingnedcharSendBuf[BUFSIZE],Recvbuf[BUFSIZE];

unsingnedcharSPtr,RPtr;

bitSendOK,RecvOK;

voidComISR(void)interrupt4//單片機串行口中斷服務程序

{

if(TI)//如果數(shù)據(jù)發(fā)送中斷

{

TI=0;//首先清發(fā)送中斷標志位

if(!SendOK)//如果數(shù)據(jù)幀沒發(fā)送中斷

{

TB=0;//發(fā)送的是數(shù)據(jù)幀,因此將TB8置0

SBUF=SendBuf[SPtr++];//取一個字節(jié)發(fā)送

if(SPtr>=BUFSIZE)//如果讀指針已指向緩沖區(qū)尾,說明數(shù)據(jù)發(fā)送完

SendOK=1;//置發(fā)送完標志為1

}

elseSendOK=0;//執(zhí)行到此,說明本次中斷是最后一個發(fā)送字節(jié)引

//發(fā)的,直接將數(shù)據(jù)發(fā)送完標志清0即可

}

if(RI)//如果數(shù)據(jù)接收中斷

{

RI=0;//首先清接收中斷標志位

RecvBuf[RPtr++]=SBUF;//讀接收的數(shù)據(jù)放入接收數(shù)據(jù)緩沖區(qū)

if(RPtr>=16)//如讀指針數(shù)據(jù)已指向緩沖區(qū)尾,說明數(shù)據(jù)收完

RecvOK=1;//置接收完標志為1

}

}

voidmian(void)

{

unsignedcharSlaveAddr,SlaveCount,i,CheckSum;

TMOD=0x20;

//T1模式2,波特率發(fā)生器

TL1=256-(OSC/12/16/BAUDRATE);

TH1=256-(OSC/12/16/BAUDRATE);

TR1=1;

SCON=0xd8;

//串口方式3,REN=1,TB8=1,發(fā)地址模式

PCON|=0x80;

//SMOD=1

ES=1;

EA=1;//允許串行口中斷并開總中斷

SlaveAddr=SLVADDR;//設置首先被尋址的從機地址

SlaveCount=0;

while(1)

{

//假設發(fā)送數(shù)據(jù)報已準備好,下面設置發(fā)送機地址,并計算校驗和,填入數(shù)據(jù)包中

SendBuf[0]=HSTADDR;

for(i=1;i<(BUFSIZE-1);i++)SendBuf[i]=0x41+i-1;

CheckSum=0;

for(i=1;i<(BUFSIZE-1);i++)CheckSum+=SendBuf[i];

SendBuf[BUFSIZE-1]=CheckSum;//構造一個模擬的數(shù)據(jù)包用于程序調試

SendOK=0;//置發(fā)送完標志為無效

SPtr=0;//置發(fā)送緩沖區(qū)讀指針為0,指向第一個數(shù)據(jù)

TB8=1;//因為主機要首先發(fā)送地址幀,因此置TB8=1

P34=0;//驅動主機的MAX485處于發(fā)送狀態(tài)

SBUF=(SlaveAddr+SlaveCount);//發(fā)送當前被訪問的從機地址

while(!SendOK);//地址幀發(fā)完后,主機將在單片機串行口中斷調

//度下發(fā)完整個數(shù)據(jù)包,主程序等待發(fā)完標志

RecvOK=0;//準備接受從機數(shù)據(jù)報,先置接收完標志為0

RPcvOK=0;//置接收緩沖區(qū)寫指令為0,指向第一個位置

SM2=0;`//僅采集從機數(shù)據(jù),因此置多機通信為0

P34=1;//將主機RS485驅動為接收方式

while(!RecvOK);//數(shù)據(jù)的接收在中斷服務程序中完成,主程序只需

//要等待其置接收完標志為有效即可

/*…*///此處省略“處理接收到的數(shù)據(jù)”的過程

SlaveCount++;//計算下一個從機地址,循環(huán)訪問8個從機

if(SlaveCount==SLVCNT)SlaveCount=0;

}

}****************************************

Slave.c

****************************************

#include<reg51.h>

//用宏定義設置系統(tǒng)常數(shù),以方便統(tǒng)一修改

#defineHSTADDR0x0f

#defineSLVADDR0xf0

#defineSLVCNT8

#defineBUFSIZE16

#defineOSC

#defineBAUDRATE9600

//定義接收、發(fā)送緩沖區(qū)以及它們的操作指針、操作完成狀態(tài)位。它們是全局變量,本文件

//所有函數(shù)都可以訪問。一般程序中用于控制各函數(shù)協(xié)同工作的同步標識等都使用全局變量

unsingnedcharSendBuf[BUFSIZE],Recvbuf[BUFSIZE];

unsingnedcharSPtr,RPtr;

unsingnedcharRecvAddr;

bitSendOK,RecvOK;

voidComISR(void)interrupt4//單片機串行口中斷服務程序

{

if(TI)//如果數(shù)據(jù)發(fā)送中斷

{

TI=0;//首先清發(fā)送中斷標志位

if(!SendOK)//如果數(shù)據(jù)幀沒發(fā)送中斷

{

SBUF=SendBuf[SPtr++];//從緩沖區(qū)取一個字節(jié)發(fā)送

if(SPtr>=BUFSIZE)

SendOK=1;//如果數(shù)據(jù)已發(fā)生完,置發(fā)送完標志為1

}

}

if(RI)//如果數(shù)據(jù)接收中斷

{

RI=0;//首先清接收中斷標志位

if(RB8)//判斷當前是否處于接收地址狀態(tài)

{

RecvAddr=SBUF;//如果是,則該中斷是由主機發(fā)送地址幀引起

if(RecvAddr==SLVADDR)//判斷主機是否尋址本機

SM2=0;//是尋址本機,置多機通信位無效,準備收數(shù)據(jù)

}

}

else//如果RB8無效,則中斷是由主機發(fā)數(shù)據(jù)引起

{

RecBuf[RPtr++]=SBUF;//收串口數(shù)據(jù),存入接收緩沖區(qū)

if(RPtr>=BUFSIZE)//如果接收緩沖區(qū)已滿,置接收完標志為1

RecvOK=1;

}

}

voidmian(void)

{

unsignedchari,CheckSum;

TMOD=0x20;//T1模式2,波特率發(fā)生器

SCON=0xF0;//串口方式3,SM2=1,REN=1,準備收地址

PCON|=0x80;

TL1=256-(OSC/12/16/BAUDRATE);

TH1=256-(OSC/12/16/BAUDRATE);

TR1=1;

ES=1;

EA=1;//允許串行口中斷并開總中斷

while(1)

{

SM2=1;//從機首先置多機通信控制位有效

P34=1;//驅動MAX485處于接收狀態(tài),準備收地址

RecvOK=0;//接收完狀態(tài)無效

RPtr=0;//清空接收緩沖區(qū)

while(!RecvOK);//等待主機完成發(fā)送地址+數(shù)據(jù)的過程

/*…*///此處省略“處理接收到的數(shù)據(jù)”的過程

/*…*///此處省略“準備待發(fā)送數(shù)據(jù)”的過程

TB8=0;//從機接收完主機數(shù)據(jù)后開始發(fā)送數(shù)據(jù)

P34=0;//驅動MAX485處于發(fā)送狀態(tài)

SendBuf[0]=SLVADDR;//模擬發(fā)送主機的數(shù)據(jù)采集/控制包供調試

for(i=1;i<15;i++)SendBuf[i]=0x61+i-1;

CheckSum=0;

for(i=0;i<15;i++)CheckSum+=SendBuf[i];

SendBuf[15]=CheckSum;

//裝配數(shù)據(jù)并計算校驗和

SendOK=0;

//發(fā)送完標志無效

SPtr=0;//發(fā)送指針指向第一個字節(jié)

TI=1;//置TI=1,跳轉到中斷服務程序

while(!SendOK);//數(shù)據(jù)報由中斷服務程序調度發(fā)送

//等發(fā)送完標志有效后,再等待下一次被尋址

}

}

串行外設接口(SerialPeripheralInterface,SPI)是Motorola公司提出的一種全雙工同步串行外設接口,允許單片機等微控制器與各種外部設備以同步串行方式進行信息交換。由于SPI總線一共只需3~4條數(shù)據(jù)線和控制線即可實現(xiàn)與具有SPI總線功能的各種I/O器件進行連接,8.3SPI總線而擴展并行總線則需要8條數(shù)據(jù)線、8~16條地址線、2~3條控制線,因此采用SPI總線接口可以簡化整個電路的設計,節(jié)省更多常規(guī)電路中的接口器件和I/O口線,并提高了系統(tǒng)的可靠性。8.3.1SPI總線的工作原理

Motorola公司生產的絕大多數(shù)微控制器(MCU)都配有SPI硬件接口。SPI用于CPU與各種外圍設備器件進行全雙工同步串行通信。這些外圍器件可以是簡單的TTL移位寄存器、復雜的LCD顯示驅動器、A/D、D/A轉換子系統(tǒng)或其他的MCU。SPI只需4條線就可以完成MCU與各種外圍器件的通信,這4條線是:串行時鐘線(SCK)、主機輸入/從機輸出數(shù)據(jù)線(MISO)、主機輸出/從機輸入數(shù)據(jù)線(MOSI)、低電平有效從機選擇線(CS)。在大多數(shù)場合,使用1個MCU作為主控制器,以控制與一個或多個外圍器件進行數(shù)據(jù)的傳輸與交換。SPI總線系統(tǒng)的典型結構如圖8.11所示,該系統(tǒng)由一個主機、n個外圍設備和一個作為從機的控制器組成。線路連接的特點:主控制器與外圍設備的同名端相連,串行時鐘SCLK用于同步SPI總線的MOSI和MISO傳輸信號,每個外圍設備或從控制器都有片選信號,主控制器通過譯碼器來分時選通外圍設備。系統(tǒng)中存在多個控制器時,應明確其主從地位,在某一時刻只能有一個控制器為主機,其他均為從機。SPI工作時,主機的移位寄存器中的數(shù)據(jù)逐位從輸出引腳(MOSI)輸出(高位在前),同時從輸入引腳(MISO)接收的數(shù)據(jù)逐位移到移位寄存器(高位在前)。完成一個字節(jié)發(fā)送后,通過片選信號,可以從另一個外圍設備接收的字節(jié)數(shù)據(jù)進入移位寄存器中。

圖8.11SPI總線系統(tǒng)的典型結構框圖

SPI總線的主要特點:

①全雙工三線同步傳送;

②可設置為主機或從機工作方式;

③可控制串行時鐘的相位和極性;

④具有結束發(fā)送中斷標志和寫沖突保護標志;

⑤主機方式時,通信速率可以由編程設置為4種,最高可達1.05Mb/s;從機方式時,通信速率由串行通信時鐘(SCLK)決定,最高可達2.1Mb/s;

⑥有多主機方式出錯保護,防止多個MCU同時成為串行總線的主機;⑦可方便地與各種串行擴展器件接口;

⑧對于沒有SPI接口的微處理器,可以用通用的I/O口,用軟件模擬實現(xiàn)SPI接口。8.3.2SPI總線的通信時序

SPI串行數(shù)據(jù)通信接口可以配置為四種不同的工作模式(SPI0,SPI1,SPI2,SPI3),如表8.5所示。表中CPHA用來表示同步時鐘信號的相位,CPOL表示同步時鐘信號的極性。圖8.12為SPI總線工作的4種模式下SCLK波形示意圖,其中使用的最為廣泛的是SPI0和SPI3方式(實線表示)。表8.5SPI串行通信接口工作模式

圖8.12SPI總線工作的4種模式時鐘極性(CPOL)對傳輸協(xié)議沒有重大的影響。如果CPOL=0,串行同步時鐘的空閑狀態(tài)為低電平;如果CPOL=1,串行同步時鐘的空閑狀態(tài)為高電平。時鐘相位(CPHA)能夠配置用于選擇兩種不同的傳輸協(xié)議之一進行數(shù)據(jù)傳輸。如果CPHA=0,在串行同步時鐘的第一個跳變沿(上升或下降)數(shù)據(jù)被采樣;如果CPHA=1,在串行同步時鐘的第二個跳變沿(上升或下降)數(shù)據(jù)被采樣。SPI主模塊和與之通信的外設時鐘相位和極性應該一致。SPI總線4種模式的接口時序如圖8.13、圖8.14、圖8.15和圖8.16所示。

圖8.13SPI總線數(shù)據(jù)傳輸時序圖(SPI0)

圖8.14SPI總線數(shù)據(jù)傳輸時序圖(SPI1)

圖8.15SPI總線數(shù)據(jù)傳輸時序圖(SPI2)

圖8.16SPI總線數(shù)據(jù)傳輸時序圖(SPI3)對于沒有SPI接口的單片機來說,可使用軟件來模擬SPI的操作,包括串行時鐘、數(shù)據(jù)輸入和輸出,用I/O口線模擬SPI串口通信的方法。8.3.3硬件電路設計

MC14489是Motorola公司生產的5位7段LED譯碼驅動芯片,能直接驅動LED數(shù)據(jù)顯示器。使用一個外接電阻RX即可控制每一段的輸出電流,有三線串行接口(SPI),可直接與具有SPI接口的CPU相連,也可通過軟件模擬與沒有SPI接口的CPU配合工作。

1.工作原理

MC14489芯片由24位輸入移位寄存器、位系統(tǒng)設置寄存器、位顯示寄存器、位選開關、段選開關、位驅動器、段譯碼、驅動器、內部振蕩器等組成。在串行輸入使能腳ENABLE為低有效時,串行數(shù)據(jù)輸入到內部移位寄存器,ENABLE上升沿把移位寄存器中的數(shù)據(jù)根據(jù)數(shù)據(jù)位數(shù)不同自動將8位數(shù)據(jù)裝入系統(tǒng)設置寄存器或將24位數(shù)據(jù)裝入顯示寄存器。

2.管腳介紹

圖8.17給出了MC14489芯片的管腳圖。

管腳3:VDD為電源的正極輸入,范圍為4.5~6V。

管腳14:VSS為地。

管腳11:CLOCK為串行數(shù)據(jù)時鐘輸入端,時鐘頻率范圍為0~4MHz。

管腳12:DATAIN為串行數(shù)據(jù)輸入端。

管腳18:DATAOUT為串行數(shù)據(jù)輸出端,用于將MC14489各級級聯(lián)使用。

管腳8:RX為接外部電流設置電阻,阻值范圍為700歐姆至無窮大。管腳10:ENABLE為使能信號輸入端,低電平有效。

管腳7、6、5、4、2、1、20、19:a~h為陽極驅動電流源,若接共陰極LED數(shù)碼管,a~g驅動7段筆劃,h驅動小數(shù)點;若接發(fā)光二極管,則應采用非譯碼方式,使用a、b、c和d共可控制20只發(fā)光管,同時h也可控制5只。在此方式下e、f與g不使用。

管腳9、13、15、16、17:BANK1~BANK5為陰極開關,可分別接至5組數(shù)碼管或者發(fā)光管的公共陰極。

圖8.17MC14489芯片管腳圖

3.MC14489的主要特性

(1)具有SPI標準的三線串行接口,可直接與具有SPI接口的CPU相連,也可采用軟件模擬SPI接口,最大串行時鐘頻率可達4MHz。

(2)有一個8位的內部系統(tǒng)設置寄存器,用于設置芯片的工作模式。

(3)有一個24位顯示寄存器,該寄存器用于存放包括小數(shù)點段在內的顯示代碼。

(4)除可通過一個公共的外接電阻RX來確定每一段的最大峰值電流外,還可由輸入的顯示代碼決定全部顯示段為滿亮顯示或半亮度顯示。

(5)通過系統(tǒng)設置寄存器的第零位可設置全部顯示段為全亮或全暗,上電復位后芯片自動處于全暗的低功耗方式。

(6)芯片內具有BCD七段譯碼電路,可顯示0~9和A~F十六進制數(shù),還可顯示15種其他字符。

(7)多片MC14489可級聯(lián)使用以增加顯示位數(shù)。

(8)工作電壓范圍:4.5~6V。

4.MC14489的工作時序

當ENABLE腳處于低電平時,CLOCK腳上的一個時鐘上升沿就從DATAIN腳串行輸入一位數(shù)據(jù)到內部系統(tǒng)設置寄存器或內部顯示寄存器。MC14489采用了所謂“位抓取”技術,在向內部系統(tǒng)設置寄存器和顯示寄存器送數(shù)時不需要引導碼和地址碼,而是根據(jù)一次串行輸入數(shù)據(jù)的字節(jié)數(shù)由內部自動確定送往哪一個寄存器。若輸入是單字節(jié)數(shù)據(jù),將被送往系統(tǒng)設置寄存器,若輸入的是多字節(jié)數(shù)據(jù),則將被送往顯示寄存器。串行輸入數(shù)據(jù)在MC14489內部系統(tǒng)設置寄存器中各位的作用如圖8.18所示,顯示寄存器中各位的作用如圖8.19所示。

圖8.18MC14489內部設置寄存器中各位的作用

圖8.19MC14489顯示寄存器各位的作用圖8.20為AT89C52與MC14489的硬件連接電路。AT89C52不帶SPI串行總線接口,所以使用軟件來模擬SPI的操作,包括串行時鐘、數(shù)據(jù)輸入和數(shù)據(jù)輸出。

圖8.20AT89C52與MC14489接口設計電路原理圖

AT89C52的P1.0、P1.1和P1.2管腳分別連到MC14489的DATAIN、CLOCK和ENABLE,用來模擬SPI接口。BANK1~BANK5連接到LED的陰極,a~h連接到LED的陽極。8.3.4軟件程序設計

以下為在5位LED上顯示“12345”的程序代碼。#include<reg52.h>

#defineucharunsignedchar

sbitDATA=P10;//定義P1.0為DATAIN

sbitCLK=P11;//定義P1.1為CLOCK

sbitENA=P12;//定義P1.2為ENABLE

voidDSPCMD(ucharCMD);//單字節(jié)命令函數(shù),寫入MC14489內部設置寄存器

voidDSPDATA(ucharDSCMD,ucharDSDATA1,ucharDSDATA2);

//多字節(jié)命令函數(shù),寫入MC14489顯示寄存器

voidmain()

{

DSPCMD(0xEF);//寫內部設置寄存器

DSPDATA(0x81,0x23,0x45);//在5位LED上顯示12345,滿亮度顯示

}

/*單字節(jié)命令函數(shù),寫入MC14489內部設置寄存器*/

voidDSPCMD(ucharCMD)

{uchari;

ENA=0;//使能MC14489

for(i=8;i>=1;i--)//寫入單字節(jié)命令

{

DATA=CMD&0x80;

CMD=CMD<<1;

CLK=0;

CLK=1;

ENA=1;

}

}//禁止MC14489

/*多字節(jié)命令函數(shù),寫入MC14489顯示寄存器*/

voidDSPDATA(ucharDSCMD,ucharDSDATA1,ucharDSDATA2)

{ucharDSP,i,j;

i=0;

ENA=0;//使能MC14489

while(i<24)//寫入三字節(jié)顯示數(shù)據(jù)

{

if(i<8){DSP=DSCMD;}

elseif(i<16){DSP=DSDATA1;}

else{DSP=DSDATA2;}

for(j=8;j>=1;j--)

{

DATA=DSP&0x80;

DSP=DSP<<1;

CLK=0;

CLK=1;

}

i=i+8;

}

ENA=1;

}//禁止MC14489

目前比較流行的集中串行擴展總線中,I2C(InterICBUS)總線以其嚴格的規(guī)范和眾多的帶I2C接口的外圍芯片而獲得廣泛應用。I2C總線是Philips推出的芯片間的串行傳輸總線,它以兩根連線實現(xiàn)了完善的全雙工同步數(shù)據(jù)傳送,可以極方便地構成多機系統(tǒng)和外圍器件擴展系統(tǒng)。I2C總線采用了器件地址的硬件設置方法,通過軟件尋址完全避免了器件的片選線尋址方法,從而使硬件系統(tǒng)具有最簡單而靈活的擴展方法。8.4I2C總線8.4.1I2C總線的工作原理

I2C總線應用系統(tǒng)的典型結構如圖8.21所示。I2C總線的串行數(shù)據(jù)線SDA和串行時鐘線SCL必須經過上拉電阻R接到正電源上。當總線空閑時,SDA和SCL必須保持高電平。為了使總線上所有電路的輸出能完成“線與”的功能,連接到總線上的器件的輸出極必須為“開漏”或“開集”的形式,所以總線上需要加上拉電阻。

I2C總線是多主機總線,可以有兩個或更多的能夠控制的設備與總線連接。I2C總線器件采用硬件設置地址的方法,器件無片選線,減少了總線的數(shù)量。I2C總線的兩根信號線是數(shù)據(jù)線(SDA)和時鐘線(SCL)。所有進入I2C總線系統(tǒng)的設備都帶有I2C總線接口,符合I2C總線電氣規(guī)范特性,將外部設備的數(shù)據(jù)線(SDA)和時鐘線(SCL)與I2C總線的SDA、SCL相連即可。各個外部的設備的供電可以不同,但是這些設備需要共地。

圖8.21I2C總線應用系統(tǒng)的典型結構

I2C總線的串行數(shù)據(jù)傳送與一般UART的串行數(shù)據(jù)傳送相比,無論從接口電氣特性、傳送狀態(tài)管理以及程序編制特點都有很大的不同,了解這些特點十分重要。

1)I2C基本特征

(1)二線傳輸。I2C總線上所有的節(jié)點,如主器件(單片機、微處理器)、外圍器件、接口模塊等都連在同名端SCL(時鐘線)和SDA(數(shù)據(jù)線)上。

(2)系統(tǒng)中有多個主器件時,這些器件可以作為總線的主控制器(無中心主機)。I2C總線工作時任何一個主器件都有可能成為主控制器。多機競爭時的時鐘同步與總線仲裁都由硬件與軟件模塊自動完成。

(3)I2C總線傳輸時,采用狀態(tài)碼管理方法。對于總線傳輸時的任何一種狀態(tài),在狀態(tài)寄存器中都會出現(xiàn)相應的狀態(tài)碼,并會自動進入相應的狀態(tài)處理程序進行自動處理。

(4)系統(tǒng)中的所有外圍器件和模塊采用器件地址和引腳地址的編址方法。系統(tǒng)中主控制器對任意節(jié)點的尋址采用純軟件的尋址方式,避免了片選的連線方法。系統(tǒng)中若有地址編碼沖突,可通過改變地址的引腳電平來解決。

(5)所有帶有I2C接口的外圍器件都具有應答功能。片內有多個單元地址時,數(shù)據(jù)讀寫都有自動加1功能。這樣,在I2C總線對某一器件讀寫多個字節(jié)時很容易實現(xiàn)自動操作,即準備好讀寫入口條件后,只需啟動I2C總線就可以完成N個字節(jié)的讀寫操作。

(6)I2C總線的電氣接口由開漏晶體管組成,開路輸出沒有連到電源的鉗位二極管,而連到I2C總線的每個器件上,其自身電源可以獨立,但須共地。總線上各個結點可以在系統(tǒng)帶電情況下接入或撤出。

I2C總線的時鐘線SCL和數(shù)據(jù)線SDA都是雙向數(shù)據(jù)線??偩€備用時二者都必須保持高電平狀態(tài),只有關閉I2C總線時才能使SCL鉗位在低電平。在標準I2C模式下數(shù)據(jù)傳送速率可達100kb/s,高速模式下可達400kb/s。總線驅動能力受總線電容限制,不加驅動擴展時驅動能力為400pF。

2)I2C總線信號定義

I2C總線通過兩線,即串行數(shù)據(jù)(SDA)和串行時鐘(SCL)線,在連接到總線的器件間傳遞信息。每個器件都有一個唯一的地址識別(無論是微控制器、LCD驅動器、存儲器或鍵盤接口)而且都可以作為一個發(fā)送器或接收器(由器件的功能決定)。很明顯,LCD驅動器只是一個接收器,而存儲器既可以接收又可以發(fā)送數(shù)據(jù)。除了發(fā)送器和接收器外,器件在執(zhí)行數(shù)據(jù)傳輸時也可以被看做是主機或從機(見表8.6)。主機是初始化總線的數(shù)據(jù)傳輸并產生允許傳輸?shù)臅r鐘信號的器件。此時,任何被尋址的器件都被認為是從機。表8.6常見術語的描述術語描述發(fā)送器發(fā)送數(shù)據(jù)到總線的器件接收器從總線接收數(shù)據(jù)的器件主機初始化發(fā)送,產生時鐘信號和終止發(fā)送的器件從機被主機尋址的器件多主機同時有多于一個主機嘗試控制總線,但不破壞報文仲裁是一個在有多個主機同時嘗試控制總線,但只允許其中一個控制總線并使報文不被破壞的過程同步兩個或多個器件同步時鐘信號的過程SDA線上的數(shù)據(jù)必須在時鐘的高電平周期保持穩(wěn)定。數(shù)據(jù)線的高或低電平狀態(tài)只有在SCL線的時鐘信號是低電平時才能改變(見圖8.22)。

圖8.22I2C的位傳輸在I2C總線中唯一出現(xiàn)的是被定義為起始條件S和停止條件P如圖8.23所示的情況。起始條件(S):當SCL線是高電平時,SDA線從高電平向低電平切換;停止條件(P):當SCL線是高電平時,SDA線由低電平向高電平切換。

圖8.23I2C起始和停止條件起始條件和停止條件一般由主機產生總線在起始條件后被認為處于忙的狀態(tài),在停止條件的某段時間后總線被認為再次處于空閑狀態(tài)。

如果產生重復起始條件(Sr)而不產生停止條件,總線會一直處于忙的狀態(tài)。此時的起始條件(S)和重復起始條件(Sr)在功能上是一樣的(見圖8.23)。

如果連接到總線的器件合并了必要的接口硬件,那么用它們檢測起始和停止條件十分簡便。但是沒有這種接口的微控制器在每個時鐘周期至少要采樣SDA線兩次來判別有沒有發(fā)生電平切換。8.4.2I2C總線的通信時序

I2C總線的工作時序如圖8.24所示。發(fā)送到SDA線上的每個字節(jié)必須為8位。每次傳輸可以發(fā)送的字節(jié)數(shù)量不受限制。每個字節(jié)后必須跟一個響應位。首先傳輸?shù)氖菙?shù)據(jù)的最高位(見圖8.24),從機要完成一些其他功能后(例如一個內部中斷服務程序)才能接收或發(fā)送下一個完整的數(shù)據(jù)字節(jié)可以使時鐘線SCL保持低電平迫使主機進入等待狀態(tài)。當從機準備好接收下一個數(shù)據(jù)字節(jié)并釋放時鐘線SCL后數(shù)據(jù)傳輸繼續(xù)。

圖8.24I2C總線工作時序圖利用SDA線進行數(shù)據(jù)傳送時,發(fā)送器每發(fā)送完一個數(shù)據(jù)字節(jié)后,都要求接收器發(fā)回一個應答信號(ACK)。發(fā)送器要接收應答信號仍由主控制器的時鐘SCL控制傳送。因此主控發(fā)送器必須在接收器發(fā)送應答信號前釋放SDA線,使其保持高電平,以便主控制器對SDA線上應答信號進行檢測。若被控制器由于某種原因無法繼續(xù)接收SDA線上數(shù)據(jù)時,必須向SDA線輸出一個非應答信號(NACK),使SDA線保持高電平。主控制器如果收到非應答信號(NACK),就要產生一個停止信號來終止SDA線上的數(shù)據(jù)傳送。

應答信號在第9個時鐘位置上出現(xiàn),接收器在SDA線上輸出低電平為應對信號(ACK),輸出高電平為非應答信號(NACK)。I2C總線時鐘信號以及應答和非應答信號間的關系如圖8.25所示。當主控制器作為接收器送來的最后一個數(shù)據(jù)時,也必須給被控制器發(fā)送一個非應答信號(NACK)。被控制器收到主控制器發(fā)來的非應答信號(NACK)后釋放SDA線,以便主控制器發(fā)送停止信號來結束數(shù)據(jù)的傳送。I2C總線上的應答信號是比較重要的,它決定了數(shù)據(jù)傳送是否成功,在編程時應該著重考慮。

圖8.25I2C總線響應在I2C總線上可以連接多個外圍器件,所有的外圍器件都有規(guī)范的器件地址。在進行數(shù)據(jù)傳送之前,I2C總線會首先發(fā)送一個字節(jié)進行尋址。這個字節(jié)是緊跟在起始條件之后發(fā)送的,表示要通信的從器件地址。其格式定義如表8.7所示。表8.7通信從器件地址含義地址信息是7bit,占用了地址字節(jié)的高7位,可以對127個器件進行尋址。該字節(jié)的第0bit用于表示數(shù)據(jù)的傳送方向:當該位是高電平時,表示由從器件向主器件發(fā)送數(shù)據(jù),即主器件對從器件進行讀操作;當該位為低電平時,表示由主器件向從器件發(fā)送數(shù)據(jù),即主器件對從器件進行寫操作。

起始條件后,總線中各個器件將自己的地址與主器件送到總線上的器件地址進行對比,如果發(fā)生匹配,該器件認為被主器件尋址。一般來說,從器件的地址由一部分固定地址和一部分可變地址組成,而可變地址確定了在I2C總線上可容納的此類器件的最多數(shù)目。8.4.3硬件電路設計

由于標準的MCS51單片機不具備I2C總線接口,MCS51單片機在擴展具有I2C總線的芯片時可利用單片機的I/O接口與之相連,在程序中利用位操作指令和移位指令模仿I2C總線的操作時序編寫相應的程序。圖8.26是MCS51單片機實現(xiàn)I2C總線的硬件原理圖。

圖8.26單片機實現(xiàn)I2C總線硬件原理圖本例的硬件電路設計比較簡單,僅僅利用89C52的兩個通道I/O口P1.2和P1.3模擬SDA和SCL。注意,因為I2C總線的電器特性,SDA和SCL均要接上拉電阻。8.4.4軟件程序設計

單片機模擬I2C總線向從器件發(fā)送數(shù)據(jù)和由從器件接收數(shù)據(jù)的程序流程圖分別如圖8.27和圖8.28所示。

圖8.27向從器件發(fā)送數(shù)據(jù)

圖8.28從器件接收數(shù)據(jù)

程序如下:

#include<reg52.h>//引用標準庫的頭文件

#include<intrins.h>

#defineucharunsignedchar

#defineuintunsignedint

sbitSDA=P1^2;//串行數(shù)據(jù)

sbitSCL=P1^3;//串行時鐘

ucharidataslave_dev_adr;//從器件地址

ucharidatasendbuf[8];//數(shù)據(jù)發(fā)送緩沖區(qū)

ucharidatarecivebuf[8];//數(shù)據(jù)接收緩沖區(qū)

bitbdataNack;//器件壞或錯誤標志位

bitbdataNackFlag;//非應答標志位

voiddelay5us();//延時約5μs,對于12M時鐘

voidstart(void);//起始條件子函數(shù)

voidstop(void);//停止條件子函數(shù)

voidack(void);//發(fā)送應答子函數(shù)

voidn_ack(void);//發(fā)送非應答子函數(shù)

voidcheckack(void);//應答位檢查子函數(shù)

voidsendbyte(ucharidata*ch);//發(fā)送一個字節(jié)數(shù)據(jù)子函數(shù)

voidrecbyte(ucharidata*ch);//接收一字節(jié)子程序

voidsendnbyte(ucharidata*sla,ucharn);//發(fā)送n字節(jié)數(shù)據(jù)子程序

voidrecnbyte(ucharidata*sla,ucharn);//接收n字節(jié)數(shù)據(jù)子程序

/*主函數(shù),模擬實現(xiàn)I2C總線的數(shù)據(jù)收發(fā)*/

voidmain(void)

{

uchari,numbyte;

numbyte=8;/*需發(fā)送的8字節(jié)數(shù)據(jù)*/

for(i=0;i<numbyte;i++)

sendbuf[i]=i+0x11;

slave_dev_adr=0x58;//從器件地址

sendnbyte(&slave_dev_adr,numbyte);//向從器件發(fā)送存放在sendbuf[8]中的8字節(jié)數(shù)據(jù)

for(i=0;i<10000;i++)

delay5us();

recnbyte(&slave_dev_adr,numbyte);//由從器件接收8字節(jié)數(shù)據(jù),存放在rbuf中

}

/*延時約5μs,對于12M時鐘*/

voiddelay5us()

{

uinti;

for(i=0;i<5;i++)

_nop_();

}

/*起始條件子函數(shù)*/

voidstar

溫馨提示

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

最新文檔

評論

0/150

提交評論