一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

CW32L052單片機支持DMA實現(xiàn)高速數(shù)據(jù)傳輸

jf_qE49KoVBr8 ? 來源:CW32生態(tài)社區(qū) ? 2024-02-27 11:36 ? 次閱讀

概述

CW32L052支持DMA(Direct Memory Access),即直接內(nèi)存訪問,無需CPU干預(yù),實現(xiàn)高速數(shù)據(jù)傳輸。數(shù)據(jù)的傳輸可以發(fā)生在:

?外設(shè)和內(nèi)存之間:例如ADC采集數(shù)據(jù)到內(nèi)存,這種傳輸方式常見于需要將外設(shè)采集的數(shù)據(jù)快速傳輸?shù)絻?nèi)存進行處理的應(yīng)用。

?內(nèi)存和內(nèi)存之間:例如在兩個不同的數(shù)組之間傳輸數(shù)據(jù),或者在不同的內(nèi)存塊之間進行數(shù)據(jù)拷貝。

?外設(shè)和外設(shè)之間:例如從一個SPI主/從機傳輸數(shù)據(jù)到另一個SPI從/主機。

使用DMA能夠有效減輕CPU的負擔(dān),特別是在大量數(shù)據(jù)需要高效傳輸?shù)那闆r下,可以提高系統(tǒng)的整體性能。

框圖

f8bbca9c-d51e-11ee-a297-92fbcf53809c.png

DMA功能框圖

特性

使用DMA,最核心的就是配置要傳輸?shù)臄?shù)據(jù),包括數(shù)據(jù)從哪里來,要到哪里去,傳輸?shù)臄?shù)據(jù)的單位是什么,要傳多少數(shù)據(jù),是一次傳輸還是連續(xù)傳輸?shù)鹊取?/p>

4條獨立DMA通道

f96ac70e-d51e-11ee-a297-92fbcf53809c.png

4個DMA通道的優(yōu)先級和通道號綁定,通道號越小優(yōu)先級越高,通道號越大優(yōu)先級越低。

4種傳輸模式:

硬件觸發(fā)BULK傳輸模式、硬件觸發(fā)BLOCK傳輸模式、軟件觸發(fā)BULK傳輸模式和軟件觸發(fā)BLOCK傳輸模式。

硬件 BULK
BLOCK
軟件 BULK
BLOCK

BULK傳輸模式:

適用于小數(shù)據(jù)塊的傳輸,通常涉及大量的數(shù)據(jù)點,但每個數(shù)據(jù)點的大小較小。

與BLOCK模式不同,BULK模式下DMA會更頻繁地啟動新的傳輸,因為每個數(shù)據(jù)點通常被視為單獨的傳輸單元,所以DMA控制器需要在每個數(shù)據(jù)點傳輸完成后需要重新配置或者啟動DMA。在BULK傳輸模式下,傳輸過程不可被打斷。

BLOCK傳輸模式:

適用于大數(shù)據(jù)塊的高速傳輸,通常用于需要連續(xù)傳輸大量數(shù)據(jù)的情況。BLOCK模式下,DMA會將數(shù)據(jù)分成較大的塊,并在傳輸時以這些塊為單位進行操作。DMA控制器在一次配置后,連續(xù)傳輸多個數(shù)據(jù)塊,而無需額外的干預(yù)或重新配置。每傳輸完成1個數(shù)據(jù)塊后就要進行一次傳輸優(yōu)先級的仲裁,允許CPU或者更高優(yōu)先級的DMA通道訪問當(dāng)前DMA通道所占用的外設(shè)。

?硬件觸發(fā)和軟件觸發(fā):

要想通過DMA來傳輸數(shù)據(jù),必須先給DMA控制器發(fā)送DMA請求。部分外設(shè)支持硬件觸發(fā)啟動DMA傳輸,如FLASH存儲器、UART串口、TIM定時器ADC數(shù)模轉(zhuǎn)換器等被配置為DMA通道的觸發(fā)源時,

f97e9fb8-d51e-11ee-a297-92fbcf53809c.png

可以產(chǎn)生DMA請求(DMA request),硬件觸發(fā)啟動DMA傳輸,

fa145864-d51e-11ee-a297-92fbcf53809c.png

而不支持硬件DMA的外設(shè),只能配置為軟件觸發(fā)啟動DMA傳輸。

fa24d4c8-d51e-11ee-a297-92fbcf53809c.png

雖然每個通道可以接收多個外設(shè)的請求,但是同一時間只能接收一個,不能同時接收多個。

?DMA中斷

