《STM32嵌入式單片機原理與應用》 課件 李正軍 第9、10章 SPI與I2C串行總線、DMA控制器_第1頁
《STM32嵌入式單片機原理與應用》 課件 李正軍 第9、10章 SPI與I2C串行總線、DMA控制器_第2頁
《STM32嵌入式單片機原理與應用》 課件 李正軍 第9、10章 SPI與I2C串行總線、DMA控制器_第3頁
《STM32嵌入式單片機原理與應用》 課件 李正軍 第9、10章 SPI與I2C串行總線、DMA控制器_第4頁
《STM32嵌入式單片機原理與應用》 課件 李正軍 第9、10章 SPI與I2C串行總線、DMA控制器_第5頁
已閱讀5頁,還剩123頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第9章SPI與I2C串行總線本章講述了SPI與I2C串行總線,包括SPI通信原理、STM32F103的SPI工作原理、SPI庫函數(shù)、SPI串行總線應用實例、I2C通信原理、STM32F103的I2C接口、STM32F103的I2C庫函數(shù)和I2C串行總線應用實例。

9.1SPI通信原理串行外設接口(SerialPeripheralInterface,SPI)是由美國摩托羅拉(Motorola)公司提出的一種高速全雙工串行同步通信接口,首先出現(xiàn)在M68HC系列處理器中,由于其簡單方便,成本低廉,傳輸速度快,因此被其他半導體廠商廣泛使用,從而成為事實上的標準。SPI與USART相比,其數(shù)據(jù)傳輸速度要快得多,因此它被廣泛地應用于微控制器與ADC、LCD等設備的通信,尤其是高速通信的場合。微控制器還可以通過SPI組成一個小型同步網(wǎng)絡進行高速數(shù)據(jù)交換,完成較復雜的工作。作為全雙工同步串行通信接口,SPI采用主/從模式(master/slave),支持一個或多個從設備,能夠?qū)崿F(xiàn)主設備和從設備之間的高速數(shù)據(jù)通信。SPI具有硬件簡單、成本低廉、易于使用、傳輸數(shù)據(jù)速度快等優(yōu)點,使用于成本敏感或者高速通信的場合。但同時,SPI也存在無法檢查糾錯、不具備尋址能力和接收方?jīng)]有應答信號等缺點,不適合復雜或者可靠性要求較高的場合。SPI是同步全雙工串行通信接口。由于同步,SPI有一條公共的時鐘線;由于全雙工,SPI至少有兩條數(shù)據(jù)線來實現(xiàn)數(shù)據(jù)的雙向同時傳輸;由于串行,SPI收發(fā)數(shù)據(jù)只能一位一位地在各自的數(shù)據(jù)線上傳輸,因此最多只有兩條數(shù)據(jù)線:一條發(fā)送數(shù)據(jù)線和一條接收數(shù)據(jù)線。由此可見,SPI在物理層體現(xiàn)為4條信號線,分別是SCK、MOSI、MISO和SS。1)SCK(SerialClock),即時鐘線,由主設備產(chǎn)生。不同的設備支持的時鐘頻率不同。但每個時鐘周期可以傳輸一位數(shù)據(jù),經(jīng)過8個時鐘周期,一個完整的字節(jié)數(shù)據(jù)就傳輸完成了。2)MOSI(MasterOutputSlaveInput),即主設備數(shù)據(jù)輸出/從設備數(shù)據(jù)輸入線。這條信號線上的方向是從主設備到從設備,即主設備從這條信號線發(fā)送數(shù)據(jù),從設備從這條信號線上接收數(shù)據(jù)。有的半導體廠商(如Microchip公司),站在從設備的角度,將其命名為SDI。9.1.1SPI介紹3)MISO(MasterInputSlaveOutput),即主設備數(shù)據(jù)輸入/從設備數(shù)據(jù)輸出線。這條信號線上的方向是由從設備到主設備,即從設備從這條信號線發(fā)送數(shù)據(jù),主設備從這條信號線上接收數(shù)據(jù)。有的半導體廠商(如Microchip公司),站在從設備的角度,將其命名為SDO。4)SS(SlaveSelect),有時候也叫CS(ChipSelect),SPI從設備選擇信號線,當有多個SPI從設備與SPI主設備相連(即一主多從)時,SS用來選擇激活指定的從設備,由SPI主設備(通常是微控制器)驅(qū)動,低電平有效。當只有一個SPI從設備與SPI主設備相連(即一主一從)時,SS并不是必需的。因此,SPI也被稱為三線同步通信接口。除了SCK、MOSI、MISO和SS這4條信號線外,SPI接口還包含一個串行移位寄存器,如圖9-1所示。圖9-1SPI接口組成SPI互連主要有一主一從和一主多從兩種互連方式。1.一主一從在一主一從的SPI互連方式下,只有一個SPI主設備和一個SPI從設備進行通信。這種情況下,只需要分別將主設備的SCK、MOSI、MISO和從設備的SCK、MOSI、MISO直接相連,并將主設備的SS置為高電平,從設備的SS接地(置為低電平,片選有效,選中該從設備)即可,如圖9-2所示。9.1.2SPI互連圖9-2一主一從的SPI互連2.一主多從在一主多從的SPI互連方式下,一個SPI主設備可以和多個SPI從設備相互通信。這種情況下,所有的SPI設備(包括主設備和從設備)共享時鐘線和數(shù)據(jù)線,即SCK、MOSI、MISO這3條線,并在主設備端使用多個GPIO引腳來選擇不同的SPI從設備,如圖9-3所示。顯然,在多個從設備的SPI互連方式下,片選信號SS必須對每個從設備分別進行選通,增加了連接的難度和連接的數(shù)量,失去了串行通信的優(yōu)勢。圖9-3一主多從的SPI互連9.2STM32F103的SPI工作原理串行外設接口(SPI)允許芯片與外部設備以半/全雙工、同步、串行方式通信。此接口可以被配置成主模式,并為外部從設備提供通信時鐘(SCK),接口還能以多主的配置方式工作。它可用于多種用途,包括使用一條雙向數(shù)據(jù)線的雙線單工同步傳輸,還可使用CRC校驗的可靠通信。STM32F103微控制器的小容量產(chǎn)品有1個SPI接口,中等容量產(chǎn)品有2個SPI,大容量產(chǎn)品則有3個SPI。STM32F103微控制器SPI主要具有以下特征:1)3線全雙工同步傳輸。2)帶或不帶第三根雙向數(shù)據(jù)線的雙線單工同步傳輸。3)8或16位傳輸幀格式選擇。4)主或從操作。5)支持多主模式。6)8個主模式波特率預分頻系數(shù)(最大為fPCLK/2)。7)從模式頻率(最大為fPCLK/2)。8)主模式和從模式的快速通信。9.2.1SPI主要特征9)主模式和從模式下均可以由軟件或硬件進行NSS管理:主/從操作模式的動態(tài)改變。10)可編程的時鐘極性和相位。11)可編程的數(shù)據(jù)順序,MSB在前或LSB在前。12)可觸發(fā)中斷的專用發(fā)送和接收標志。13)SPI總線忙狀態(tài)標志。14)支持可靠通信的硬件CRC。在發(fā)送模式下,CRC值可以被作為最后一個字節(jié)發(fā)送;在全雙工模式下,對接收到的最后一個字節(jié)自動進行CRC校驗。15)可觸發(fā)中斷的主模式故障、過載以及CRC錯誤標志。16)支持DMA功能的1字節(jié)發(fā)送和接收緩沖器:產(chǎn)生發(fā)送和接受請求。STM32F103微控制器SPI主要由波特率發(fā)生器、收發(fā)控制和數(shù)據(jù)存儲轉(zhuǎn)移三部分組成,內(nèi)部結構如圖9-4所示。波特率發(fā)生器用來產(chǎn)生SPI的SCK時鐘信號,收發(fā)控制主要由控制寄存器組成,數(shù)據(jù)存儲轉(zhuǎn)移主要由移位寄存器、接收緩沖區(qū)和發(fā)送緩沖區(qū)等構成。

