<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

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

3天內不再提示

CW32L052 DMA直接內存訪問

CW32生態社區 ? 來源: CW32生態社區 ? 作者: CW32生態社區 ? 2024-02-28 16:48 ? 次閱讀

BD網盤鏈接:

https://pan.baidu.com/s/10WHNgB_cicTP1SbdcI4AkQ?pwd=l1et
提取碼:l1et

概述

CW32L052支持DMA(Direct Memory Access),即直接內存訪問,無需CPU干預,實現高速數據傳輸。數據的傳輸可以發生在:

? 外設和內存之間 :例如ADC采集數據到內存,這種傳輸方式常見于需要將外設采集的數據快速傳輸到內存進行處理的應用。

? 內存和內存之間 :例如在兩個不同的數組之間傳輸數據,或者在不同的內存塊之間進行數據拷貝。

? 外設和外設之間 :例如從一個SPI主/從機傳輸數據到另一個SPI從/主機。

使用DMA能夠有效減輕CPU的負擔,特別是在大量數據需要高效傳輸的情況下,可以提高系統的整體性能。

框圖

9ef6ad3b859e526939b1d50ce98b3cb53493144165354211_.jpg

特性

使用DMA,最核心的就是配置要傳輸的數據,包括數據從哪里來,要到哪里去,傳輸的數據的單位是什么,要傳多少數據,是一次傳輸還是連續傳輸等等。

4 條獨立DMA通道
3625f5c76a6b39256dd4c2e081854abe3493144165354211_.jpg

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

4種傳輸模式

硬件觸發BULK傳輸模式、硬件觸發BLOCK傳輸模式、軟件觸發BULK傳輸模式和軟件觸發BLOCK傳輸模式。
QQ圖片20240228162240.jpg

BULK傳輸模式 :

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

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

BLOCK傳輸模式 :

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

? 硬件觸發和軟件觸發:

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

51c1a122007e5f1b02dcbd819c8ef0123493144165354211_.jpg

可以產生DMA請求(DMA request),硬件觸發啟動DMA傳輸,
ab77011b6159b98f41225496ac5f6e2f3493144165354211_.jpg
而不支持硬件DMA的外設,只能配置為 軟件觸發啟動DMA傳輸 。
7c1277aa377d43761f820c354134c99d3493144165354211_.jpg

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

? DMA中斷

DMA通道在傳輸工程中可產生2個中斷標志:傳輸錯誤中斷標志和傳輸完成中斷標志

不同 DMA 通道的中斷各自獨立,通過中斷標志寄存器 DMA_ISR 可以獲取各通道的中斷標志。標志對應多個可能的產生原因,具體產生原因需查詢 DMA_CSRy.STATUS 狀態位,如下表所示
60bd017b9abd57ca9eabff17f4627fb63493144165354211_.jpg

? 數據寬度

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

? 數據塊數量

傳輸的數據塊數量可以設置為1 ~ 65535

? 數據傳輸優先級

當CPU和DMA訪問不同的外設時,數據的傳輸可以同時進行;

當CPU和DMA同時訪問同一個外設時,CPU的優先級高于DMA。

從外設到內存

BD網盤鏈接:

https://pan.baidu.com/s/1RlVVPt72fJrnBBUEHf3iJQ?pwd=oklw
提取碼:oklw

通過ADC轉換完成標志觸發(硬件觸發)DMA方式實現外設到內存的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數字段碼
#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配置函數
void DMA_Configuration(void);      //DMA配置函數
void LCD_Configuration(void);      //LCD配置函數
void LCD_Proc(uint16_t dispdata);  //LCD子程序函數