DMA通道在傳輸工程中可產(chǎn)生2個中斷標(biāo)志:傳輸錯誤中斷標(biāo)志和傳輸完成中斷標(biāo)志

不同 DMA 通道的中斷各自獨立,通過中斷標(biāo)志寄存器 DMA_ISR 可以獲取各通道的中斷標(biāo)志。標(biāo)志對應(yīng)多個可能的產(chǎn)生原因,具體產(chǎn)生原因需查詢 DMA_CSRy.STATUS 狀態(tài)位,如下表所示

fa33a6d8-d51e-11ee-a297-92fbcf53809c.png

?數(shù)據(jù)寬度:

數(shù)據(jù)位寬可以設(shè)置為8bit、16bit和32bit,DMA通道的源地址和目的地址的位寬必須完全一致

?數(shù)據(jù)塊數(shù)量:

傳輸?shù)臄?shù)據(jù)塊數(shù)量可以設(shè)置為1 ~ 65535

?數(shù)據(jù)傳輸優(yōu)先級

當(dāng)CPU和DMA訪問不同的外設(shè)時,數(shù)據(jù)的傳輸可以同時進行;

當(dāng)CPU和DMA同時訪問同一個外設(shè)時,CPU的優(yōu)先級高于DMA。

從外設(shè)到內(nèi)存

通過ADC轉(zhuǎn)換完成標(biāo)志觸發(fā)(硬件觸發(fā))DMA方式實現(xiàn)外設(shè)到內(nèi)存的DMA傳輸

核心代碼:

#include "main.h" 
#include "delay.h" 
#include "gpio.h" 
#include "cw32l052_lcd.h" 
#include "cw32l052_adc.h" 
#include "cw32l052_dma.h" 
 
#define NUM0 0x070d  //段式LCD數(shù)字段碼 
#define NUM1 0x0600 
#define NUM2 0x030e 
#define NUM3 0x070a 
#define NUM4 0x0603 
#define NUM5 0x050b 
#define NUM6 0x050f 
#define NUM7 0x0700 
#define NUM8 0x070f 
#define NUM9 0x070b 
 
void ADC_Configuration(void);      //ADC配置函數(shù) 
void DMA_Configuration(void);      //DMA配置函數(shù) 
void LCD_Configuration(void);      //LCD配置函數(shù) 
void LCD_Proc(uint16_t dispdata);  //LCD子程序函數(shù) 
 
/* 
**功能說明:
**ADC采集數(shù)據(jù)觸發(fā)DMA,將采集到的數(shù)據(jù)(1.2V內(nèi)核電壓基準(zhǔn)源)存儲在內(nèi)存value中,并顯示在LCD屏上 
*/ 
int main(void) 
{ 
  LED_Init(); 
  LCD_Configuration(); 
  ADC_Configuration(); 
  DMA_Configuration(); 
  while (1) 
  { 
    LCD_Proc(value);  //顯示采集到的ADC 
    PA15_TOG(); 
    Delay_ms(500); 
  } 
} 
 
void ADC_Configuration(void) 
{ 
  ADC_InitTypeDef   ADC_InitStruct = {0}; 
   
  __RCC_ADC_CLK_ENABLE(); 
  __RCC_GPIOA_CLK_ENABLE(); 
   
  PA00_ANALOG_ENABLE(); //PA00 (AIN0) 
   
  ADC_InitStruct.ADC_OpMode = ADC_SingleChOneMode;   //單通道單次轉(zhuǎn)換模式 
  ADC_InitStruct.ADC_ClkDiv = ADC_Clk_Div128;       //PCLK 
  ADC_InitStruct.ADC_SampleTime = ADC_SampTime5Clk; //5個ADC時鐘周期 
  ADC_InitStruct.ADC_VrefSel = ADC_Vref_VDDA;       //VDDA參考電壓(3.3V) 
  ADC_InitStruct.ADC_InBufEn = ADC_BufEnable;       //開啟跟隨器 
  ADC_InitStruct.ADC_TsEn = ADC_TsDisable;           //內(nèi)置溫度傳感器失能 
  ADC_InitStruct.ADC_DMASOCEn = ADC_DMASOCEnable;   //ADC轉(zhuǎn)換完成觸發(fā)DMA傳輸 
  ADC_InitStruct.ADC_Align = ADC_AlignRight;         //ADC轉(zhuǎn)換結(jié)果右對齊 
  ADC_InitStruct.ADC_AccEn = ADC_AccDisable;         //轉(zhuǎn)換結(jié)果累加不使能 
  ADC_Init(&ADC_InitStruct);                        //初始化ADC配置    
  CW_ADC->CR1_f.DISCARD = FALSE;                    //ADC轉(zhuǎn)換結(jié)果保存策略配置:新數(shù)據(jù)覆蓋未被讀取的舊數(shù)據(jù)        
  CW_ADC->CR1_f.CHMUX = ADC_Vref1P2Input;           //待轉(zhuǎn)換通道配置:1.2V內(nèi)核電壓基準(zhǔn)源 
 
  ADC_ClearITPendingBit(ADC_IT_EOC); 
  ADC_ITConfig(ADC_IT_EOC, ENABLE); 
  ADC_EnableNvic(ADC_INT_PRIORITY); 
 
  ADC_Enable(); 
  ADC_SoftwareStartConvCmd(ENABLE);                  //開始轉(zhuǎn)換 
} 
 