9.2.2SPI內(nèi)部結構圖9-4STM32F103微控制器SPI內(nèi)部結構圖通常SPI通過4個引腳與外部器件相連:①MISO:主設備輸入/從設備輸出引腳。該引腳在從模式下發(fā)送數(shù)據(jù),在主模式下接收數(shù)據(jù)。②MOSI:主設備輸出/從設備輸入引腳。該引腳在主模式下發(fā)送數(shù)據(jù),在從模式下接收數(shù)據(jù)。③SCK:串口時鐘,作為主設備的輸出,從設備的輸入。④NSS:從設備選擇。這是一個可選的引腳,用來選擇主/從設備。它的功能是用來作為片選引腳,讓主設備可以單獨地與特定從設備通信,避免數(shù)據(jù)線上的沖突。SPI_CR寄存器的CPOL和CPHA位,能夠組合成四種可能的時序關系。CPOL(時鐘極性)位控制在沒有數(shù)據(jù)傳輸時時鐘的空閑狀態(tài)電平,此位對主模式和從模式下的設備都有效。如果CPOL被清0,SCK引腳在空閑狀態(tài)保持低電平;如果CPOL被置1,SCK引腳在空閑狀態(tài)保持高電平。如圖9-5所示,如果CPHA(時鐘相位)位被清0,數(shù)據(jù)在SCK時鐘的奇數(shù)(第1、3、5個···)跳變沿(CPOL位為0時就是上升沿,CPOL位為1時就是下降沿)進行數(shù)據(jù)位的存取,數(shù)據(jù)在SCK時鐘偶數(shù)(第2、4、6個···)跳變沿(CPOL位為0時就是下降沿,CPOL位為1時就是上升沿)準備就緒。9.2.3時鐘信號的相位和極性圖9-5CPHA=0時SPI時序圖如圖9-6所示,如果CPHA(時鐘相位)位被置1,數(shù)據(jù)在SCK時鐘的偶數(shù)(第2、4、6個···)跳變沿(CPOL位為0時就是下降沿,CPOL位為1時就是上升沿)進行數(shù)據(jù)位的存取,數(shù)據(jù)在SCK時鐘奇數(shù)(第1、3、5個···)跳變沿(CPOL位為0時就是上升沿,CPOL位為1時就是下降沿)準備就緒。圖9-6CPHA=1時SPI時序圖CPOL時鐘極性和CPHA時鐘相位的組合選擇數(shù)據(jù)捕捉的時鐘邊沿。圖9-5和圖9-6顯示了SPI傳輸?shù)?種CPHA和CPOL位組合。此圖可以解釋為主設備和從設備的SCK、MISO、MOSI引腳直接連接的主或從時序圖。根據(jù)SPI_CR1寄存器中的LSBFIRST位,輸出數(shù)據(jù)位時可以MSB在先也可以LSB在先。根據(jù)SPI_CR1寄存器的DFF位,每個數(shù)據(jù)幀可以是8位或是16位。所選擇的數(shù)據(jù)幀格式?jīng)Q定發(fā)送/接收的數(shù)據(jù)長度。9.2.4數(shù)據(jù)幀格式在SPI為主模式時,在SCK腳產(chǎn)生串行時鐘。請按照以下步驟配置SPI為主模式。9.2.5配置SPI為主模式1.配置步驟1)通過SPI_CR1寄存器的BR[2:0]位定義串行時鐘波特率。2)選擇CPOL和CPHA位,定義數(shù)據(jù)傳輸和串行時鐘間的相位關系。3)設置DFF位來定義8位或16位數(shù)據(jù)幀格式。4)配置SPI_CR1寄存器的LSBFIRST位定義幀格式。5)如果需要NSS引腳工作在輸入模式,硬件模式下,在整個數(shù)據(jù)幀傳輸期間應把NSS腳連接到高電平;在軟件模式下,需設置SPI_CR1寄存器的SSM位和SSI位。如果NSS引腳工作在輸出模式,則只需設置SSOE位。6)必須設置MSTR位和SPE位(只當NSS腳被連到高電平,這些位才能保持置位)。在這個配置中,MOSI引腳是數(shù)據(jù)輸出,而MISO引腳是數(shù)據(jù)輸入。2.數(shù)據(jù)發(fā)送過程當寫入數(shù)據(jù)至發(fā)送緩沖器時,發(fā)送過程開始。在發(fā)送第一個數(shù)據(jù)位時,數(shù)據(jù)字被并行地(通過內(nèi)部總線)傳入移位寄存器,而后串行地移出到MOSI腳上;“MSB在先”還是“LSB在先”,取決于SPI_CR1寄存器中的LSBFIRST位的設置。數(shù)據(jù)從發(fā)送緩沖器傳輸?shù)揭莆患拇嫫鲿rTXE標志將被置位,如果設置了SPI_CR1寄存器中的TXEIE位,將產(chǎn)生中斷。3.數(shù)據(jù)接收過程對于接收器來說,當數(shù)據(jù)傳輸完成時:1)傳送移位寄存器里的數(shù)據(jù)到接收緩沖器,并且RXNE標志被置位。2)如果設置了SPI_CR2寄存器中的RXNEIE位,則產(chǎn)生中斷。在最后一個采樣時鐘沿,RXNE位被設置,在移位寄存器中接收到的數(shù)據(jù)字被傳送到接收緩沖器。讀SPI_DR寄存器時,SPI設備返回接收緩沖器中的數(shù)據(jù)。讀SPI_DR寄存器將清除RXNE位。9.3SPI庫函數(shù)SPI固件庫支持21種庫函數(shù),如表9-1所示。為了理解這些函數(shù)的具體使用方法,對標準庫中部分函數(shù)做詳細介紹。表9-1SPI庫函數(shù)函數(shù)名稱功能SPI_DeInit將外設SPIx寄存器重設為缺省值SPI_Init根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設SPIx寄存器SPI_StructInit把SPI_InitStruct中的每一個參數(shù)按缺省值填入SPI_Cmd使能或者失能SPI外設SPI_ITConfig使能或者失能指定的SPI中斷SPI_DMACmd使能或者失能指定SPI的DMA請求SPI_SendData通過外設SPIx發(fā)送一個數(shù)據(jù)SPI_ReceiveData返回通過SPIx接收最近數(shù)據(jù)SPI_DMALastTransferCmd使下一次DMA傳輸為最后一次傳輸SPI_NSSInternalSoftwareConfig為選定的SPI軟件配置內(nèi)部NSS引腳SPI_SSOutputCmd使能或者失能指定的SPISPI_DataSizeConfig設置選定的SPI數(shù)據(jù)大小SPI_TransmitCRC發(fā)送SPIx的CRC值SPI_CalculateCRC使能或者失能指定SPI的傳輸字CRC值計算SPI_GetCRC返回指定SPI的發(fā)送或者接收CRC寄存器值SPI_GetCRCPolynomial返回指定SPI的CRC多項式寄存器值SPI_BiDirectionalLineConfig選擇指定SPI在雙向模式下的數(shù)據(jù)傳輸方向SPI_GetFlagStatus檢查指定的SPI標志位設置與否SPI_ClearFlag清除SPIx的待處理標志位SPI_GetITStatus檢查指定的SPI中斷發(fā)生與否SPI_ClearITPendingBit清除SPIx的中斷待處理位1.函數(shù)SPI_DeInit函數(shù)名:SPI_I2S_DeInit。函數(shù)原型:voidSPI_I2S_DeInit(SPI_TypeDef*SPIx)。功能描述:將外設SPIx寄存器重設為缺省值。輸入?yún)?shù):SPIx,x可以是1或者2,用來選擇SPI外設。輸出參數(shù):無。返回值:無。2.函數(shù)SPI_Init函數(shù)名:SPI_Init。函數(shù)原型:voidSPI_Init(SPI_TypeDef*SPIx,SPI_InitTypeDef*SPI_InitStruct)。功能描述:根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設SPIx寄存器。輸入?yún)?shù)1:SPIx,x可以是1或者2,用來選擇SPI外設。輸入?yún)?shù)2:SPI_InitStruct,指向結構SPI_InitTypeDef的指針,包含了外設SPI的配置信息。輸出參數(shù):無。返回值:無。3.函數(shù)SPI_Cmd函數(shù)名:SPI_Cmd。函數(shù)原型:voidSPI_Cmd(SPI_TypeDef*SPIx,F(xiàn)unctionalState

NewState)。功能描述:使能或者失能SPI外設。輸入?yún)?shù)1:SPIx,x可以是1或者2,用來選擇SPI外設。輸入?yún)?shù)2:NewState,外設SPIx的新狀態(tài),這個參數(shù)可以取ENABLE或者DISABLE。輸出參數(shù):無。返回值:無。4.函數(shù)SPI_SendData函數(shù)名:SPI_I2S_SendData。函數(shù)原型:voidSPI_I2S_SendData(SPI_TypeDef*SPIx,u16Data)。功能描述:通過外設SPIx發(fā)送一個數(shù)據(jù)。輸入?yún)?shù)1:SPIx,x可以是1或者2,用來選擇SPI外設。輸入?yún)?shù)2:Data,待發(fā)送的數(shù)據(jù)。輸出參數(shù):無。返回值:無。5.函數(shù)SPI_I2S_ReceiveData函數(shù)名:SPI_I2S_ReceiveData。函數(shù)原型:u16SPI_I2S_ReceiveData(SPI_TypeDef*SPIx)。功能描述:返回通過SPIx最近接收的數(shù)據(jù)。輸入?yún)?shù):SPIx,x可以是1或者2,用來選擇SPI外設。輸出參數(shù):無。返回值:接收到的字。6.函數(shù)SPI_I2S_ITConfig函數(shù)名:SPI_I2S_ITConfig。函數(shù)原型:voidSPI_I2S_ITConfig(SPI_TypeDef*SPIx,uint8_tSPI_I2S_IT,F(xiàn)unctionalState

NewState)。功能描述:使能或者失能指定的SPI/I2S中斷。輸入?yún)?shù)1:SPIx,x可以是1或者2,用來選擇SPI外設。輸入?yún)?shù)2:SPI_I2S_IT,待使能或者失能的SPI/I2S中斷源。輸入?yún)?shù)3:NewState,SPIx/I2S中斷的新狀態(tài),這個參數(shù)可以取ENABLE或者DISABLE。輸出參數(shù):無。返回值:無。7.函數(shù)SPI_I2S_GetITStatus函數(shù)名:SPI_I2S_GetITStatus。函數(shù)原型:ITStatusSPI_I2S_GetITStatus(SPI_TypeDef*SPIx,uint8_tSPI_I2S_IT)。功能描述:檢查指定的SPI_I2S中斷發(fā)生與否。輸入?yún)?shù)1:SPIx,x可以是1或者2,用來選擇SPI外設。輸入?yún)?shù)2:SPI_I2S_IT,待檢查的SPI_I2S中斷源。輸出參數(shù):無。返回值:SPI_IT的新狀態(tài)。8.函數(shù)SPI_I2S_ClearFlag函數(shù)名:SPI_I2S_ClearFlag。函數(shù)原型:voidSPI_I2S_ClearFlag(SPI_TypeDef*SPIx,uint16_tSPI_I2S_FLAG)。功能描述:清除SPI/I2S的待處理標志位。輸入?yún)?shù)1:SPIx,x可以是1或者2,用來選擇SPI外設。輸入?yún)?shù)2:SPI_I2S_FLAG,待清除的SPI/I2S標志位。輸出參數(shù):無。返回值:無。9.4SPI串行總線應用實例Flash存儲器又稱閃存,它與EEPROM都是掉電后數(shù)據(jù)不丟失的存儲器,但Flash存儲器容量普遍大于EEPROM,現(xiàn)在基本取代了它的地位。我們生活中常用的U盤、SD卡、SSD固態(tài)硬盤以及STM32芯片內(nèi)部用于存儲程序的設備,都是Flash類型的存儲器。本節(jié)以一種使用SPI通信的串行Flash存儲芯片W25Q64的讀寫為例,講述STM32的SPI使用方法。實例中STM32的SPI外設采用主模式,通過查詢事件的方式來確保正常通信。SPI是一種串行同步通信協(xié)議,由一個主設備和一個或多個從設備組成,主設備啟動一個與從設備的同步通信,從而完成數(shù)據(jù)的交換。該總線大量用在Flash、ADC、RAM和顯示驅(qū)動器之類的慢速外設器件中。因為不同的器件通信命令不同,這里具體介紹STM32上SPI的配置方法,關于具體器件請參考相關說明書。SPI配置流程圖如圖9-7所示,主要包括開啟時鐘、相關引腳配置和SPI工作模式設置。其中,GPIO配置需將SPI器件片選設置為高電平,SCK、MISO、MOSI設置為復用功能。配置完成后,可根據(jù)器件功能和命令進行讀寫操作。