/*
**功能說明:
**ADC采集數據觸發DMA,將采集到的數據(1.2V內核電壓基準源)存儲在內存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;   //單通道單次轉換模式
  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;           //內置溫度傳感器失能
  ADC_InitStruct.ADC_DMASOCEn = ADC_DMASOCEnable;   //ADC轉換完成觸發DMA傳輸
  ADC_InitStruct.ADC_Align = ADC_AlignRight;         //ADC轉換結果右對齊
  ADC_InitStruct.ADC_AccEn = ADC_AccDisable;         //轉換結果累加不使能
  ADC_Init(&ADC_InitStruct);                        //初始化ADC配置
  CW_ADC- >CR1_f.DISCARD = FALSE;                    //ADC轉換結果保存策略配置:新數據覆蓋未被讀取的舊數據
  CW_ADC- >CR1_f.CHMUX = ADC_Vref1P2Input;           //待轉換通道配置:1.2V內核電壓基準源

  ADC_ClearITPendingBit(ADC_IT_EOC);
  ADC_ITConfig(ADC_IT_EOC, ENABLE);
  ADC_EnableNvic(ADC_INT_PRIORITY);

  ADC_Enable();
  ADC_SoftwareStartConvCmd(ENABLE);                  //開始轉換
}

void ADC_IRQHandler(void)
{
    /* USER CODE BEGIN */
  if(ADC_GetITStatus(ADC_IT_EOC) != RESET)
  {
      ADC_ClearITPendingBit(ADC_IT_EOC);
      ADC_SoftwareStartConvCmd(ENABLE);              //開始轉換
  }
    /* 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; //數據寬度32bit
  DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix; //源地址固定
  DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix;  //目標地址固定
  DMA_InitStruct.DMA_TransferCnt = 1;  //數據塊數量1
  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&(CW_ADC- >RESULT0);  //數據源地址 (外設)
  DMA_InitStruct.DMA_DstAddress = (uint32_t)&value;   //傳輸目標地址   (內存)
  DMA_InitStruct.TrigMode = DMA_HardTrig;  //硬件觸發DMA傳輸
  DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_SINGLETRANSCOM;  //硬件觸發源:ADC單次轉換完成標志
  DMA_Init(CW_DMACHANNEL1,&DMA_InitStruct); //DMA通道1
  DMA_ClearITPendingBit(DMA_IT_ALL);  //清除DMA中斷標志位
  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傳輸完成標志
    {
        DMA_ClearITPendingBit(DMA_IT_TC1);

        CW_DMACHANNEL1- >CNT = 0x10001;     //REPEAT寫1,傳輸數量為1
        DMA_Cmd(CW_DMACHANNEL1, ENABLE);
    }
    /* USER CODE END */
}

演示:ADC轉換結果為1580左右,換算成電壓:1580/4096*3.3=1.27V
bb14a42ed7249c53164cee59f53eb0083493144165354211_.jpg

從內存到內存

BD網盤鏈接:

https://pan.baidu.com/s/1ScCk-UqHBjJA5PxwSqMhkg?pwd=4701
提取碼:4701

通過軟件觸發DMA方式實現內存(FLASH)到內存(SRAM)的DMA傳輸

核心代碼

//單片機頭文件

#include "main.h"

#include "cw32l052_lcd.h"

#include "cw32l052_dma.h"

//硬件外設

#include "delay.h"

#include "gpio.h"

//C庫

#include < string.h >

 

#define NUM0 0x070d  //段式LCD數字段碼

#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] =   //源內存(FLASH)數據

{

  9999,8888,7777,6666,5555,

  4444,3333,2222,1111,0

};

 

uint16_t dstBuf[DATASIZE]={0};      //目標內存(SRAM)數據

 

void DMA_Configuration(void);      //DMA配置函數

void LCD_Configuration(void);      //LCD配置函數

void LCD_Proc(uint16_t dispdata);  //LCD子程序函數

 

uint32_t value=0;  //ADC數值

 

/*

**功能說明:

**將srcBuf數組中的數據通過DMA傳送到dstBuf數組中,

**srcBuf數組中的數據通過const關鍵詞存儲到FLASH中,

**dstBuf數組存儲在SRAM程序運行過程中

**傳輸完成后比較兩數組內容,相同則打開LED1和LED1,LCD上循環顯示dstBuf數據;

**不同則進入死循環,兩指示燈閃爍

*/

int main(void)