void ADC_IRQHandler(void) 
{ 
    /* USER CODE BEGIN */ 
  if(ADC_GetITStatus(ADC_IT_EOC) != RESET) 
  { 
      ADC_ClearITPendingBit(ADC_IT_EOC); 
      ADC_SoftwareStartConvCmd(ENABLE);              //開始轉(zhuǎn)換 
  } 
    /* USER CODE END */ 
} 
 
void NVIC_Configuration(void) 
{ 
    __disable_irq(); 
 
    NVIC_ClearPendingIRQ(DMACH1_IRQn); 
 
    NVIC_EnableIRQ(DMACH1_IRQn); 
 
    __enable_irq(); 
} 
 
void DMA_Configuration(void) 
{ 
  DMA_InitTypeDef DMA_InitStruct = {0}; 
   
  __RCC_DMA_CLK_ENABLE(); 
   
  DMA_StructInit(&DMA_InitStruct);  
  DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK;     //BLOCK模式 
  DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_32BIT; //數(shù)據(jù)寬度32bit 
  DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix; //源地址固定 
  DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix;  //目標(biāo)地址固定 
  DMA_InitStruct.DMA_TransferCnt = 1;  //數(shù)據(jù)塊數(shù)量1 
  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&(CW_ADC->RESULT0);  //數(shù)據(jù)源地址 (外設(shè)) 
  DMA_InitStruct.DMA_DstAddress = (uint32_t)&value;   //傳輸目標(biāo)地址   (內(nèi)存) 
  DMA_InitStruct.TrigMode = DMA_HardTrig;  //硬件觸發(fā)DMA傳輸 
  DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_SINGLETRANSCOM;  //硬件觸發(fā)源:ADC單次轉(zhuǎn)換完成標(biāo)志 
  DMA_Init(CW_DMACHANNEL1,&DMA_InitStruct); //DMA通道1 
  DMA_ClearITPendingBit(DMA_IT_ALL);  //清除DMA中斷標(biāo)志位 
  DMA_ITConfig(CW_DMACHANNEL1, DMA_IT_TC, ENABLE);   //使能DMA通道1中斷 
  NVIC_Configuration(); 
  DMA_Cmd(CW_DMACHANNEL1, ENABLE); //啟動DMA通道1進行傳輸 
} 
 
void DMACH1_IRQHandler(void) 
{ 
    /* USER CODE BEGIN */ 
  if( DMA_GetITStatus(DMA_IT_TC1) )  //DMA通道1傳輸完成標(biāo)志 
    { 
        DMA_ClearITPendingBit(DMA_IT_TC1); 
 
        CW_DMACHANNEL1->CNT = 0x10001;     //REPEAT寫1,傳輸數(shù)量為1                        
        DMA_Cmd(CW_DMACHANNEL1, ENABLE);  
    } 
    /* USER CODE END */ 
}

演示:ADC轉(zhuǎn)換結(jié)果為1580左右,換算成電壓:1580/4096*3.3=1.27V

fa4a338a-d51e-11ee-a297-92fbcf53809c.png

從內(nèi)存到內(nèi)存

通過軟件觸發(fā)DMA方式實現(xiàn)內(nèi)存(FLASH)到內(nèi)存(SRAM)的DMA傳輸

核心代碼:

//單片機頭文件
#include "main.h"
#include "cw32l052_lcd.h"
#include "cw32l052_dma.h"
//硬件外設(shè)
#include "delay.h"
#include "gpio.h"
//C庫
#include 


#define NUM0 0x070d  //段式LCD數(shù)字段碼
#define NUM1 0x0600
#define NUM2 0x030e
#define NUM3 0x070a
#define NUM4 0x0603
#define NUM5 0x050b
#define NUM6 0x050f
#define NUM7 0x0700
#define NUM8 0x070f
#define NUM9 0x070b