9.4.1SPI配置流程圖9-7SPI配置流程圖W25Q64SPI串行Flash硬件連接圖如圖9-8所示。9.4.2SPI串行總線應用的硬件設計圖9-8W25Q64SPI串行Flash接口電路圖本開發(fā)板中的Flash芯片(W25Q64)是一種使用SPI通信協(xié)議的NORFlash存儲器,它的CS/CLK/DIO/DO引腳分別連接到STM32對應的SPI引腳NSS、SCK、MOSI、MISO上,其中STM32的NSS引腳是一個普通的GPIO,不是SPI的專用NSS引腳,所以程序中要使用軟件控制的方式。Flash芯片中還有WP和HOLD引腳。WP引腳可控制寫保護功能,當該引腳為低電平時,禁止寫入數(shù)據(jù)。直接接電源,不使用寫保護功能。HOLD引腳可用于暫停通信,該引腳為低電平時,通信暫停,數(shù)據(jù)輸出引腳輸出高阻抗狀態(tài),時鐘和數(shù)據(jù)輸入引腳無效。直接接電源,不使用通信暫停功能。關于Flash芯片的更多信息,可參考W25Q64數(shù)據(jù)手冊。若使用的開發(fā)板Flash的型號或控制引腳不一樣,只需根據(jù)工程模板修改即可,程序的控制原理相同。為了使工程更加有條理,把讀寫Flash相關的代碼獨立分開存儲,方便以后移植。在“工程模板”之上新建bsp_spi_flash.c及bsp_spi_flash.h文件。編程要點:1)初始化通信使用的目標引腳及端口時鐘;2)使能SPI外設的時鐘;3)配置SPI外設的模式、地址、速率等參數(shù)并使能SPI外設;4)編寫基本SPI按字節(jié)收發(fā)的函數(shù);5)編寫對Flash擦除及讀寫操作的函數(shù);6)編寫測試程序,對讀寫數(shù)據(jù)進行校驗。9.4.3SPI串行總線應用的軟件設計9.5I2C通信原理I2C總線是原Philips公司推出的一種用于IC器件之間連接的2線制串行擴展總線,它通過2條信號線(SDA,串行數(shù)據(jù)線;SCL,串行時鐘線)在連接到總線上的器件之間傳送數(shù)據(jù),所有連接在總線的I2C器件都可以工作于發(fā)送方式或接收方式。I2C總線主要是用來連接整體電路,I2C是一種多向控制總線,也就是說多個芯片可以連接到同一總線結構下,同時每個芯片都可以作為實時數(shù)據(jù)傳輸?shù)目刂圃?。這種方式簡化了信號傳輸總線接口。I2C總線結構如圖9-10所示。9.5.1I2C串行總線概述圖9-10I2C總線結構1.數(shù)據(jù)位的有效性規(guī)定如圖9-11所示,I2C總線進行數(shù)據(jù)傳送時,時鐘信號為高電平期間,數(shù)據(jù)線上的數(shù)據(jù)必須保持穩(wěn)定,只有在時鐘線上的信號為低電平期間,數(shù)據(jù)線上的高電平或低電平狀態(tài)才允許變化。