{

  LED_Init();

  LCD_Configuration();

  DMA_Configuration();

  DMA_SWTrigCmd(CW_DMACHANNEL1);   //使能通道1軟件觸發

  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數據

      {

        LCD_Proc(dstBuf[i]);

        Delay_ms(500);

      }

  }

  else  //如果不相同

  {

    while(1)  //進入while死循環

    {

      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; //數據寬度16bit

  DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Increase; //源地址固定

  DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Increase;  //目標地址遞增

  DMA_InitStruct.DMA_TransferCnt = DATASIZE;  //數據塊數量

  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&srcBuf[0];  //數據源地址 (內存)

  DMA_InitStruct.DMA_DstAddress = (uint32_t)&dstBuf[0];   //傳輸目標地址 (內存)

  DMA_InitStruct.TrigMode = DMA_SWTrig;  //軟件觸發DMA傳輸

 

  DMA_Init(CW_DMACHANNEL1,&DMA_InitStruct); //DMA通道1

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

}

演示:LCD屏上顯示通過DMA傳輸的dstBuf的數據
84d8e21c06ee1765cf4f14287e94e4733493144165354211_.jpg

從外設到外設

BD網盤鏈接:

https://pan.baidu.com/s/1fSyMPAapft2a_Vy_d3F9vw?pwd=dw6x
提取碼:dw6x

通過硬件觸發DMA方式實現外設(SPI)到外設(SPI)的DMA傳輸

核心代碼

/*單片機頭文件*/

#include "main.h"

/*硬件驅動*/

#include "delay.h"

#include "gpio.h"

#include "cw32l052_dma.h"

#include "cw32l052_spi.h"

/*C庫*/

#include < string.h >

 

//硬件連接

//SPIY_SCK  (PA10) -- SPIX_SCK  (PB13)

//SPIY_MISO (PA11) -- SPIX_MISO (PB14)

//SPIY_MOSI (PA12) -- SPIX_MOSI (PB15)

 

//SPI2相關定義(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相關定義(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()

 

//數組長度

#define   BUFFERSIZE                 ARRAY_SZ(TxBuffer1)

 

//發送內容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

                      };

//發送內容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];  //接收數組1

uint8_t RxBuffer2[BUFFERSIZE];  //接收數組2

uint8_t TxCounter = 0;  //發送計數

uint8_t RxCounter = 0;  //接收計數

 

uint8_t TransferStatus1 = 1;  //DMA傳輸狀態標志1

uint8_t TransferStatus2 = 1;  //DMA傳輸狀態標志2

 

void DMA_Configuration(void);      //DMA配置函數

void SPI_Configuration(void);      //SPI配置函數

void SPI_GPIO_Configuration(void); //SPI相關GPIO口配置

 

/*

**功能說明:

**主機SPIY發送TxBuffer1中的數據,從機SPIX通過DMA接收數據并存儲到RxBuffer1

**主機SPIY發送無效數據,啟動SPI通信,同時SPIX從機通過DMA發送TxBuffer2中的數據,SIPY接收數據并存儲到RxBuffer2

**單獨比較TxBuffer1與RxBuffer1、TxBuffer2與RxBuffer2中的內容,比較結果通過LED燈指示

*/

int main(void)

{

  LED_Init();               //初始化LED指示燈

  SPI_GPIO_Configuration(); //配置PI相關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);//等待發送緩沖空(為空后硬件自動置1)

    SPI_SendData(SPIY,TxBuffer1[TxCounter++]); //發送TxBuffer1中的數據,通過數據寄存器DR把數據填充到發送緩沖區中

  }

  while(DMA_GetFlagStatus(SPIX_RX_DMACHANNEL) != DMA_CHANNEL_STATUS_TRANSCOMPLETE);//等待DMA接收完成

 

  SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Set); //釋放從機SPIX,結束信號

  TransferStatus1 = memcmp(TxBuffer1, RxBuffer1, BUFFERSIZE); //對比兩數組數據

  if(TransferStatus1==0)  //如果數據相同

  {

    LED1_ON();  //LED1指示

  }

  else

  {

    LED1_OFF();

  }

 

  TxCounter = 0;

  SPI_ReceiveData(SPIY);//讀DR以清除RXNE(接收非空)標志位

  SPI_DMACmd(SPIX, SPI_DMAReq_Rx, DISABLE);//失能SPIX DMA RX

  SPI_FlushSendBuff(SPIX);//清空發送緩沖區和移位寄存器

  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){;} //主機發送數據以啟動SPI通信

    SPI_SendData(SPIY, TxBuffer1[TxCounter++]);

 

    while(SPI_GetFlagStatus(SPIY, SPI_FLAG_RXNE) == RESET){;}

      RxBuffer2[RxCounter++] = SPI_ReceiveData(SPIY);  //獲取接收緩沖區中的內容

  }

  while(SPI_GetFlagStatus(SPIY,SPI_FLAG_BUSY) == SET); //檢查數據是否已經全部通過SPI發送完畢

  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 復用

    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; //數據位寬8bit

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;  //時鐘極性

  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//時鐘相位,奇數邊緣采樣

  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; //數據寄存器

  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);

}

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10456

    瀏覽量

    206661
  • 內存
    +關注

    關注

    8

    文章

    2767

    瀏覽量

    72813
  • dma
    dma
    +關注

    關注

    3

    文章

    536

    瀏覽量

    99149
  • CW32
    +關注

    關注

    1

    文章

    122

    瀏覽量

    239