#define DATASIZE 10


uint16_t const srcBuf[DATASIZE] =   //源內(nèi)存(FLASH)數(shù)據(jù)
{
  9999,8888,7777,6666,5555,
  4444,3333,2222,1111,0
};


uint16_t dstBuf[DATASIZE]={0};      //目標(biāo)內(nèi)存(SRAM)數(shù)據(jù)


void DMA_Configuration(void);      //DMA配置函數(shù)
void LCD_Configuration(void);      //LCD配置函數(shù)
void LCD_Proc(uint16_t dispdata);  //LCD子程序函數(shù)


uint32_t value=0;  //ADC數(shù)值


/*
**功能說明:
**將srcBuf數(shù)組中的數(shù)據(jù)通過DMA傳送到dstBuf數(shù)組中,
**srcBuf數(shù)組中的數(shù)據(jù)通過const關(guān)鍵詞存儲到FLASH中,
**dstBuf數(shù)組存儲在SRAM程序運行過程中
**傳輸完成后比較兩數(shù)組內(nèi)容,相同則打開LED1和LED1,LCD上循環(huán)顯示dstBuf數(shù)據(jù);
**不同則進入死循環(huán),兩指示燈閃爍
*/
int main(void)
{
  LED_Init();
  LCD_Configuration();
  DMA_Configuration();
  DMA_SWTrigCmd(CW_DMACHANNEL1);   //使能通道1軟件觸發(fā)
  while(DMA_GetFlagStatus(CW_DMACHANNEL1)!=DMA_CHANNEL_STATUS_TRANSCOMPLETE); //等待傳輸完成
  if(memcmp(srcBuf,dstBuf,DATASIZE)==0)  //如果srcBuf和dstBuf相同
  {
      LED1_ON(); //指示燈
      LED2_ON();
      for(int i=0;i<10;i++)  //LCD屏顯示dstBuf數(shù)據(jù)
      {
        LCD_Proc(dstBuf[i]);
        Delay_ms(500);
      }
  }
  else  //如果不相同
  {
    while(1)  //進入while死循環(huán)
    {
      PA15_TOG();  //指示燈
      PC10_TOG();
      Delay_ms(500);
    }
  }
  
  while (1)
  {
    
  }
}


void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStruct = {0};
  
  __RCC_DMA_CLK_ENABLE();
  
  DMA_StructInit(&DMA_InitStruct); 
  DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK;     //BLOCK模式
  DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_16BIT; //數(shù)據(jù)寬度16bit
  DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Increase; //源地址固定
  DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Increase;  //目標(biāo)地址遞增
  DMA_InitStruct.DMA_TransferCnt = DATASIZE;  //數(shù)據(jù)塊數(shù)量
  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&srcBuf[0];  //數(shù)據(jù)源地址 (內(nèi)存)
  DMA_InitStruct.DMA_DstAddress = (uint32_t)&dstBuf[0];   //傳輸目標(biāo)地址 (內(nèi)存)
  DMA_InitStruct.TrigMode = DMA_SWTrig;  //軟件觸發(fā)DMA傳輸


  DMA_Init(CW_DMACHANNEL1,&DMA_InitStruct); //DMA通道1
  DMA_Cmd(CW_DMACHANNEL1, ENABLE); //啟動DMA通道1進行傳輸
}

演示:LCD屏上顯示通過DMA傳輸?shù)膁stBuf的數(shù)據(jù)

fa6d0a04-d51e-11ee-a297-92fbcf53809c.png

從外設(shè)到外設(shè)

通過硬件觸發(fā)DMA方式實現(xiàn)外設(shè)(SPI)到外設(shè)(SPI)的DMA傳輸

核心代碼:

/*單片機頭文件*/
#include "main.h"
/*硬件驅(qū)動*/
#include "delay.h"
#include "gpio.h"
#include "cw32l052_dma.h"
#include "cw32l052_spi.h"
/*C庫*/
#include 


//硬件連接
//SPIY_SCK  (PA10) -- SPIX_SCK  (PB13)
//SPIY_MISO (PA11) -- SPIX_MISO (PB14)
//SPIY_MOSI (PA12) -- SPIX_MOSI (PB15)