9.5.2I2C總線的數(shù)據(jù)傳送圖9-11I2C數(shù)據(jù)有效性規(guī)定2.起始和終止信號I2C總線規(guī)定,當SCL為高電平時,SDA的電平必須保持穩(wěn)定不變的狀態(tài),只有當SCL處于低電平時,才可以改變SDA的電平值,但起始信號和停止信號是特例。因此,當SCL處于高電平時,SDA的任何跳變都會被識別成為一個起始信號或停止信號。如圖9-12所示,SCL線為高電平期間,SDA線由高電平向低電平的變化表示起始信號;SCL線為高電平期間,SDA線由低電平向高電平的變化表示終止信號。圖9-12I2C總線起始和終止信號3.數(shù)據(jù)傳送格式1)字節(jié)傳送與應答在I2C總線的數(shù)據(jù)傳輸過程中,發(fā)送到SDA信號線上的數(shù)據(jù)以字節(jié)為單位,每個字節(jié)必須為8位,而且是高位(MSB)在前,低位(LSB)在后,每次發(fā)送數(shù)據(jù)的字節(jié)數(shù)量不受限制。但在這個數(shù)據(jù)傳輸過程中需要著重強調(diào)的是,當發(fā)送方發(fā)送完每一字節(jié)后,都必須等待接收方返回一個應答響應信號,如圖9-13所示。響應信號寬度為1位,緊跟在8個數(shù)據(jù)位后面,所以發(fā)送1字節(jié)的數(shù)據(jù)需要9個SCL時鐘脈沖。響應時鐘脈沖也是由主機產(chǎn)生的,主機在響應時鐘脈沖期間釋放SDA線,使其處在高電平。圖9-13I2C總線字節(jié)傳送與應答2)總線的尋址掛在I2C總線上的器件可以很多,但相互間只有兩根線連接(數(shù)據(jù)線和時鐘線),如何進行識別尋址呢?具有I2C總線結構的器件在其出廠時已經(jīng)給定了器件的地址編碼。I2C總線器件地址SLA(以7位為例)格式如圖9-14所示。圖9-14I2C總線器件地址格式(1)DA3~DA0:4位器件地址是I2C總線器件固有的地址編碼,器件出廠時就已給定,用戶不能自行設置。例如,I2C總線器件E2PROMAT24CXX的器件地址為1010。(2)A2~A0:3位引腳地址用于相同地址器件的識別。若I2C總線上掛有相同地址的器件,或同時掛有多片相同器件時,可用硬件連接方式對3位引腳A2~A0接Vcc或接地,形成地址數(shù)據(jù)。(3)R/W:用于確定數(shù)據(jù)傳送方向。R/W=1時,主機接收(讀);R/W=0,主機發(fā)送(寫)。主機發(fā)送地址時,總線上的每個從機都將這7位地址碼與自己的地址進行比較,如果相同,則認為自己正被主機尋址,根據(jù)R/W位將自己確定為發(fā)送器或接收器。3)數(shù)據(jù)幀格式I2C總線上傳送的數(shù)據(jù)信號是廣義的,既包括地址信號,又包括真正的數(shù)據(jù)信號。在起始信號后必須傳送一個從機的地址(7位),第8位是數(shù)據(jù)的傳送方向位(R/W),用0表示主機發(fā)送數(shù)據(jù)(W),1表示主機接收數(shù)據(jù)(R)。每次數(shù)據(jù)傳送總是由主機產(chǎn)生的終止信號結束。但是,若主機希望繼續(xù)占用總線進行新的數(shù)據(jù)傳送,則可以不產(chǎn)生終止信號,立即再次發(fā)出起始信號對另一從機進行尋址。在總線的一次數(shù)據(jù)傳送過程中,可以有以下幾種組合方式。(1)主機向從機寫數(shù)據(jù)主機向從機寫n個字節(jié)數(shù)據(jù),數(shù)據(jù)傳送方向在整個傳送過程中不變。12C的數(shù)據(jù)線SDA上的數(shù)據(jù)流如圖9-15所示。有陰影部分表示數(shù)據(jù)由主機向從機傳送,無陰影部分則表示數(shù)據(jù)由從機向主機傳送。A表示應答,A表示非應答(高電平),S表示起始信號,P表示終止信號。如果主機要向從機傳輸一個或多個字節(jié)數(shù)據(jù),在SDA上需經(jīng)歷以下過程:①主機產(chǎn)生起始信號S。②主機發(fā)送尋址字節(jié)SLAVEADDRESS,其中的高7位表示數(shù)據(jù)傳輸目標的從機地址;最后1位是傳輸方向位,此時其值為0,表示數(shù)據(jù)傳輸方向從主機到從機。③當某個從機檢測到主機在I2C總線上廣播的地址與它的地址相同時,該從機就被選中,并返回一個應答信號A。沒被選中的從機會忽略之后SDA上的數(shù)據(jù)。圖9-15主機向從機寫數(shù)據(jù)SDA數(shù)據(jù)流④當主機收到來自從機的應答信號后,開始發(fā)送數(shù)據(jù)DATA。主機每發(fā)送完一個字節(jié),從機產(chǎn)生一個應答信號。如果在I2C的數(shù)據(jù)傳輸過程中,從機產(chǎn)生了非應答信號/A,則主機提前結束本次數(shù)據(jù)傳輸。⑤當主機的數(shù)據(jù)發(fā)送完畢后,主機產(chǎn)生一個停止信號結束數(shù)據(jù)傳輸,或者產(chǎn)生一個重復起始信號進入下一次數(shù)據(jù)傳輸。(2)主機從從機讀數(shù)據(jù)主機從從機讀n個字節(jié)數(shù)據(jù)時,I2C的數(shù)據(jù)線SDA上的數(shù)據(jù)流如圖9-16所示。其中,陰影框表示數(shù)據(jù)由主機傳輸?shù)綇臋C,透明框表示數(shù)據(jù)流由從機傳輸?shù)街鳈C。9-16主機由從機讀數(shù)據(jù)時SDA上的數(shù)據(jù)流流如果主機要從從機讀取一個或多個字節(jié)數(shù)據(jù),在SDA上需經(jīng)歷以下過程:①主機產(chǎn)生起始信號S。②主機發(fā)送尋址字節(jié)SLAVEADDRESS,其中的高7位表示數(shù)據(jù)傳輸目標的從機地址;最后1位是傳輸方向位,此時其值為1,表示數(shù)據(jù)傳輸方向由從機到主機。尋址字節(jié)SLAVEADDRESS發(fā)送完畢后,主機釋放SDA(拉高SDA)。③當某個從機檢測到主機在12C總線上廣播的地址與它的地址相同時,該從機就被選中,并返回一個應答信號A。沒被選中的從機會忽略之后SDA上的數(shù)據(jù)。④當主機收到應答信號后,從機開始發(fā)送數(shù)據(jù)DATA。從機每發(fā)送完一個字節(jié),主機產(chǎn)生一個應答信號。當主機讀取從機數(shù)據(jù)完畢或者主機想結束本次數(shù)據(jù)傳輸時,可以向從機返回一個非應答信號/A,從機即自動停止數(shù)據(jù)傳輸。⑤當傳輸完畢后,主機產(chǎn)生一個停止信號結束數(shù)據(jù)傳輸,或者產(chǎn)生一個重復起始信號進入下一次數(shù)據(jù)傳輸。(3)主機和從機雙向數(shù)據(jù)傳送在傳送過程中,當需要改變傳送方向時,起始信號和從機地址都被重復產(chǎn)生一次,但兩次讀/寫方向位正好反向。I2C的數(shù)據(jù)線SDA上的數(shù)據(jù)流如圖9-17所示。圖9-17主機和從機雙向數(shù)據(jù)傳送SDA上的數(shù)據(jù)流主機和從機雙向數(shù)據(jù)傳送的數(shù)據(jù)傳送過程是主機向從機寫數(shù)據(jù)和主機由從機讀數(shù)據(jù)的組合,故不再贅述。4.傳輸速率I2C的標準傳輸速率為100Kbit/s,快速傳輸可達400Kbit/s。目前還增加了高速模式,最高傳輸速率可達3.4Mbit/s。9.6STM32F103的I2C接口STM32F103微控制器的I2C模塊連接微控制器和I2C總線,提供多主機功能,支持標準和快速兩種傳輸速率,控制所有I2C總線特定的時序、協(xié)議、仲裁和定時。支持標準和快速兩種模式,同時與SMBus2.0兼容。I2C模塊有多種用途,包括CRC碼的生成和校驗、SMBus(SystemManagementBus,系統(tǒng)管理總線)和PMBus(PowerManagementBus,電源管理總線)。根據(jù)特定設備的需要,可以使用DMA以減輕CPU的負擔。STM32F103微控制器的小容量產(chǎn)品有1個I2C,中等容量和大容量產(chǎn)品有2個I2C。STM32F103微控制器的I2C主要具有以下特性:1)所有的I2C都位于APB1總線。2)支持標準(100Kbit/s)和快速(400Kbit/s)兩種傳輸速率。3)所有的I2C可工作于主模式或從模式,可以作為主發(fā)送器、主接收器、從發(fā)送器或者從接收器。4)支持7位或10位尋址和廣播呼叫。5)具有3個狀態(tài)標志:發(fā)送器/接收器模式標志、字節(jié)發(fā)送結束標志、總線忙標志。9.6.1STM32F103的I2C主要特性6)具有2個中斷向量:1個中斷用于地址/數(shù)據(jù)通信成功,1個中斷用于錯誤。7)具有單字節(jié)緩沖器的DMA。8)兼容系統(tǒng)管理總線SMBus2.0。STM32F103系列微控制器的I2C結構,由SDA線和SCL線展開,主要分為時鐘控制、數(shù)據(jù)控制和控制邏輯等部分,負責實現(xiàn)I2C的時鐘產(chǎn)生、數(shù)據(jù)收發(fā)、總線仲裁和中斷、DMA等功能,如圖9-18所示。9.6.2STM432F103的I2C內(nèi)部結構圖9-18STM32F103微控制器I2C接口內(nèi)部結構1.時鐘控制時鐘控制模塊根據(jù)控制寄存器CCR、CR1和CR2中的配置產(chǎn)的生I2C協(xié)議的時鐘信號:即SCL線上的信號。為了產(chǎn)生正確時序,必須在I2C_CR2寄存器中設定I2C的輸入時鐘。當I2C工作在標準傳輸速率時,輸入時鐘的頻率必須大于等于2MHz;當I2C工作在快速傳輸速率時,輸入時鐘的頻率必須大于等于4MHz。2.數(shù)據(jù)控制數(shù)據(jù)控制模塊通過一系列控制架構,在將要發(fā)送數(shù)據(jù)的基礎上,按照12C的數(shù)據(jù)格式加上起始信號、地址信號、應答信號和停止信號,將數(shù)據(jù)一位一位從SDA線上發(fā)送出去。讀取數(shù)據(jù)時,則從SDA線上的信號中提取出接收到的數(shù)據(jù)值。發(fā)送和接收的數(shù)據(jù)都被保存在數(shù)據(jù)寄存器中。3.控制邏輯控制邏輯用于產(chǎn)生I2C中斷和DMA請求。I2C接口可以按下述4種模式中的一種運行:1)從發(fā)送器模式。2)從接收器模式。3)主發(fā)送器模式。4)主接收器模式。該模塊默認工作于從模式。接口在生成起始條件后自動地從從模式切換到主模式;當仲裁丟失或產(chǎn)生停止信號時,則從主模式切換到從模式。允許多主機功能。主模式時,I2C接口啟動數(shù)據(jù)傳輸并產(chǎn)生時鐘信號。串行數(shù)據(jù)傳輸總是以起始條件開始并以停止條件結束。起始條件和停止條件都是在主模式下由軟件控制產(chǎn)生。9.6.3STM32F103的模式選擇從模式時,I2C接口能識別它自己的地址(7位或10位)和廣播呼叫地址。軟件能夠控制開啟或禁止廣播呼叫地址的識別。數(shù)據(jù)和地址按8位/字節(jié)進行傳輸,高位在前。跟在起始條件后的1或2字節(jié)是地址(7位模式為1字節(jié),10位模式為2字節(jié))。地址只在主模式發(fā)送。在一個字節(jié)傳輸?shù)?個時鐘后的第9個時鐘期間,接收器必須回送一個應答位(ACK)給發(fā)送器。9.7STM32F103的I2C庫函數(shù)STM32標準庫中提供了幾乎覆蓋所有I2C操作的函數(shù),I2C函數(shù)庫如表9-2所示。為了理解這些函數(shù)的具體使用方法,本節(jié)將對標準庫中部分函數(shù)做詳細介紹。表9-2I2C庫函數(shù)函數(shù)名稱功能I2C_DeInit將外設I2Cx寄存器重設為缺省值I2C_Init根據(jù)I2C_InitStruct中指定的參數(shù)初始化外設I2Cx寄存器I2C_StructInit把I2C_InitStruct中的每一個參數(shù)按缺省值填入I2C_Cmd使能或者失能I2C外設I2C_DMACmd使能或者失能指定I2C的DMA請求I2C_DMALastTransferCmd使下一次DMA傳輸為最后一次傳輸I2C_GenerateSTART產(chǎn)生I2Cx傳輸START條件I2C_GenerateSTOP產(chǎn)生I2Cx傳輸STOP條件I2C_AcknowledgeConfig使能或者失能指定I2C的應答功能I2C_OwnAddress2Config設置指定I2C的自身地址2I2C_DualAddressCmd使能或者失能指定I2C的雙地址模式I2C_GeneralCallCmd使能或者失能指定I2C的廣播呼叫功能I2C_ITConfig使能或者失能指定的I2C中斷I2C_SendData通過外設I2Cx發(fā)送一個數(shù)據(jù)I2C_ReceiveData讀取I2Cx最近接收的數(shù)據(jù)I2C_Send7bitAddress向指定的從I2C設備傳送地址字I2C_ReadRegister讀取指定的I2C寄存器并返回其值I2C_SoftwareResetCmd使能或者失能指定I2C的軟件復位I2C_SMBusAlertConfig驅(qū)動指定I2Cx的SMBusAlert引腳電平為高或低表9-2I2C庫函數(shù)(續(xù)表)函數(shù)名稱功能I2C_TransmitPEC使能或者失能指定I2C的PEC傳輸I2C_PECPositionConfig選擇指定I2C的PEC位置I2C_CalculatePEC使能或者失能指定I2C的傳輸字PEC值計算I2C_GetPEC返回指定I2C的PEC值I2C_ARPCmd使能或者失能指定I2C的ARPI2C_StretchClockCmd使能或者失能指定I2C的時鐘延展I2C_FastModeDutyCycleConfig選擇指定I2C的快速模式占空比I2C_GetLastEvent返回最近一次I2C事件I2C_CheckEvent檢查最近一次I2C事件是否是輸入的事件I2C_GetFlagStatus檢查指定的I2C標志位設置與否I2C_ClearFlag清除I2Cx的待處理標志位I2C_GetITStatus檢查指定的I2C中斷發(fā)生與否I2C_ClearITPendingBit清除I2Cx的中斷待處理位1.函數(shù)I2C_DeInit函數(shù)名:I2C_DeInit函數(shù)原型:voidI2C_DeInit(I2C_TypeDef*I2Cx)功能描述:將外設I2Cx寄存器重設為缺省值輸入?yún)?shù):I2Cx:x可以是1或者2,用來選擇I2C外設輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):RCC_APB1PeriphClockCmd()例如:/*DeinitializeI2C2interface*/I2C_DeInit(I2C2);2.函數(shù)I2C_Init函數(shù)名:I2C_Init函數(shù)原型:voidI2C_Init(I2C_TypeDef*I2Cx,I2C_InitTypeDef*I2C_InitStruct)功能描述:根據(jù)I2C_InitStruct中指定的參數(shù)初始化外設I2Cx寄存器輸入?yún)?shù)1:I2Cx:x可以是1或者2,用來選擇I2C外設輸入?yún)?shù)2:I2C_InitStruct:指向結構I2C_InitTypeDef的指針,包含了外設GPIO的配置信息輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):無例如:/*InitializetheI2C1accordingtotheI2C_InitStructuremembers*/I2C_InitTypeDefI2C_InitStructure;I2C_InitStructure.I2C_Mode=I2C_Mode_SMBusHost;I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1=0x03A2;I2C_InitStructure.I2C_Ack=I2I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed=200000;I2C_Init(I2C1,&I2C_InitStructure);3.函數(shù)I2C_Cmd函數(shù)名:函數(shù)I2C_Cmd函數(shù)原型:voidI2C_Cmd(I2C_TypeDef*I2Cx,F(xiàn)unctionalState

NewState)功能描述:使能或者失能I2C外設輸入?yún)?shù)1:I2Cx:x可以是1或者2,用來選擇I2C外設輸入?yún)?shù)2:NewState:外設I2Cx的新狀態(tài),可以為ENABLE或者DISABLE輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):無例如:/*EnableI2C1peripheral*/I2C_Cmd(I2C1,ENABLE);4.函數(shù)I2C_GenerateSTART函數(shù)名:I2C_GenerateSTART函數(shù)原型:voidI2C_GenerateSTART(I2C_TypeDef*I2Cx,F(xiàn)unctionalState

NewState)功能描述:產(chǎn)生I2Cx傳輸START條件輸入?yún)?shù)1:I2Cx:x可以是1或者2,用來選擇I2C外設輸入?yún)?shù)2:NewState:I2CxSTART條件的新狀態(tài),可以為ENABLE或者DISABLE輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):無例如:/*GenerateaSTARTconditiononI2C1*/I2C_GenerateSTART(I2C1,ENABLE);5.函數(shù)I2C_GenerateSTOP函數(shù)名:I2C_GenerateSTOP函數(shù)原型:voidI2C_GenerateSTOP(I2C_TypeDef*I2Cx,F(xiàn)unctionalState

NewState)功能描述:產(chǎn)生I2Cx傳輸STOP條件輸入?yún)?shù)1:I2Cx:x可以是1或者2,用來選擇I2C外設輸入?yún)?shù)2:NewState:I2CxSTOP條件的新狀態(tài),可以為ENABLE或者DISABLE輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):無例如:/*GenerateaSTOPconditiononI2C2*/I2C_GenerateSTOP(I2C2,ENABLE);6.函數(shù)I2C_Send7bitAddress函數(shù)名:I2C_Send7bitAddress函數(shù)原型:voidI2C_Send7bitAddress(I2C_TypeDef*I2Cx,u8Address,u8I2C_Direction)功能描述:向指定的從I2C設備傳送地址字輸入?yún)?shù)1:I2Cx:x可以是1或者2,用來選擇I2C外設輸入?yún)?shù)2:Address:待傳輸?shù)膹腎2C地址輸入?yún)?shù)3:I2C_Direction:設置指定的I2C設備工作為發(fā)送端還是接收端輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):無例如:/*Send,astransmitter,theSlavedeviceaddress0xA8in7-bitaddressingmodein12C1I2C_Send7bitAddress(I2C1,0xA8,I2C_Direction_Transmitter);7.函數(shù)I2C_SendData函數(shù)名:I2C_SendData函數(shù)原型:voidI2C_SendData(I2C_TypeDef*I2Cx,u8Data)功能描述:通過外設I2Cx發(fā)送一個數(shù)據(jù)輸入?yún)?shù)1:I2Cx:x可以是1或者2,用來選擇I2C外設輸入?yún)?shù)2:Data:待發(fā)送的數(shù)據(jù)輸出參數(shù):無返回值:無先決條件:無被調(diào)用函數(shù):無例如:/*Transmit0x5DbyteonI2C2*/I2C_SendData(I2C2,0x5D);8.函數(shù)I2C_ReceiveData函數(shù)名:I2C_ReceiveData函數(shù)原型:u8I2C_ReceiveData(I2C_TypeDef*I2Cx)功能描述:返回通過I2Cx最近接收的數(shù)據(jù)輸入?yún)?shù):I2Cx:x可以是1或者2,用來選擇I2C外設輸出參數(shù):無返回值:接收到的字先決條件:無被調(diào)用函數(shù):無例如:/*ReadthereceivedbyteonI2C1*/u8ReceivedData;ReceivedData=I2C_ReceiveData(I2C1);9.8I2C串行總線應用實例EEPROM是一種掉電后數(shù)據(jù)不丟失的存儲器,常用來存儲一些配置信息,以便系統(tǒng)重新上電的時候加載之。EEPOM芯片最常用的通信方式就是I2C協(xié)議,本節(jié)以EEPROM的讀寫實驗為例,講解STM32的I2C使用方法。實例中STM32的I2C外設采用主模式,分別用作主發(fā)送器和主接收器,通過查詢事件的方式來確保正常通信。雖然不同器件實現(xiàn)的功能不同,但是只要遵守I2C協(xié)議,其通信方式都是一樣的,配置流程也基本相同。對于STM32,首先要對I2C進行配置,使其能夠正常工作,再結合不同器件的驅(qū)動程序,完成STM32與不同器件的數(shù)據(jù)傳輸。STM32的I2C配置流程如圖9-19所示。9.8.1I2C配置流程圖9-19I2C配置流程圖I2C總線結構如圖9-10所示本開發(fā)板采用AT24C02串行EEPROM,AT24C02的SCL及SDA引腳連接到了STM32對應的I2C引腳中,結合上拉電阻,構成了I2C通信總線,如圖9-20所示。EEPROM芯片的設備地址一共有7位,其中高4位固定為:1010b,低3位則由A0、A1、A2信號線的電平?jīng)Q定。9.8.2I2C串行總線應用的硬件設計圖9-20AT24C02EEPROM硬件接口電路為了使工程更加有條理,把讀寫EEPROM相關的代碼獨立分開存儲,以方便以后移植。在“工程模板”之上新建bsp_i2c_ee.c及bsp_i2c_ee.h文件。編程要點:1)配置通信使用的目標引腳為開漏模式;2)使能IC外設的時鐘;3)配置IC外設的模式、地址、速率等參數(shù),并使能IC外設;4)編寫基本IC按字節(jié)收發(fā)的函數(shù);5)編寫讀寫EEPROM存儲內(nèi)容的函數(shù);6)編寫測試程序,對讀寫數(shù)據(jù)進行校驗。9.8.3I2C串行總線應用的軟件設計

