CW32L052单片机DMA直接内存访问怎么做?

2024-03-16 武汉芯源 微信公众号
单片机,CW32L052,武汉芯源 单片机,CW32L052,武汉芯源 单片机,CW32L052,武汉芯源 单片机,CW32L052,武汉芯源


概述

CW32L052支持DMA(Direct Memory Access),即直接内存访问,无需CPU干预实现高速数据传输。数据的传输可以发生在:

• 外设和内存之间:例如ADC采集数据到内存,这种传输方式常见于需要将外设采集的数据快速传输到内存进行处理的应用。

• 内存和内存之间:例如在两个不同的数组之间传输数据,或者在不同的内存块之间进行数据拷贝。

• 外设和外设之间:例如从一个SPI主/从机传输数据到另一个SPI从/主机。

 

使用DMA能够有效减轻CPU的负担,特别是在大量数据需要高效传输的情况下,可以提高系统的整体性能。


框图

DMA功能框图


特性

使用DMA,最核心的就是配置要传输的数据,包括数据从哪里来,要到哪里去,传输的数据的单位是什么,要传多少数据,是一次传输还是连续传输等等。


· 4 条独立DMA通道:

4个DMA通道的优先级和通道号绑定,通道号越小优先级越高,通道号越大优先级越低。


· 4种传输模式

硬件触发BULK传输模式、硬件触发BLOCK传输模式、软件触发BULK传输模式和软件触发BLOCK传输模式。


BULK传输模式

适用于小数据块的传输,通常涉及大量的数据点,但每个数据点的大小较小。


BLOCK模式不同,BULK模式下DMA会更频繁地启动新的传输,因为每个数据点通常被视为单独的传输单元,所以DMA控制器需要在每个数据点传输完成后需要重新配置或者启动DMA。在BULK传输模式下,传输过程不可被打断。

BULK传输模式

适用于大数据块的高速传输,通常用于需要连续传输大量数据的情况。


BLOCK模式下,DMA会将数据分成较大的块,并在传输时以这些块为单位进行操作。DMA控制器在一次配置后,连续传输多个数据块,而无需额外的干预或重新配置。每传输完成1个数据块后就要进行一次传输优先级的仲裁,允许CPU或者更高优先级的DMA通道访问当前DMA通道所占用的外设。


硬件触发和软件触发

要想通过DMA来传输数据,必须先给DMA控制器发送DMA请求。部分外设支持硬件触发启动DMA传输,如FLASH存储器、UART串口、TIM定时器、ADC数模转换器等被配置为DMA通道的触发源时。


可以产生DMA请求(DMA request),硬件触发启动DMA传输,

而不支持硬件DMA的外设,只能配置为软件触发启动DMA传输。


虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一个,不能同时接收多个。


• DMA中断

DMA通道在传输工程中可产生2个中断标志:传输错误中断标志和传输完成中断标志。


不同 DMA 通道的中断各自独立,通过中断标志寄存器 DMA_ISR 可以获取各通道的中断标志。标志对应多个可能的产生原因,具体产生原因需查询 DMA_CSRy.STATUS 状态位,如下表所示:

• 数据宽度

数据位宽可以设置为8bit、16bit和32bit,DMA通道的源地址和目的地址的位宽必须完全一致。


• 数据块数量

传输的数据块数量可以设置为1 ~ 65535。


• 数据传输优先级

当CPU和DMA访问不同的外设时,数据的传输可以同时进行;当CPU和DMA同时访问同一个外设时,CPU的优先级高于DMA。


从外设到内存


通过ADC转换完成标志触发(硬件触发)DMA方式实现外设到内存的DMA传输:


· 核心代码

1 #include "main.h"

2 #include "delay.h"

3 #include "gpio.h"

4 #include "cw32l052_lcd.h"

5 #include "cw32l052_adc.h"

6 #include "cw32l052_dma.h"  

7

8 #define NUM0 0x070d  //段式LCD数字段码

9 #define NUM1 0x0600

10 #define NUM2 0x030e