//SPI2相關(guān)定義(Master)
#define    SPIX                     CW_SPI2               
#define   SPIX_GPIO          CW_GPIOB
#define    SPIX_SCK_PIN             GPIO_PIN_13
#define   SPIX_MISO_PIN            GPIO_PIN_14
#define    SPIX_MOSI_PIN            GPIO_PIN_15
#define    SPIX_AF_SCK              PB13_AFx_SPI2SCK()
#define    SPIX_AF_MISO             PB14_AFx_SPI2MISO()
#define    SPIX_AF_MOSI             PB15_AFx_SPI2MOSI()
#define    SPIX_RX_DMACHANNEL       CW_DMACHANNEL1
#define    SPIX_TX_DMACHANNEL       CW_DMACHANNEL2  
#define     SPIX_DMA_RXTRIGSOURCE    DMA_HardTrig_SPI2_RXBufferNE
#define     SPIX_DMA_TXTRIGSOURCE    DMA_HardTrig_SPI2_TXBufferE


//SPI1相關(guān)定義(Slave)
#define    SPIY                     CW_SPI1
#define   SPIY_GPIO          CW_GPIOA
#define    SPIY_SCK_PIN             GPIO_PIN_10
#define    SPIY_MISO_PIN            GPIO_PIN_11
#define    SPIY_MOSI_PIN            GPIO_PIN_12
#define    SPIY_AF_SCK              PA10_AFx_SPI1SCK()
#define    SPIY_AF_MISO             PA11_AFx_SPI1MISO()
#define    SPIY_AF_MOSI             PA12_AFx_SPI1MOSI()


//數(shù)組長度
#define   BUFFERSIZE                 ARRAY_SZ(TxBuffer1)


//發(fā)送內(nèi)容1
uint8_t TxBuffer1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
                       0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
                       0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,
                       0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23
                      };
//發(fā)送內(nèi)容2
uint8_t TxBuffer2[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
                       0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
                       0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
                       0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
                       0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83
                      };
                    
uint8_t RxBuffer1[BUFFERSIZE];  //接收數(shù)組1
uint8_t RxBuffer2[BUFFERSIZE];  //接收數(shù)組2
uint8_t TxCounter = 0;  //發(fā)送計數(shù)
uint8_t RxCounter = 0;  //接收計數(shù)
  
uint8_t TransferStatus1 = 1;  //DMA傳輸狀態(tài)標(biāo)志1
uint8_t TransferStatus2 = 1;  //DMA傳輸狀態(tài)標(biāo)志2
                      
void DMA_Configuration(void);      //DMA配置函數(shù)
void SPI_Configuration(void);      //SPI配置函數(shù)
void SPI_GPIO_Configuration(void); //SPI相關(guān)GPIO口配置
  
/*
**功能說明:
**主機SPIY發(fā)送TxBuffer1中的數(shù)據(jù),從機SPIX通過DMA接收數(shù)據(jù)并存儲到RxBuffer1
**主機SPIY發(fā)送無效數(shù)據(jù),啟動SPI通信,同時SPIX從機通過DMA發(fā)送TxBuffer2中的數(shù)據(jù),SIPY接收數(shù)據(jù)并存儲到RxBuffer2
**單獨比較TxBuffer1與RxBuffer1、TxBuffer2與RxBuffer2中的內(nèi)容,比較結(jié)果通過LED燈指示
*/
int main(void)
{
  LED_Init();               //初始化LED指示燈
  SPI_GPIO_Configuration(); //配置PI相關(guān)GPIO口
  DMA_Configuration();      //配置DMA傳輸
  SPI_Configuration();      //配置SPI傳輸
  SPI_DMACmd(SPIX, SPI_DMAReq_Rx, ENABLE); //使能SPIX DMA RX
  SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Reset);//位選CS選中從機SPIX,起始信號
  while(TxCounter < BUFFERSIZE)
  {
    while(SPI_GetFlagStatus(SPIY,SPI_FLAG_TXE) == RESET);//等待發(fā)送緩沖空(為空后硬件自動置1)
    SPI_SendData(SPIY,TxBuffer1[TxCounter++]); //發(fā)送TxBuffer1中的數(shù)據(jù),通過數(shù)據(jù)寄存器DR把數(shù)據(jù)填充到發(fā)送緩沖區(qū)中
  }
  while(DMA_GetFlagStatus(SPIX_RX_DMACHANNEL) != DMA_CHANNEL_STATUS_TRANSCOMPLETE);//等待DMA接收完成


  SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Set); //釋放從機SPIX,結(jié)束信號
  TransferStatus1 = memcmp(TxBuffer1, RxBuffer1, BUFFERSIZE); //對比兩數(shù)組數(shù)據(jù)
  if(TransferStatus1==0)  //如果數(shù)據(jù)相同
  {
    LED1_ON();  //LED1指示
  }
  else
  {
    LED1_OFF();
  }
  
  TxCounter = 0;
  SPI_ReceiveData(SPIY);//讀DR以清除RXNE(接收非空)標(biāo)志位
  SPI_DMACmd(SPIX, SPI_DMAReq_Rx, DISABLE);//失能SPIX DMA RX
  SPI_FlushSendBuff(SPIX);//清空發(fā)送緩沖區(qū)和移位寄存器
  SPI_DMACmd(SPIX, SPI_DMAReq_Tx, ENABLE);//使能SPIX DMA TX
  SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Reset);
  while(TxCounter < BUFFERSIZE)
  {      
    while(SPI_GetFlagStatus(SPIY, SPI_FLAG_TXE) == RESET){;} //主機發(fā)送數(shù)據(jù)以啟動SPI通信
    SPI_SendData(SPIY, TxBuffer1[TxCounter++]);
      
    while(SPI_GetFlagStatus(SPIY, SPI_FLAG_RXNE) == RESET){;}
      RxBuffer2[RxCounter++] = SPI_ReceiveData(SPIY);  //獲取接收緩沖區(qū)中的內(nèi)容  
  }
  while(SPI_GetFlagStatus(SPIY,SPI_FLAG_BUSY) == SET); //檢查數(shù)據(jù)是否已經(jīng)全部通過SPI發(fā)送完畢  
  SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Set); //釋放
  TransferStatus2 = memcmp(TxBuffer2, RxBuffer2, BUFFERSIZE);  //檢查
  if(TransferStatus2 == 0)
  {
    LED2_ON();
  }
  else
  {
    LED2_OFF();
  }
  while (1)
  {
    
  }
}