第10章DMA控制器本章講述了DMA控制器,包括DMA的結構和主要特征、DMA的功能描述、DMA庫函數(shù)和DMA應用實例。10.1DMA的結構和主要特征DMA(DirectMemoryAccess,直接存儲器存取)用來提供在外設和存儲器之間或者存儲器和存儲器之間的高速數(shù)據(jù)傳輸,無須CPU干預,是所有現(xiàn)代計算機的重要特色。在DMA模式下,CPU只需向DMA控制器下達指令,讓DMA控制器來處理數(shù)據(jù)的傳送,數(shù)據(jù)傳送完畢再把信息反饋給CPU,這樣在很大程度上減輕了CPU資源占有率,可以大大節(jié)省系統(tǒng)資源。DMA主要用于快速設備和主存儲器成批交換數(shù)據(jù)的場合。在這種應用中,處理問題的出發(fā)點集中到兩點:一是不能丟失快速設備提供出來的數(shù)據(jù),二是進一步減少快速設備輸入/輸出操作過程中對CPU的打擾。這可以通過把這批數(shù)據(jù)的傳輸過程交由DMA來控制,讓DMA代替CPU控制在快速設備與主存儲器之間直接傳輸數(shù)據(jù)。當完成一批數(shù)據(jù)傳輸之后,快速設備還是要向CPU發(fā)一次中斷請求,報告本次傳輸結束的同時,“請示”下一步的操作要求。STM32的兩個DMA控制器有12個通道(DMA1有7個通道,DMA2有5個通道),每個通道專門用來管理來自一個或多個外設對存儲器訪問的請求。還有一個仲裁器來協(xié)調(diào)各個DMA請求的優(yōu)先權。DMA的功能框圖如圖10-1所示。STM32F103VET6的DMA模塊具有如下特征。1)12個獨立的可配置的通道(請求):DMA1有7個通道,DMA2有5個通道。2)每個通道都直接連接專用的硬件DMA請求,每個通道都支持軟件觸發(fā)。這些功能通過軟件來配置。3)在同一個DMA模塊上,多個請求間的優(yōu)先權可以通過軟件編程設置(共有4級:很高、高、中等和低),優(yōu)先權設置相等時由硬件決定(請求0優(yōu)先于請求1,以此類推)。4)獨立數(shù)據(jù)源和目標數(shù)據(jù)區(qū)的傳輸寬度(字節(jié)、半字、全字)是獨立的,模擬打包和拆包的過程。源和目的地址必須按數(shù)據(jù)傳輸寬度對齊。5)支持循環(huán)的緩沖器管理。6)每個通道都有3個事件標志(DMA半傳輸、DMA傳輸完成和DMA傳輸出錯),這3個事件標志通過邏輯“或”運算成為一個單獨的中斷請求。7)存儲器和存儲器間的傳輸。8)外設和存儲器、存儲器和外設之間的傳輸。9)閃存、SRAM、外設的SRAM、APB1、APB2和AHB外設均可作為訪問的源和目標。10)可編程的數(shù)據(jù)傳輸最大數(shù)目為65536。圖10-1DMA的功能框圖10.2DMA的功能描述DMA控制器和Cortex-M3核心共享系統(tǒng)數(shù)據(jù)總線,執(zhí)行直接存儲器數(shù)據(jù)傳輸。當CPU和DMA同時訪問相同的目標(RAM或外設)時,DMA請求會暫停CPU訪問系統(tǒng)總線若干個周期,總線仲裁器執(zhí)行循環(huán)調(diào)度,以保證CPU至少可以得到一半的系統(tǒng)總線(存儲器或外設)使用時間。發(fā)生一個事件后,外設向DMA控制器發(fā)送一個請求信號。DMA控制器根據(jù)通道的優(yōu)先權處理請求。當DMA控制器開始訪問發(fā)出請求的外設時,DMA控制器立即發(fā)送給外設一個應答信號。當從DMA控制器得到應答信號時,外設立即釋放請求。一旦外設釋放請求,DMA控制器同時撤銷應答信號。如果有更多的請求,外設可以在下一個周期啟動請求??傊?,每次DMA傳送由3個操作組成:1)從外設數(shù)據(jù)寄存器或者從當前外設/存儲器地址寄存器指示的存儲器地址讀取數(shù)據(jù),第一次傳輸時的開始地址是DMA_CPARx或DMA_CMARx寄存器指定的外設基地址或存儲器單元。10.2.1DMA處理2)將讀取的數(shù)據(jù)保存到外設數(shù)據(jù)寄存器或者當前外設/存儲器地址寄存器指示的存儲器地址,第一次傳輸時的開始地址是DMA_CPARx或DMA_CMARx寄存器指定的外設基地址或存儲器單元。3)執(zhí)行一次DMA_CNDTRx寄存器的遞減操作,該寄存器包含未完成的操作數(shù)目。仲裁器根據(jù)通道請求的優(yōu)先級啟動外設/存儲器的訪問。優(yōu)先權管理分兩個階段。1)軟件:每個通道的優(yōu)先權可以在DMA_CCRx寄存器中的PL[1:0]設置,有4個等級:最高優(yōu)先級、高優(yōu)先級、中等優(yōu)先級、低優(yōu)先級。2)硬件:如果兩個請求有相同的軟件優(yōu)先級,則較低編號的通道比較高編號的通道有較高的優(yōu)先權。例如,通道2優(yōu)先于通道4。DMA1控制器的優(yōu)先級高于DMA2控制器的優(yōu)先級。