11 #define NUM3 0x070a

12 #define NUM4 0x0603

13 #define NUM5 0x050b

14 #define NUM6 0x050f

15 #define NUM7 0x0700

16 #define NUM8 0x070f

17 #define NUM9 0x070b

18

19 void ADC_Configuration(void);      //ADC配置函数

20 void DMA_Configuration(void);      //DMA配置函数

21 void LCD_Configuration(void);      //LCD配置函数

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

23

24  /*

25 **功能说明:

26 **ADC采集数据触发DMA,将采集到的数据(1.2V内核电压基准源)存储在内存value中,并显示在LCD屏上

27 */ 


28 int main(void)

29 {   

30   LED_Init();

31   LCD_Configuration();

32   ADC_Configuration();   

33   DMA_Configuration();   

34   while (1)   

35   {     

36     LCD_Proc(value);  //显示采集到的ADC

37     PA15_TOG();

38     Delay_ms(500);

39   }

40 }  

41

42 void ADC_Configuration(void)

43 {   

44   ADC_InitTypeDef   ADC_InitStruct = {0};

45

46   __RCC_ADC_CLK_ENABLE();

47   __RCC_GPIOA_CLK_ENABLE();

48

49   PA00_ANALOG_ENABLE();

50 


51   ADC_InitStruct.ADC_OpMode = ADC_SingleChOneMode;   //单通道单次转换模式   

52   ADC_InitStruct.ADC_ClkDiv = ADC_Clk_Div128;       //PCLK   

53   ADC_InitStruct.ADC_SampleTime = ADC_SampTime5Clk; //5个ADC时钟周期   

54   ADC_InitStruct.ADC_VrefSel = ADC_Vref_VDDA;       //VDDA参考电压(3.3V)   

55   ADC_InitStruct.ADC_InBufEn = ADC_BufEnable;       //开启跟随器   

56   ADC_InitStruct.ADC_TsEn = ADC_TsDisable;           //内置温度传感器失能   

57   ADC_InitStruct.ADC_DMASOCEn = ADC_DMASOCEnable;   //ADC转换完成触发DMA传输   

58   ADC_InitStruct.ADC_Align = ADC_AlignRight;         //ADC转换结果右对齐   

59   ADC_InitStruct.ADC_AccEn = ADC_AccDisable;         //转换结果累加不使能   

60   ADC_Init(&ADC_InitStruct);                        //初始化ADC配置      

61   CW_ADC->CR1_f.DISCARD = FALSE;                    //ADC转换结果保存策略配置:新数据覆盖未被读取的旧数据          

62   CW_ADC->CR1_f.CHMUX = ADC_Vref1P2Input;           //待转换通道配置:1.2V内核电压基准源    

63

64   ADC_ClearITPendingBit(ADC_IT_EOC);   

65   ADC_ITConfig(ADC_IT_EOC, ENABLE);   

66   ADC_EnableNvic(ADC_INT_PRIORITY);    

67

68   ADC_Enable();   

69   ADC_SoftwareStartConvCmd(ENABLE);                  //开始转换

70 }  

71

72 void ADC_IRQHandler(void)

73 {     

74     /* USER CODE BEGIN */   

75   if(ADC_GetITStatus(ADC_IT_EOC) != RESET)

76   {

77       ADC_ClearITPendingBit(ADC_IT_EOC);

78       ADC_SoftwareStartConvCmd(ENABLE);              //开始转换   

79   }     

80     /* USER CODE END */ 

81 }  

82

83 void NVIC_Configuration(void)

84 {

85   __disable_irq();

86      

87   NVIC_ClearPendingIRQ(DMACH1_IRQn);

88

89   NVIC_EnableIRQ(DMACH1_IRQn);

90

91   __enable_irq();

92 }

93

94 void DMA_Configuration(void)