void SPI_GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    
    //打開GPIO時鐘
    __RCC_GPIOA_CLK_ENABLE();
    __RCC_GPIOB_CLK_ENABLE();


    //SPI SCK MOSI MISO 復(fù)用
    SPIY_AF_SCK;
    SPIY_AF_MISO;
    SPIY_AF_MOSI;
    SPIX_AF_SCK;
    SPIX_AF_MISO;
    SPIX_AF_MOSI;


    //推挽輸出
    GPIO_InitStructure.Pins = SPIY_SCK_PIN | SPIY_MOSI_PIN;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(SPIY_GPIO, &GPIO_InitStructure);


    GPIO_InitStructure.Pins = SPIX_MISO_PIN;
    GPIO_Init(SPIX_GPIO, &GPIO_InitStructure);


    //浮空輸入
    GPIO_InitStructure.Pins = SPIX_SCK_PIN | SPIX_MOSI_PIN;
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    GPIO_Init(SPIX_GPIO, &GPIO_InitStructure);


    GPIO_InitStructure.Pins = SPIY_MISO_PIN;
    GPIO_Init(SPIY_GPIO, &GPIO_InitStructure);
}


void SPI_Configuration(void)
{
  SPI_InitTypeDef SPI_InitStructure = {0};
  
  __RCC_SPI1_CLK_ENABLE();
  __RCC_SPI2_CLK_ENABLE();
  
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //雙線全雙工模式
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主機模式
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //數(shù)據(jù)位寬8bit
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;  //時鐘極性
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//時鐘相位,奇數(shù)邊緣采樣
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //配置NSS引腳(片選信號線)的使用模式,軟件控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //波特率:PCLK8分頻
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //MSB先行模式
  SPI_InitStructure.SPI_Speed = SPI_Speed_Low; //低速
  SPI_Init(SPIY,&SPI_InitStructure);
  
  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; //從機模式
  SPI_Init(SPIX,&SPI_InitStructure);
  
  SPI_Cmd(SPIX,ENABLE);
  SPI_Cmd(SPIY,ENABLE);
}


