<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32的SPI采用DMA方式傳輸測試

          STM32的SPI采用DMA方式傳輸測試

          作者: 時間:2016-11-19 來源:網絡 收藏
          環(huán)境:

          主機:WIN7

          本文引用地址:http://www.ex-cimer.com/article/201611/318288.htm

          開發(fā)環(huán)境:MDK4.23

          MCU:STM32F103CBT6

          說明:

          參考鏈接:http://www.openedv.com/posts/list/3159.htm

          SPI傳輸數據分為連續(xù)傳輸和非連續(xù)傳輸.

          連續(xù)傳輸時序圖:

          非連續(xù)傳輸時序圖:

          非連續(xù)傳輸模式可以參考上篇文章:http://blog.csdn.net/jdh99/article/details/7598573

          官方pdf關于連續(xù)和非連續(xù)傳輸的說明:
          當在主模式下發(fā)送數據時,如果軟件足夠快,能夠在檢測到每次TXE的上升沿(或TXE中斷),并立即在正在進行的傳輸結束之前寫入SPI_DR寄存器,則能夠實現連續(xù)的通信;此時,在每個數據項的傳輸之間的SPI時鐘保持連續(xù),同時BSY位不會被清除。

          簡而言之,就是要及時監(jiān)測TXE.在SPI在1M以上波特率傳輸時,傳輸一位時間為1us,導致軟件不能及時判斷,此時可以用dma的方式來進行SPI傳輸.

          源代碼:

          配置:

          #define buffersize 512#define SPI1_DR_Addr ( (u32)0x4001300C )extern uint8_t SPI1_TX_Buff[buffersize];extern uint8_t SPI1_RX_Buff[buffersize];

          void SPI1_DMA_Configuration( void ){RCC->AHBENR |= 1<<0 ;                     //DMA1時鐘使能/*------------------配置SPI1_RX_DMA通道Channel2---------------------*/DMA1_Channel2->CCR &= ~( 1<<14 ) ;        //非存儲器到存儲器模式DMA1_Channel2->CCR |=    2<<12   ;        //通道優(yōu)先級高DMA1_Channel2->CCR &= ~( 3<<10 ) ;        //存儲器數據寬度8bitDMA1_Channel2->CCR &= ~( 3<<8  ) ;        //外設數據寬度8bitDMA1_Channel2->CCR |=    1<<7    ;        //存儲器地址增量模式DMA1_Channel2->CCR &= ~( 1<<6  ) ;        //不執(zhí)行外設地址增量模式DMA1_Channel2->CCR &= ~( 1<<5  ) ;        //執(zhí)行循環(huán)操作DMA1_Channel2->CCR &= ~( 1<<4  ) ;        //從外設讀DMA1_Channel2->CNDTR &= 0x0000   ;        //傳輸數量寄存器清零DMA1_Channel2->CNDTR = buffersize ;       //傳輸數量設置為buffersize個DMA1_Channel2->CPAR = SPI1_DR_Addr ;      //設置外設地址,注意PSIZEDMA1_Channel2->CMAR = (u32)SPI1_RX_Buff ; //設置DMA存儲器地址,注意MSIZE/*------------------配置SPI1_TX_DMA通道Channel3---------------------*/DMA1_Channel3->CCR &= ~( 1<<14 ) ;        //非存儲器到存儲器模式DMA1_Channel3->CCR |=    0<<12   ;        //通道優(yōu)先級最低DMA1_Channel3->CCR &= ~( 3<<10 ) ;        //存儲器數據寬度8bitDMA1_Channel3->CCR &= ~( 3<<8 )  ;        //外設數據寬度8bitDMA1_Channel3->CCR |=    1<<7    ;        //存儲器地址增量模式DMA1_Channel3->CCR &= ~( 1<<6 )  ;        //不執(zhí)行外設地址增量模式DMA1_Channel3->CCR &= ~( 1<<5 ) ;         //不執(zhí)行循環(huán)操作DMA1_Channel3->CCR |=    1<<4    ;        //從存儲器讀DMA1_Channel3->CNDTR &= 0x0000   ;        //傳輸數量寄存器清零DMA1_Channel3->CNDTR = buffersize ;       //傳輸數量設置為buffersize個DMA1_Channel3->CPAR = SPI1_DR_Addr ;      //設置外設地址,注意PSIZEDMA1_Channel3->CMAR = (uint32_t)SPI1_TX_Buff ; //設置DMA存儲器地址,注意MSIZE				 }


          接收與發(fā)送:

          void SPI1_ReceiveSendByte( u16 num ){DMA1_Channel2->CNDTR = 0x0000   ;           //傳輸數量寄存器清零DMA1_Channel2->CNDTR = num ;         //傳輸數量設置為buffersize個DMA1_Channel3->CNDTR = 0x0000   ;           //傳輸數量寄存器清零DMA1_Channel3->CNDTR = num ;         //傳輸數量設置為buffersize個DMA1->IFCR = 0xF0 ;                         //清除通道2的標志位DMA1->IFCR = 0xF00 ;                        //清除通道3的標志位SPI1->DR ;									//接送前讀一次SPI1->DR,保證接收緩沖區(qū)為空while( ( SPI1->SR & 0x02 ) == 0 );DMA1_Channel3->CCR |= 1 << 0 ;              //開啟DMA通道3DMA1_Channel2->CCR |= 1 << 0 ;              //開啟DMA通道2	while( ( DMA1->ISR & 0x20 ) == 0 );DMA1_Channel3->CCR &= ~( 1 << 0 ) ;         //關閉DMA通道3DMA1_Channel2->CCR &= ~( 1 << 0 ) ;         //關閉DMA通道2}
          //SPI發(fā)送一個字節(jié)static uint8 SPI_SendByte(uint8 Data){#ifndef SPI_DMA// Loop while DR register in not empltywhile( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) == RESET ) ;// Send byte through the SPI1 peripheralSPI_I2S_SendData( SPI1, Data ) ;// Wait to receive a bytewhile( SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) == RESET ) ;// Return the byte read from the SPI busreturn SPI_I2S_ReceiveData( SPI1 ) ;#elseSPI1_TX_Buff[0] = Data;SPI1_ReceiveSendByte(1);return (SPI1_RX_Buff[0]);#endif}//SPI讀取Len字節(jié)void SPI_ReadBytes( uint8 Addr, NtrxBufferPtr Buffer, uint8 Len ){#ifndef SPI_DMAif( ( Len > 0x80 ) || ( Len == 0 ) )Len = 1 ;SPI_SendByte( Len ) ;SPI_SendByte( Addr ) ;while( Len-- ){*Buffer = SPI_SendByte( 0xFF ) ;Buffer ++ ;}#elseuint8 i = 0;if( ( Len > 0x80 ) || ( Len == 0 ) )Len = 1 ;SPI1_TX_Buff[0] = Len;SPI1_TX_Buff[1] = Addr;SPI1_ReceiveSendByte(Len + 2);for (i = 0;i < Len;i++){*Buffer++ = SPI1_RX_Buff[i + 2];	}#endif}


          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();