95 {

96   DMA_InitTypeDef DMA_InitStruct = {0};

97

98   __RCC_DMA_CLK_ENABLE();

99

100  DMA_StructInit(&DMA_InitStruct);


101  DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK;     //BLOCK模式

102  DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_32BIT; //数据宽度32bit   

103  DMA_InitStruct.DMA_SrcInc = DMA_SrcAddress_Fix; //源地址固定   

104  DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Fix;  //目标地址固定   105  DMA_InitStruct.DMA_TransferCnt = 1;  //数据块数量1   

106  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&(CW_ADC->RESULT0);  //数据源地址 (外设)   

107  DMA_InitStruct.DMA_DstAddress = (uint32_t)&value;   //传输目标地址   (内存)   

108  DMA_InitStruct.TrigMode = DMA_HardTrig;  //硬件触发DMA传输   

109  DMA_InitStruct.HardTrigSource = DMA_HardTrig_ADC_SINGLETRANSCOM;  //硬件触发源:ADC单次转换完成标志   

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

111  DMA_ClearITPendingBit(DMA_IT_ALL);  //清除DMA中断标志位   

112  DMA_ITConfig(CW_DMACHANNEL1, DMA_IT_TC, ENABLE);   //使能DMA通道1中断   

113  NVIC_Configuration();   

114  DMA_Cmd(CW_DMACHANNEL1, ENABLE); //启动DMA通道1进行传输

115 }  

116

117 void DMACH1_IRQHandler(void)

118 {     

119     /* USER CODE BEGIN */   

120   if( DMA_GetITStatus(DMA_IT_TC1) )  //DMA通道1传输完成标志     

121     {         

122         DMA_ClearITPendingBit(DMA_IT_TC1);

123          

124         CW_DMACHANNEL1->CNT = 0x10001;     //REPEAT写1,传输数量为1                                

125         DMA_Cmd(CW_DMACHANNEL1, ENABLE);      

126     }     

127     /* USER CODE END */ 

128 }


演示:ADC转换结果为1580左右,换算成电压:1580/4096*3.3=1.27V


从内存到内存


通过软件触发DMA方式实现内存(FLASH)到内存(SRAM)的DMA传输:


· 核心代码

1 //单片机头文件

2 #include "main.h"

3 #include "cw32l052_lcd.h"

4 #include "cw32l052_dma.h"

5 //硬件外设

6 #include "delay.h"

7 #include "gpio.h"

8 //C库

9 #include <string.h>

10

11 #define NUM0 0x070d  //段式LCD数字段码

12 #define NUM1 0x0600

13 #define NUM2 0x030e

14 #define NUM3 0x070a

15 #define NUM4 0x0603

16 #define NUM5 0x050b

17 #define NUM6 0x050f

18 #define NUM7 0x0700

19 #define NUM8 0x070f

20 #define NUM9 0x070b

21

22 #define DATASIZE 10

23

24 uint16_t const srcBuf[DATASIZE] =   //源内存(FLASH)数据

25 {  

26   9999,8888,7777,6666,5555,  

27   4444,3333,2222,1111,0

28 };

29

30 uint16_t dstBuf[DATASIZE]={0};      //目标内存(SRAM)数据

31

32 void DMA_Configuration(void);      //DMA配置函数

33 void LCD_Configuration(void);      //LCD配置函数

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

35

36 uint32_t value=0;  //ADC数值

37

38 /*

39 **功能说明:

40 **将srcBuf数组中的数据通过DMA传送到dstBuf数组中,

41 **srcBuf数组中的数据通过const关键词存储到FLASH中,

42 **dstBuf数组存储在SRAM程序运行过程中

43 **传输完成后比较两数组内容,相同则打开LED1和LED1,LCD上循环显示dstBuf数据;

44 **不同则进入死循环,两指示灯闪烁

45 */

46 int main(void)