void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure = {0};
  
  __RCC_DMA_CLK_ENABLE();
  
  //DMA TX
  DMA_InitStructure.DMA_Mode = DMA_MODE_BLOCK; //BLOCK模式
  DMA_InitStructure.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT;
  DMA_InitStructure.DMA_SrcInc = DMA_SrcAddress_Increase;
  DMA_InitStructure.DMA_DstInc = DMA_DstAddress_Fix;
  DMA_InitStructure.TrigMode = DMA_HardTrig;
  DMA_InitStructure.HardTrigSource = SPIX_DMA_TXTRIGSOURCE;
  DMA_InitStructure.DMA_TransferCnt = BUFFERSIZE;
  DMA_InitStructure.DMA_SrcAddress = (uint32_t)&TxBuffer2[0];
  DMA_InitStructure.DMA_DstAddress = (uint32_t)&SPIX->DR; //數(shù)據(jù)寄存器
  DMA_Init(SPIX_TX_DMACHANNEL,&DMA_InitStructure);
  DMA_Cmd(SPIX_TX_DMACHANNEL,ENABLE);
  
  //DMA RX
  DMA_InitStructure.DMA_Mode = DMA_MODE_BLOCK;
  DMA_InitStructure.DMA_TransferWidth = DMA_TRANSFER_WIDTH_8BIT;
  DMA_InitStructure.DMA_SrcInc = DMA_SrcAddress_Fix;
  DMA_InitStructure.DMA_DstInc = DMA_DstAddress_Increase;
  DMA_InitStructure.TrigMode = DMA_HardTrig;
  DMA_InitStructure.HardTrigSource = SPIX_DMA_RXTRIGSOURCE;
  DMA_InitStructure.DMA_TransferCnt = BUFFERSIZE;
  DMA_InitStructure.DMA_SrcAddress = (uint32_t)&SPIX->DR;
  DMA_InitStructure.DMA_DstAddress = (uint32_t)&RxBuffer1[0];
  DMA_Init(SPIX_RX_DMACHANNEL,&DMA_InitStructure);
  DMA_Cmd(SPIX_RX_DMACHANNEL,ENABLE);
}




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6058

    文章

    44821

    瀏覽量

    644714
  • 數(shù)據(jù)傳輸
    +關(guān)注

    關(guān)注

    9

    文章

    1991

    瀏覽量

    65434
  • LCD屏
    +關(guān)注

    關(guān)注

    0

    文章

    125

    瀏覽量

    15815
  • dma
    dma
    +關(guān)注

    關(guān)注

    3

    文章

    569

    瀏覽量

    102041
  • 推挽輸出
    +關(guān)注

    關(guān)注

    0

    文章

    81

    瀏覽量

    6605

原文標(biāo)題:CW32L052單片機DMA直接內(nèi)存訪問