收藏 人收藏

    評論

    相關推薦

    CW32L052單片機支持DMA實現高速數據傳輸

    CW32L052支持DMA(Direct Memory Access),即直接內存訪問,無需CPU干預,實現高速數據傳輸。
    的頭像 發表于 02-27 11:36 ?628次閱讀

    什么是DMA直接內存訪問

    大家好,這是關于DMA的非?;镜膯栴}。1)什么是DMA直接內存訪問)和什么時候使用?2)它是如何提高CPU性能的?或如何獨立工作,以節省
    發表于 01-25 10:45

    什么是直接內存訪問DMA?

    我對DMA感到困惑。DMA是一種允許微控制器直接訪問另一個微控制器的存儲器的通信協議嗎?LED,如果不是,DMA是用來做什么的?謝謝:
    發表于 04-01 07:59

    超低功耗家族再添新成員,武漢芯源半導體發布32位M0+內核MCU CW32L052系列產品

    2023年2月,武漢芯源半導體超低功耗家族再添新成員——32位M0+內核MCU CW32L052系列芯片。CW32L052 是基于 eFlash 的單芯片低功耗微控制器,集成了主頻高達 48MHz
    發表于 02-21 14:02

    CW32L052微控制器數據手冊

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

    CW32L052微處理器用戶手冊

    CW32L052 內核為 32 位的 ARM? Cortex?-M0+ 微處理器,最大尋址空間為 4GB。芯片內置的程序存儲器、數據存儲器、各外設及端口寄存器被統一編址在同一個 4GB 的線性
    發表于 09-14 06:08

    CW32L052CxTx PCB封裝庫

    CW32L052CxTx PCB封裝庫(PADS)
    發表于 09-14 08:01

    CW32L052CxTx元件庫

    CW32L052CxTx元件庫(PADS)
    發表于 09-14 08:24

    CW32L052 StartKit軟件包

    CW32L052 StartKit 軟件包
    發表于 09-15 06:13

    CW32L052RxTx StartKit原理圖分享

    CW32L052RxTx StartKit原理圖
    發表于 09-15 07:35

    CW32L052R8T6 StartKit用戶手冊

    R8T6 StartKit 評估板需要搭配 CW-DAPLINK 調試器一起使用。CW32L052R8T6 StartKit 評估板帶有 CW32L052 StartKit 軟件包及 CW32
    發表于 09-15 06:04

    如何設置 DMA直接內存訪問

    本應用筆記解釋了使用 DMAC(直接存儲器訪問控制器)和 DTFR(DMA 觸發因子寄存器)的示例。
    的頭像 發表于 06-18 17:10 ?3254次閱讀
    如何設置 <b class='flag-5'>DMA</b>(<b class='flag-5'>直接</b><b class='flag-5'>內存</b><b class='flag-5'>訪問</b>)

    超低功耗家族再添新成員,武漢芯源半導體發布32位M0+內核MCU CW32L052系列產品

    2023年2月,武漢芯源半導體超低功耗家族再添新成員——32位M0+內核MCUCW32L052系列芯片。CW32L052是基于eFlash的單芯片低功耗微控制器,集成了主頻高達48MHz的ARM
    的頭像 發表于 02-21 14:03 ?644次閱讀
    超低功耗家族再添新成員,武漢芯源半導體發布32位M0+內核MCU <b class='flag-5'>CW32L052</b>系列產品

    STM32L4直接訪問內存模塊(DMA)介紹

    電子發燒友網站提供《STM32L4直接訪問內存模塊(DMA)介紹.pdf》資料免費下載
    發表于 08-01 10:15 ?1次下載
    STM32L4<b class='flag-5'>直接訪問</b><b class='flag-5'>內存</b>模塊(<b class='flag-5'>DMA</b>)介紹

    CW32L052 FLASH存儲器

    CW32L052內部集成了64KB嵌入式FLASH供用戶使用,可用來存儲應用程序和用戶數據。芯片支持對 FLASH 存儲器的讀、擦除和寫操作,支持擦寫保護和讀保護。芯片內置 FLASH 編程所需的高壓 BOOST 電路,無須額外提供編程電壓。
    的頭像 發表于 02-28 17:43 ?445次閱讀
    <b class='flag-5'>CW32L052</b> FLASH存儲器
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>