47 {

48   LED_Init();

49   LCD_Configuration();

50   DMA_Configuration();  

51   DMA_SWTrigCmd(CW_DMACHANNEL1);   //使能通道1软件触发  

52 while(DMA_GetFlagStatus(CW_DMACHANNEL1)!=DMA_CHANNEL_STATUS_TRANSCOMPLETE); //等待传输完成

53   if(memcmp(srcBuf,dstBuf,DATASIZE)==0)  //如果srcBuf和dstBuf相同  

54   {      

55       LED1_ON(); //指示灯      

56       LED2_ON();      

57       for(int i=0;i<10;i++)  //LCD屏显示dstBuf数据      

58       {        

59         LCD_Proc(dstBuf[i]);

60         Delay_ms(500);

61       }  

62   }  

63   else  //如果不相同  

64   {    

65     while(1)  //进入while死循环    

66     {      

67       PA15_TOG();  //指示灯      

 

68       PC10_TOG();      

69       Delay_ms(500);

70     }  

71   }    

72

73   while (1)  

74   {      

75

76   }

77 }
78

79 void DMA_Configuration(void)

80 {  

81   DMA_InitTypeDef DMA_InitStruct = {0};    

82

83   __RCC_DMA_CLK_ENABLE();    

84   DMA_StructInit(&DMA_InitStruct);   

85   DMA_InitStruct.DMA_Mode = DMA_MODE_BLOCK;     //BLOCK模式  

86   DMA_InitStruct.DMA_TransferWidth = DMA_TRANSFER_WIDTH_16BIT; //数据宽度16bit  

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

88   DMA_InitStruct.DMA_DstInc = DMA_DstAddress_Increase;  //目标地址递增  

89   DMA_InitStruct.DMA_TransferCnt = DATASIZE;  //数据块数量  

90   DMA_InitStruct.DMA_SrcAddress = (uint32_t)&srcBuf[0];  //数据源地址 (内存)  

91   DMA_InitStruct.DMA_DstAddress = (uint32_t)&dstBuf[0];   //传输目标地址 (内存)  

92   DMA_InitStruct.TrigMode = DMA_SWTrig;  //软件触发DMA传输

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

94   

95   DMA_Cmd(CW_DMACHANNEL1, ENABLE); //启动DMA通道1进行传输

96 }


演示:LCD屏上显示通过DMA传输的dstBuf的数据


从外设到内设


通过硬件触发DMA方式实现外设(SPI)到外设(SPI)的DMA传输:

· 核心代码

1 /*单片机头文件*/

2 #include "main.h"

3 /*硬件驱动*/

4 #include "delay.h"

5 #include "gpio.h"

6 #include "cw32l052_dma.h"

7 #include "cw32l052_spi.h"

8 /*C库*/

9 #include <string.h>

10

11 //硬件连接

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

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

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

15

16 //SPI2相关定义(Master)

17 #define    SPIX                     CW_SPI2               

18 #define   SPIX_GPIO          CW_GPIOB

19 #define    SPIX_SCK_PIN             GPIO_PIN_13

20 #define   SPIX_MISO_PIN            GPIO_PIN_14

21 #define    SPIX_MOSI_PIN            GPIO_PIN_15

22 #define    SPIX_AF_SCK              PB13_AFx_SPI2SCK()

23 #define    SPIX_AF_MISO             PB14_AFx_SPI2MISO()

24 #define    SPIX_AF_MOSI             PB15_AFx_SPI2MOSI()

25 #define    SPIX_RX_DMACHANNEL       CW_DMACHANNEL1

26 #define    SPIX_TX_DMACHANNEL       CW_DMACHANNEL2  

27 #define     SPIX_DMA_RXTRIGSOURCE    DMA_HardTrig_SPI2_RXBufferNE

28 #define     SPIX_DMA_TXTRIGSOURCE    DMA_HardTrig_SPI2_TXBufferE

29

30 //SPI1相关定义(Slave)

31 #define    SPIY                     CW_SPI1

32 #define   SPIY_GPIO          CW_GPIOA

33 #define    SPIY_SCK_PIN             GPIO_PIN_10

34 #define    SPIY_MISO_PIN            GPIO_PIN_11

35 #define    SPIY_MOSI_PIN            GPIO_PIN_12

36 #define    SPIY_AF_SCK              PA10_AFx_SPI1SCK()