10.2.2仲裁器每個通道都可以在有固定地址的外設寄存器和存儲器之間執(zhí)行DMA傳輸。DMA傳輸?shù)臄?shù)據(jù)量是可編程的,最大為65535。數(shù)據(jù)項數(shù)量寄存器包含要傳輸?shù)臄?shù)據(jù)項數(shù)量,在每次傳輸后遞減。1.可編程的數(shù)據(jù)量外設和存儲器的傳輸數(shù)據(jù)量可以通過DMA_CCRx寄存器中的PSIZE和MSIZE位編程設置。10.2.3DMA通道2.指針增量通過設置DMA_CCRx寄存器中的PINC和MINC標志位,外設和存儲器的指針在每次傳輸后可以有選擇地完成自動增量。當設置為增量模式時,下一個要傳輸?shù)牡刂穼⑹乔耙粋€地址加上增量值,增量值取決于所選的數(shù)據(jù)寬度為1、2或4。第一個傳輸?shù)牡刂反娣旁贒MA_CPARx/DMA_CMARx寄存器中。在傳輸過程中,這些寄存器保持它們初始的數(shù)值,軟件不能改變和讀出當前正在傳輸?shù)牡刂罚ㄋ趦?nèi)部的當前外設/存儲器地址寄存器中)。當通道配置為非循環(huán)模式時,傳輸結束后(即傳輸計數(shù)變?yōu)?)將不再產(chǎn)生DMA操作。要開始新的DMA傳輸,需要在關閉DMA通道的情況下,在DMA_CNDTRx寄存器中重新寫入傳輸數(shù)目。在循環(huán)模式下,最后一次傳輸結束時,DMA_CNDTRx寄存器的內(nèi)容會自動地被重新加載為其初始數(shù)值,內(nèi)部的當前外設/存儲器地址寄存器也被重新加載為DMA_CPARx/DMA_CMARx寄存器設定的初始基地址。3. 通道配置過程下面是配置DMA通道x的過程(x代表通道號):1)在DMA_CPARx寄存器中設置外設寄存器的地址。發(fā)生外設數(shù)據(jù)傳輸請求時,這個地址將是數(shù)據(jù)傳輸?shù)脑椿蚰繕恕?)在DMA_CMARx寄存器中設置數(shù)據(jù)存儲器的地址。發(fā)生存儲器數(shù)據(jù)傳輸請求時,傳輸?shù)臄?shù)據(jù)將從這個地址讀出或?qū)懭脒@個地址。3)在DMA_CNDTRx寄存器中設置要傳輸?shù)臄?shù)據(jù)量。在每個數(shù)據(jù)傳輸后,這個數(shù)值遞減。4)在DMA_CCRx寄存器的PL[1:0]位中設置通道的優(yōu)先級。5)在DMA_CCRx寄存器中設置數(shù)據(jù)傳輸?shù)姆较?、循環(huán)模式、外設和存儲器的增量模式、外設和存儲器的數(shù)據(jù)寬度、傳輸一半產(chǎn)生中斷或傳輸完成產(chǎn)生中斷。6)設置DMA_CCRx寄存器的ENABLE位,啟動該通道。一旦啟動了DMA通道,即可響應連到該通道上的外設的DMA請求。當傳輸一半的數(shù)據(jù)后,半傳輸標志(HTIF)被置1,當設置了允許半傳輸中斷位(HTIE)時,將產(chǎn)生中斷請求。在數(shù)據(jù)傳輸結束后,傳輸完成標志(TCIF)被置1,如果設置了允許傳輸完成中斷位(TCIE),則將產(chǎn)生中斷請求。4. 循環(huán)模式循環(huán)模式用于處理循環(huán)緩沖區(qū)和連續(xù)的數(shù)據(jù)傳輸(如ADC的掃描模式)。DMA_CCR寄存器中的CIRC位用于開啟這一功能。當循環(huán)模式啟動時,要被傳輸?shù)臄?shù)據(jù)數(shù)目會自動地被重新裝載成配置通道時設置的初值,DMA操作將會繼續(xù)進行。5.存儲器到存儲器模式DMA通道的操作可以在沒有外設請求的情況下進行,這種操作就是存儲器到存儲器模式。如果設置了DMA_CCRx寄存器中的MEM2MEM位,在軟件設置了DMA_CCRx存器中的EN位啟動DMA通道時,DMA傳輸將馬上開始。當DMA_CNDTRx寄存器為0時,DMA傳輸結束。存儲器到存儲器模式不能與循環(huán)模式同時使用。每個DMA通道都可以在DMA傳輸過半、傳輸完成和傳輸錯誤時產(chǎn)生中斷。為應用的靈活性考慮,通過設置寄存器的不同位來打開這些中斷。相關的中斷事件標志位及對應的使能控制位分別為:1)“傳輸過半”的中斷事件標志位是HTIF,中斷使能控制位是HTIE。2)“傳輸完成”的中斷事件標志位是TCIF,中斷使能控制位是TCIE。3)“傳輸錯誤”的中斷事件標志位是TEIF,中斷使能控制位是TEIE。10.2.4DMA中斷讀寫一個保留的地址區(qū)域,將會產(chǎn)生DMA傳輸錯誤。在DMA讀寫操作期間發(fā)生DMA傳輸錯誤時,硬件會自動清除發(fā)生錯誤的通道所對應的通道配置寄存器(DMA_CCRx)的EN位,該通道操作被停止。此時,在DMA_IFR寄存器中對應該通道的傳輸錯誤中斷標志位(TEIF)將被置位,如果在DMA_CCRx寄存器中設置了傳輸錯誤中斷允許位,則將產(chǎn)生中斷。10.3DMA庫函數(shù)DMA固件庫支持10種庫函數(shù),如表10-1所示。為了理解這些函數(shù)的具體使用方法,本節(jié)將對這些函數(shù)做詳細介紹。表10-1DMA庫函數(shù)函數(shù)名稱功能DMA_DeInit將DMA的通道x寄存器重設為缺省值DMA_Init根據(jù)DMA_InitStruct中指定的參數(shù),初始化DMA的通道x寄存器DMA_StructInit把DMA_InitStruct中的每一個參數(shù)按缺省值填入DMA_Cmd使能或者失能指定通道xDMA_ITConfig使能或者失能指定通道x的中斷DMA_GetCurrDataCounter得到當前DMA通道x剩余的待傳輸數(shù)據(jù)數(shù)目DMA_GetFlagStatus檢查指定的DMA通道x標志位設置與否DMA_ClearFlag清除DMA通道x待處理標志位DMA_GetITStatus檢查指定的DMA通道x中斷發(fā)生與否DMA_ClearITPendingBit清除DMA通道x中斷待處理標志位1.函數(shù)DMA_DeInit函數(shù)名:DMA_DeInit。函數(shù)原型:voidDMA_DeInit(DMA_Channel_TypeDef*DMAy_Channelx)。功能描述:DMAy_Channelx寄存器重設為缺省值。輸入?yún)?shù):DMAy_Channelx,DMAy的通道x,其中y可以是1或2,對于DMA1,x可以是1~7,對于DMA2,x可以是1~5。輸出參數(shù):無。返回值:無。例如:/*DeinitializetheDMA1Channe22*/DMA_DeInit(DMA1_Channe12);2.函數(shù)DMA_Init函數(shù)名:DMA_Init。函數(shù)原型:voidDMA_Init(DMA_Channel_TypeDef*DMAy_Channelx,DMA_InitTypeDef*DMA_InitStruct).功能描述:根據(jù)DMA_InitStruct指定的參數(shù)初始化DMAy的通道x寄存器.輸入?yún)?shù)1:DMAy_Channelx,DMAy的通道x,其中y可以是1或2,對于DMAI,x可以是1~7,對于DMA2,x可以是1~5。輸入?yún)?shù)2:DMA_InitStruct,指向結構DMA_InitTypeDef的指針,包含了DMAy通道x的配置信息。輸出參數(shù):無。返回值:無。例如:/*InitializetheDMA1ChannellaccordingtotheDMA_InitStructuremembers*/DMAInitTypeDef

DMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr=0x40005400;DMA_InitStructure.DMA_MemoryBaseAddr=0x20000100;DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;DNAInitStructure.DMA_BufferSize=256;DMAInitStructure,DMA_PeripheralInc-DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc-DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;DMAInitStructure,DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;DMAInitStructure,DMA_Priority=DMA_Priority_Medium;DMA_InitStructure,DMA_M2M=DMA_M2M_Disable;DMA_Init(DMA1_Channe11,&DMA_InitStructure);3.函數(shù)DMA_GetCurrDataCounte函數(shù)名:DMA_GetCurrDataCounter。函數(shù)原型:u16DMA_GetCurrDataCounter(DMA_Channel_TypeDef*DMAy_Channelx)。功能描述:返回當前DMAy通道x剩余的待傳輸數(shù)據(jù)數(shù)目。輸入?yún)?shù):DMAy_Channelx,選擇DMAy通道x。輸出參數(shù):無。返回值:當前DMA通道x剩余的待傳輸數(shù)據(jù)數(shù)目。例如:/*GetthenumberofremainingdataunitsinthecurrentDMA1Channe12transfer*/u16CurrDataCount;CurrDataCount-DMA_GetCurrDataCounter(DMA1_Channe12);4.函數(shù)DMA_Cmd函數(shù)名:DMA_Cmd。函數(shù)原型:voidDMA_Cmd(DMA_Channel_TypeDef*DMAy_Channelx,F(xiàn)unctionalState

NewState)。功能描述:使能或者失能指定的通道x。輸入?yún)?shù)1:DMAy_Channelx:選擇DMAy通道x。輸入?yún)?shù)2:NewState,DMA通道x的新狀態(tài)。這個參數(shù)可以取ENABLE或者DISABLE。輸出參數(shù):無。返回值:無。例如:/*EnableDMA1Channe17*/DMA_Cmd(DMA1_Channe17,ENABLE);5.函數(shù)DMA_GetFlagStatus函數(shù)名:DMA_GetFlagStatus。函數(shù)原型:FlagStatus

DMA_GetFlagStatus(uint32_tDMAy_FLAG)。功能描述:檢查指定的DMAy通道x標志位設置與否。輸入?yún)?shù):DMAyFLAG,待檢查的DMAy通道x標志位。輸出參數(shù):無。返回值:DMA_FLAG的新狀態(tài)(SET或者RESET)。例如:/*TestiftheDMA1Channe16halftransferinterruptflagissetornot*/FlagStatusStatus;Status=DMA_GetFlagStatus(DMA1_FLAG_HT6);6.函數(shù)DMA_ClearFlag函數(shù)名:DMA_ClearFlag。函數(shù)原型:voidDMA_ClearFlag(u32DMAy_FLAG)。功能描述:清除DMAy通道x待處理標志位。輸入?yún)?shù):DMAyFLAG,待清除的DMA標志位,使用操作符“|”可以同時選中多個DMA標志位。輸出參數(shù):無。返回值:無。例如:/

溫馨提示

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

評論

0/150

提交評論