文章出處:【微信號:武漢芯源半導(dǎo)體,微信公眾號:武漢芯源半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    CW32L052 DMA直接內(nèi)存訪問

    CW32L052支持DMA(Direct Memory Access),即直接內(nèi)存訪問,無需CPU干預(yù),實現(xiàn)高速
    的頭像 發(fā)表于 02-28 16:48 ?1133次閱讀
    <b class='flag-5'>CW32L052</b> <b class='flag-5'>DMA</b>直接內(nèi)存訪問

    ADXRS453Z的芯片支持使用STM32單片機DMA數(shù)據(jù)傳輸功能嗎?

    ADXRS453Z的芯片支持使用STM32單片機DMA數(shù)據(jù)傳輸功能嗎?如果,不能,考慮到我們的數(shù)據(jù)傳輸還是挺多的,那么常規(guī)的SPI通信方式
    發(fā)表于 12-29 07:47

    單片機紅外數(shù)據(jù)傳輸

    基于51單片機的紅外數(shù)據(jù)傳輸系統(tǒng)的設(shè)計主要任務(wù):寫設(shè)計要求、報告,設(shè)計各電路控制模塊、用PROTUS仿真、搭建電路模塊、寫出程序控制流程、寫出源碼、調(diào)試達到預(yù)期目標(biāo)。最終目標(biāo):利用單片機實現(xiàn)
    發(fā)表于 07-12 23:54

    請問ADXRS453Z的芯片支持使用STM32單片機DMA數(shù)據(jù)傳輸功能嗎?

    ADXRS453Z的芯片支持使用STM32單片機DMA數(shù)據(jù)傳輸功能嗎?如果,不能,考慮到我們的數(shù)據(jù)傳輸還是挺多的,那么常規(guī)的SPI通信方式
    發(fā)表于 08-10 08:13

    超低功耗家族再添新成員,武漢芯源半導(dǎo)體發(fā)布32位M0+內(nèi)核MCU CW32L052系列產(chǎn)品

    的 ARM? Cortex?-M0+ 內(nèi)核、高速嵌入式存儲器(最大64K字節(jié)FLASH、最大8K字節(jié)RAM),支持最多55路I/O接口。CW32L052內(nèi)部框圖外設(shè)包括:1路12位ADC,3路UART
    發(fā)表于 02-21 14:02

    DMA進行數(shù)據(jù)傳輸和CPU進行數(shù)據(jù)傳輸的疑問

    求大佬解答,本人正在學(xué)習(xí)STM32單片機DMA直接數(shù)據(jù)存儲部分的內(nèi)容 看了DMA簡介后,也上手過實例代碼,但是沒有實際的項目經(jīng)驗,所以有以下疑問:
    發(fā)表于 05-25 17:18

    CW32L052微控制器數(shù)據(jù)手冊

    CW32L052 是基于 eFlash 的單芯片低功耗微控制器,集成了主頻高達 48MHz 的 ARM? Cortex?-M0+ 內(nèi)核、高速嵌入式存儲器(多至 64K 字節(jié) FLASH 和多至 8K
    發(fā)表于 09-14 06:28

    CW32L052 StartKit軟件包

    CW32L052 StartKit 軟件包
    發(fā)表于 09-15 06:13

    單片機網(wǎng)絡(luò)數(shù)據(jù)傳輸

    單片機網(wǎng)絡(luò)數(shù)據(jù)傳輸器是由單片機以及有關(guān)電子電路組成的,可以通過互聯(lián)網(wǎng)絡(luò)來實現(xiàn)遠程監(jiān)控的一種傳輸裝置。用戶有了
    發(fā)表于 06-29 18:21 ?2066次閱讀

    TCP/IP協(xié)議單片機在網(wǎng)絡(luò)通信中的數(shù)據(jù)傳輸技術(shù)

    介紹了嵌入式TCP/IP協(xié)議單片機在網(wǎng)絡(luò)通信中的數(shù)據(jù)傳輸技術(shù)。將TCP/IP協(xié)議嵌入式單片機中,借助網(wǎng)卡芯片CS8900實現(xiàn)單片機在局域網(wǎng)
    發(fā)表于 04-16 22:04 ?4560次閱讀
    TCP/IP協(xié)議<b class='flag-5'>單片機</b>在網(wǎng)絡(luò)通信中的<b class='flag-5'>數(shù)據(jù)傳輸</b>技術(shù)

    DMA數(shù)據(jù)傳輸(源代碼分享)

    手頭項目也需要加入DMA數(shù)據(jù)傳輸,以最大限度地提升CPU效率,于是測試了一下XMEGA的DMA模塊,把一塊內(nèi)存中的數(shù)據(jù)DMA
    的頭像 發(fā)表于 04-27 09:22 ?9466次閱讀

    DMA數(shù)據(jù)傳輸在SPEAR300實現(xiàn)高速串口驅(qū)動設(shè)計

    DMA數(shù)據(jù)傳輸無需CPU的參與,是一種更加高效的數(shù)據(jù)傳輸方式。現(xiàn)有的DMA數(shù)據(jù)傳輸方案都是基于DMA
    發(fā)表于 04-04 12:23 ?1737次閱讀
    <b class='flag-5'>DMA</b><b class='flag-5'>數(shù)據(jù)傳輸</b>在SPEAR300<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>高速</b>串口驅(qū)動設(shè)計

    AT89C52單片機與PC之間的無線數(shù)據(jù)傳輸設(shè)計

    和專用無線傳輸芯片實現(xiàn)簡單的短距離無線傳輸方案,硬件部分包括單片機端和PC端,實現(xiàn)
    發(fā)表于 08-16 17:36 ?5596次閱讀
    AT89C52<b class='flag-5'>單片機</b>與PC<b class='flag-5'>機</b>之間的無線<b class='flag-5'>數(shù)據(jù)傳輸</b>設(shè)計

    超低功耗家族再添新成員,武漢芯源半導(dǎo)體發(fā)布32位M0+內(nèi)核MCU CW32L052系列產(chǎn)品

    ?Cortex?-M0+內(nèi)核、高速嵌入式存儲器(最大64K字節(jié)FLASH、最大8K字節(jié)RAM),支持最多55路I/O接口。CW32L052內(nèi)部框圖外設(shè)包括:1路12位ADC,3路UART(支持
    的頭像 發(fā)表于 02-21 14:03 ?1206次閱讀
    超低功耗家族再添新成員,武漢芯源半導(dǎo)體發(fā)布32位M0+內(nèi)核MCU <b class='flag-5'>CW32L052</b>系列產(chǎn)品

    CW32L052 FLASH存儲器

    CW32L052內(nèi)部集成了64KB嵌入式FLASH供用戶使用,可用來存儲應(yīng)用程序和用戶數(shù)據(jù)。芯片支持對 FLASH 存儲器的讀、擦除和寫操作,支持擦寫保護和讀保護。芯片內(nèi)置 FLASH
    的頭像 發(fā)表于 02-28 17:43 ?913次閱讀
    <b class='flag-5'>CW32L052</b> FLASH存儲器