37 #define    SPIY_AF_MISO             PA11_AFx_SPI1MISO()

38 #define    SPIY_AF_MOSI             PA12_AFx_SPI1MOSI()

39

40 //数组长度

41 #define   BUFFERSIZE                 ARRAY_SZ(TxBuffer1)

42

43 //发送内容1

44 uint8_t TxBuffer1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,                       

45                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,

46                        0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,                       

47                        0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C,                       

48                        0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23                      

49                        };

50 //发送内容2

51 uint8_t TxBuffer2[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,                       52                        0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,                       

53                        0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,                       

54                        0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,                       

55                        0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83                      

56                        };

57

58 uint8_t RxBuffer1[BUFFERSIZE];  //接收数组1

59 uint8_t RxBuffer2[BUFFERSIZE];  //接收数组2

60 uint8_t TxCounter = 0;  //发送计数

61 uint8_t RxCounter = 0;  //接收计数  

62 

63 uint8_t TransferStatus1 = 1;  //DMA传输状态标志1

64 uint8_t TransferStatus2 = 1;  //DMA传输状态标志2

65

66 void DMA_Configuration(void);      //DMA配置函数

67 void SPI_Configuration(void);      //SPI配置函数

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

69


70 /*

71 **功能说明:

72 **主机SPIY发送TxBuffer1中的数据,从机SPIX通过DMA接收数据并存储到RxBuffer1

73 **主机SPIY发送无效数据,启动SPI通信,同时SPIX从机通过DMA发送TxBuffer2中的数据,SIPY接收数据并存储到RxBuffer2

74 **单独比较TxBuffer1与RxBuffer1、TxBuffer2与RxBuffer2中的内容,比较结果通过LED灯指示

75 */

76 int main(void)

77 {

78   LED_Init();               //初始化LED指示灯  

79   SPI_GPIO_Configuration(); //配置PI相关GPIO口  

80   DMA_Configuration();      //配置DMA传输  

81   SPI_Configuration();      //配置SPI传输  

82   SPI_DMACmd(SPIX, SPI_DMAReq_Rx, ENABLE); //使能SPIX DMA RX  

83    SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Reset);//位选CS选中从机SPIX,起始信号  

84   while(TxCounter < BUFFERSIZE)  

85   {

86     while(SPI_GetFlagStatus(SPIY,SPI_FLAG_TXE) == RESET);//等待发送缓冲空(为空后硬件自动置1)    

87     SPI_SendData(SPIY,TxBuffer1[TxCounter++]); //发送TxBuffer1中的数据,通过数据寄存器DR把数据填充到发送缓冲区中

88   } 

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

90  

91   SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Set); //释放从机SPIX,结束信号  

92    TransferStatus1 = memcmp(TxBuffer1, RxBuffer1, BUFFERSIZE); //对比两数组数据

93  if(TransferStatus1==0)  //如果数据相同

94  {    

95    LED1_ON();  //LED1指示  

96  }  

97  else  

98  {    

99    LED1_OFF();  

100 }

101

102   TxCounter = 0;  

103   SPI_ReceiveData(SPIY);//读DR以清除RXNE(接收非空)标志位  

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

105   SPI_FlushSendBuff(SPIX);//清空发送缓冲区和移位寄存器  

106   SPI_DMACmd(SPIX, SPI_DMAReq_Tx, ENABLE);//使能SPIX DMA TX  

107   SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Reset);  

108   while(TxCounter < BUFFERSIZE)  

109   {          

110     while(SPI_GetFlagStatus(SPIY, SPI_FLAG_TXE) == RESET){;} //主机发送数据以启动SPI通信    

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

112

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

114     RxBuffer2[RxCounter++] = SPI_ReceiveData(SPIY);  //获取接收缓冲区中的内容

115   }  

116   while(SPI_GetFlagStatus(SPIY,SPI_FLAG_BUSY) == SET); //检查数据是否已经全部通过SPI发送完毕    

117   SPI_NSSInternalSoftwareConfig(SPIX, SPI_NSSInternalSoft_Set); //释放  

118   TransferStatus2 = memcmp(TxBuffer2, RxBuffer2, BUFFERSIZE);  //检查

119  if(TransferStatus2 == 0)  

120  {    

121    LED2_ON();

122  }

123  else

124  {

125    LED2_OFF();

126  }

127  while (1)

128  {

129

130  }

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

}

授权代理商:世强先进(深圳)科技股份有限公司
技术资料,数据手册,3D模型库,原理图,PCB封装文件,选型指南来源平台:世强硬创平台www.sekorm.com
现货商城,价格查询,交期查询,订货,现货采购,在线购买,样品申请渠道:世强硬创平台电子商城www.sekorm.com/supply/
概念,方案,设计,选型,BOM优化,FAE技术支持,样品,加工定制,测试,量产供应服务提供:世强硬创平台www.sekorm.com
集成电路,电子元件,电子材料,电气自动化,电机,仪器全品类供应:世强硬创平台www.sekorm.com
  • +1 赞 0
  • 收藏
  • 评论 0

本文由Kong转载自武汉芯源 微信公众号,原文标题为:CW32L052单片机DMA直接内存访问,本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关研发服务和供应服务

评论

   |   

提交评论

全部评论(0

暂无评论

相关推荐

【经验】芯源CW32系列单片机低功耗模式介绍及UART深度休眠模式示例

CW32单片机低功耗模式介绍及UART深度休眠模式示例。

2023-05-31 -  设计经验 代理服务 技术支持 采购服务

武汉芯源CW32系列单片机数字电压电流表产品硬件设计指南

本文基于武汉芯源CW32系列单片机,介绍数字电压电流表产品硬件设计指南,希望对各位工程师有所帮助。

2024-06-20 -  设计经验 代理服务 技术支持 采购服务

单片机硬件抗干扰常用方法

影响单片机系统可靠安全运行的主要因素主要来自系统内部和外部的各种电气干扰,并受系统结构设计、元器件选择、安装、制造工艺影响。这些都构成单片机系统的干扰因素,常会导致单片机系统运行失常,轻则影响产品质量和产量,重则会导致事故,造成重大经济损失。

2024-09-12 -  设计经验 代理服务 技术支持 采购服务

采用TSSOP20封装的高性能32位单片机PY32F003,凭借高性价比降维打击吊打8位单片机市场

安信泰AXTEK PY32F003是目前市面上一颗比较火的高性价比的MCU,市场价格普遍低于很多8位单片机,非常有竞争力;采用Cortex M0+核心,支持硬件乘法,支持中断向量重定向;常见的TSSOP-20,SO-8,DFN-8,SO-16,QFN-20,MSOP-10,QFN-32,LQFP-32封装都有。

2024-02-09 -  产品 代理服务 技术支持 采购服务

晶振为什么是单片机系统的核心?

晶振为什么是单片机系统的核心?本文TROQ创捷电子来给大家分享一二。单片机晶振,也称为石英晶体振荡器,是单片机系统中不可或缺的元件之一。它能够为单片机提供稳定的时钟信号,确保单片机正常运行。在单片机系统中,晶振结合内部的电路,产生单片机所必需的时钟频率,单片机的一切指令的执行都是建立在这个基础上的。

2024-11-16 -  产品 代理服务 技术支持 采购服务

单片机晶振的工作原理与常用频率

单片机晶振是单片机内部电路产生单片机所需的时钟频率的部件,单片机晶振提供的时钟频率越高,那么单片机运行速度就越快,单片接的一切指令的执行都是建立在单片机晶振提供的时钟频率。单片机晶振常用的频点:110592晶振。

2024-06-17 -  技术探讨 代理服务 技术支持 采购服务

CMS80F262x 增强型闪存1T 8051单片机数据手册

描述- 本资料为CMS80F262x系列单片机的数据手册,详细介绍了该系列单片机的特性、功能、存储结构、管脚定义、GPIO特性、功能概要等。该系列单片机是一款增强型闪存8051单片机,具有64KB程序区、256B RAM空间、4KB XRAM、1KB数据FLASH,支持多种振荡方式和多种工作模式,内置多种外设,如定时器、ADC、PWM、LCD、LED等,适用于各种嵌入式应用。

型号- CMS80F262X 系列,CMS80F2629,CMS80F262X,CMS80F26282,CMS80F262C,CMS80F262B,CMS80F262A

2024 年 8 月  - 中微半导体  - 数据手册  - Rev. 1.0.5 代理服务 技术支持 采购服务

【技术】武汉芯源CW32单片机UART基本数据收发功能介绍

通用异步收发器是一种通用串行数据总线,常用于系统内各子模块间的数据交换。本文将以武汉芯源推出的CW32系列单片机的CW32L083为例,介绍UART基本数据收发功能。

2023-04-25 -  技术探讨 代理服务 技术支持 采购服务

为什么叫单片机烧写呢?

单片机启动时会直接运行这些芯片中的程序,完成既定的功能。所谓烧写,其实就是对单片机中的rom进行擦写。现代工艺下,rom已经可以进行多次擦写,但在早期,rom只能一次性设计好,例如早期的PLC,把二极管上的丝烧了后就永久编码出1。

2023-10-18 -  技术探讨

【经验】CW32F030C8T6单片机如何通过看手册配置时钟树

本章简单展示了如何查找手册来配置寄存器,且再次强调库函数的本质就是操作寄存器。单片机都会有一个时钟树,时钟树的图可以在编程手册(不是数据表和内核手册)中找到。部分单片机想要工作在高工作频率下,需要设置flash等待时间并打开缓存和预取指令使能。

2023-10-02 -  设计经验 代理服务 技术支持 采购服务

如何使用CW32单片机通过ESP8266连接OneNET物联网平台,发送温湿度数据到平台,并接受平台的云控制?

本实验使用到了CW32-48F大学计划开发板、DHT11温湿度传感器模块、ESP8266WIFI模块及Keil5开发环境。

2023-12-06 -  设计经验 代理服务 技术支持 采购服务

单片机:科技舞台上的灵动舞者

单片机,全称为单片微型计算机,是一种集成在一块芯片上的微型计算机。它虽然体积微小,却蕴含着巨大的能量。就像一个迷你的智慧大脑,能够精确地控制和协调各种设备的运行。它就像是一位默默无闻的幕后英雄,为我们的生活带来了极大的便利。

2024-09-07 -  应用方案 代理服务 技术支持 采购服务

英锐芯提供8位OTP单片机等多种类型的单片机,可满足移动电源、加湿器、无线遥控灯等应用需求

英锐芯目前可以开发应用的单片机类型有8位OTP单片机或MTP单片机(MCU),包括普通IO口型(带触摸功能跟不带触摸功能)、AD型 MCU(带触摸跟不带触摸)。8位FLASH单片机(MCU)包括普通IO口型(带触摸功能跟不带触摸功能)、AD型MCU(带触摸跟不带触摸)。

2023-02-01 -  原厂动态 代理服务 技术支持 采购服务

【经验】武汉芯源CW32L083单片机的RTC功能介绍

CW32L083内置经独立校准的32kHz频率的RC时钟源,为RTC提供驱动时钟,RTC可在深度休眠模式下运行, 适用于要求低功耗的应用场合。本文是CW32L083单片机的RTC设置时间及闹钟部分的介绍,CW32其他型号也可以参考此文。

2023-02-09 -  设计经验 代理服务 技术支持 采购服务

解析CW32单片机的独立看门狗IWDT和窗口看门狗WWDT

看门狗在那些对安全性和稳定性要求较高的应用中特别重要,如工业控制、汽车电子、医疗设备和航空航天等领域。通过使用看门狗,可以大大减少系统因软件故障而导致的长时间不可用或错误操作的风险。本文介绍CW32单片机的两个看门狗:独立看门狗IWDT和窗口看门狗WWDT。

2024-08-17 -  技术探讨 代理服务 技术支持 采购服务
展开更多

电子商城

查看更多

品牌:瑞纳捷

品类:低功耗通用MCU

价格:¥2.1667

现货: 291,270

品牌:瑞纳捷

品类:低功耗通用MCU

价格:¥1.2667

现货: 78,202

品牌:瑞纳捷

品类:低功耗通用MCU

价格:¥1.1667

现货: 36,712

品牌:SILICON LABS

品类:Mixed-Signal MCU

价格:¥12.9143

现货: 33,058

品牌:瑞纳捷

品类:低功耗通用MCU

价格:¥1.1667

现货: 26,123

品牌:SILICON LABS

品类:Mixed-Signal MCU

价格:¥12.1718

现货: 14,132

品牌:SILICON LABS

品类:32位MCU

价格:¥24.8076

现货: 10,000

品牌:SILICON LABS

品类:8b Wireless MCU

价格:¥7.2474

现货: 9,029

品牌:瑞纳捷

品类:低功耗通用MCU

价格:¥1.2667

现货: 6,020

品牌:SILICON LABS

品类:8位MCU

价格:¥101.4587

现货: 5,361

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

现货市场

查看更多

品牌:RENESAS

品类:microcontroller

价格:¥2.8532

现货:188,410

品牌:RENESAS

品类:MCU

价格:¥5.8041

现货:86,925

品牌:RENESAS

品类:32-BIT GENERAL MCU

价格:¥7.3800

现货:76,715

品牌:RENESAS

品类:32-BIT GENERAL MCU

价格:¥15.3000

现货:75,000

品牌:RENESAS

品类:32-BIT GENERAL MCU

价格:¥257.6400

现货:58,799

品牌:RENESAS

品类:microcontroller

价格:¥32.9564

现货:40,179

品牌:RENESAS

品类:MCU

价格:¥19.4999

现货:39,498

品牌:RENESAS

品类:MCU

价格:¥39.8484

现货:38,160

品牌:RENESAS

品类:MCU

价格:¥78.9058

现货:34,935

品牌:RENESAS

品类:MCU

价格:¥49.6804

现货:32,610

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

品牌:

品类:

价格:

现货:

服务

查看更多

工控触摸一体机定制

提供7~27寸工控机定制,支持嵌⼊式/ 壁挂式 /桌⾯式/悬挂式等安装方式,采用纯平⾯板IP65防尘防⽔等级,莫⽒7级硬度触摸屏,兼容多种操作系统:组态软件/安卓/XP/win7/8/10/Linux等,支持主板、接⼝、外观、⽀架、刷卡器、⾝份证阅读器、LOGO、⻨克⻛、系统、电池、蓝⽛、4G/5G、摄像头、GPS系统、⼆维码扫描器、指纹等特殊应⽤场景定制

最小起订量: 1台 提交需求>

丙烯酸/环氧/有机硅导热胶定制

可定制导热胶的导热系数1~6W、粘度范围3000~250000cps、固化方式可加热、仅室温、可UV;施胶方式:点胶机、手工、喷胶、转印;支持颜色、硬度、固化时间等参数的个性化定制。

最小起订量: 1支 提交需求>

查看更多

授权代理品牌:接插件及结构件

查看更多

授权代理品牌:部件、组件及配件

查看更多

授权代理品牌:电源及模块

查看更多

授权代理品牌:电子材料

查看更多

授权代理品牌:仪器仪表及测试配组件

查看更多

授权代理品牌:电工工具及材料

查看更多

授权代理品牌:机械电子元件

查看更多

授权代理品牌:加工与定制

世强和原厂的技术专家将在一个工作日内解答,帮助您快速完成研发及采购。
我要提问

954668/400-830-1766(工作日 9:00-18:00)

service@sekorm.com

研发客服
商务客服
服务热线

联系我们

954668/400-830-1766(工作日 9:00-18:00)

service@sekorm.com

投诉与建议

E-mail:claim@sekorm.com

商务合作

E-mail:contact@sekorm.com

收藏
收藏当前页面