- 浏览: 689984 次
文章分类
STM32 DMA及其DAM与DA实现正弦波生成
DMA有什么用?
直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
有多少个DMA资源?
有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。
数据从什么地方送到什么地方?
外设到SRAM(I2C/UART等获取数据并送入SRAM);
SRAM的两个区域之间;
外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比);
SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形);
……还有一些目前还搞不清楚的。
DMA可以传递多少数据?
传统的DMA的概念是用于大批量数据的传输,但是我理解,在STM32中,它的概念被扩展了,也许更多的时候快速是其应用的重点。数据可以从1~65535个。
通道是如何分配的?
见下面的这个表:
如何来用DMA?
确定数据来源,确定数据目的地,选择使用哪个通道,设定传输多少个数据,设定数据传递模式等等就可以了。且读一下STM32提供给我们的例子。
//////////////////////////////////////////
……
这个是官方自带的例子,很好看懂~有不明白的给我留言。
直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
有多少个DMA资源?
有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。
数据从什么地方送到什么地方?
外设到SRAM(I2C/UART等获取数据并送入SRAM);
SRAM的两个区域之间;
外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比);
SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形);
……还有一些目前还搞不清楚的。
DMA可以传递多少数据?
传统的DMA的概念是用于大批量数据的传输,但是我理解,在STM32中,它的概念被扩展了,也许更多的时候快速是其应用的重点。数据可以从1~65535个。
通道是如何分配的?
见下面的这个表:
如何来用DMA?
确定数据来源,确定数据目的地,选择使用哪个通道,设定传输多少个数据,设定数据传递模式等等就可以了。且读一下STM32提供给我们的例子。
//////////////////////////////////////////
……
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR3_Address; //设定外围设备的地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_Buffer; //设定内存地址,SRC_Buffer是前面定义的一个数组 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //方向控制 DMA_InitStructure.DMA_BufferSize = 3; //缓冲区大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外围地址增量控制 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址增量控制 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA_PeripheralDataSize_HalfWord的值为0x100,后一个为0x400,在在stm32f10x_dma.h中定义,用于决定存储器数据宽度*/ DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 以下是stm32f10x_dma.c中有关DMA的初始化设置代码 tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode | DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc | DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize | DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M; DMAy_Channelx->CCR = tmpreg; /////看到了,这里对CCR寄存器进行了写操作,它把上面的那些设置都设定进去了。 DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize; DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr; DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr; //内存地址送入CMAR寄存器 ------------------------------------------------------------------------------------------ 再来看一个DMA的例子 DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); DMA_Cmd(DMA1_Channel5, ENABLE);
用DMA与DA产生正弦波的代码如下:
/** ****************************************************************************** * @file DAC/DualModeDMA_SineWave/main.c * @author MCD Application Team * @version V3.5.0 * @date 08-April-2011 * @brief Main program body. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2> ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "stm32f10x_dac.h" #include "stm32f10x_dma.h" #include "stm32f10x_tim.h" /** @addtogroup STM32F10x_StdPeriph_Examples * @{ */ /** @addtogroup DAC_DualModeDMA_SineWave * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define DAC_DHR12RD_Address 0x40007420 /* Init Structure definition */ DAC_InitTypeDef DAC_InitStructure; DMA_InitTypeDef DMA_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; uint32_t Idx = 0; /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ const uint16_t Sine12bit[32] = { 2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056, 3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, 599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647}; const uint16_t Sine12bitlow[32] = { 1024, 1224, 1415,1592,1749,1875,1970,2028,2048,2028, 1969, 1875, 1748,1592,1415,1224,1024,824,632,454, 600,172,78,19,0,19,78,172,300,454,632,824 }; uint32_t DualSine12bit[32]; /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void); void Delay(__IO uint32_t nCount); /* Private functions ---------------------------------------------------------*/ /** * @brief Main program. * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically connected to the DAC converter. In order to avoid parasitic consumption, the GPIO pin should be configured in analog */ GPIO_Configuration(); /* TIM2 Configuration */ /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 100; TIM_TimeBaseStructure.TIM_Prescaler = 100; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM2 TRGO selection */ TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); /* DAC channel1 Configuration */ DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); /* DAC channel2 Configuration */ DAC_Init(DAC_Channel_2, &DAC_InitStructure); /* Fill Sine32bit table */ for (Idx = 0; Idx < 32; Idx++) { DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]); } #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL /* DMA2 channel4 configuration */ DMA_DeInit(DMA2_Channel4); #else /* DMA1 channel4 configuration */ DMA_DeInit(DMA1_Channel4); #endif DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualSine12bit; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 32; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL DMA_Init(DMA2_Channel4, &DMA_InitStructure); /* Enable DMA2 Channel4 */ DMA_Cmd(DMA2_Channel4, ENABLE); #else DMA_Init(DMA1_Channel4, &DMA_InitStructure); /* Enable DMA1 Channel4 */ DMA_Cmd(DMA1_Channel4, ENABLE); #endif /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is automatically connected to the DAC converter. */ DAC_Cmd(DAC_Channel_1, ENABLE); /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is automatically connected to the DAC converter. */ DAC_Cmd(DAC_Channel_2, ENABLE); /* Enable DMA for DAC Channel2 */ DAC_DMACmd(DAC_Channel_2, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1) { } } /** * @brief Configures the different system clocks. * @param None * @retval None */ void RCC_Configuration(void) { /* Enable peripheral clocks ------------------------------------------------*/ #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL /* DMA2 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); #else /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); #endif /* GPIOA Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* DAC Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); /* TIM2 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); } /** * @brief Configures the different GPIO ports. * @param None * @retval None */ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically connected to the DAC converter. In order to avoid parasitic consumption, the GPIO pin should be configured in analog */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); } /** * @brief Inserts a delay time. * @param nCount: specifies the delay time length. * @retval None */ void Delay(__IO uint32_t nCount) { for(; nCount != 0; nCount--); } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
这个是官方自带的例子,很好看懂~有不明白的给我留言。
相关推荐
STM32F103使用用DMA+DAC 实现 50HZ正弦波输出 亲自测试输出稳定
此代码基于stm32,使用DMA的双缓冲机制和stm32片上DAC达到输出指定频率正弦波
STM32 可调正弦波发生程序(DMA).zip
正点原子探索者系列 STM32F4之dacdma高速输出正弦波加adcdma多通道高速采集信号,TFTLCD显示
STM32H750运用TIME和DMA传输,DAC输出双路可调相位差的正弦波发生器STM32CUBEMX生成MDK5编译
利用STM32实现了正弦波的输出,利用示波器可以清晰地监测出来。
本文件是关于使用STM32的DA模块连续输出正弦波信号与AD采集并配合matlab实时绘图的测试
采用stm32自带的DMA +DAC+TIMER来实现正弦波、三角波、方波、锯齿波的生成、频率可调
STM32 DAM配置例程,适用STM32各种芯片,详细的介绍了 DAM的配置过程。根据例子修改即可应用。
在STM32板子与电脑串口助手进行通信,用串口的DMA方式,先接收,再发送到PC端,可以连续接收,通过按键一次发送.
STM32DMA详细讲解,适用于初学者参考只用
stm32F103 DMA方式读A/D值 可连续读两路A/D值
(2)本资源使用stm32自带的ADC采集外部输入的正弦信号(外加信号需要偏置,因为32自带ADC采集0~3.3V)。 (3)采用stm32官方DSP库的FFT算法处理数据(64,256,1024点处理) (4)计算正弦波失真度。 (5) 采样频率...
stm32f103 定时器 PWM 模式 搭配 DMA 输出 精确脉冲注意事项1.压缩包内并未包括stm32外设固件库驱动,需要下载后,设置自己的include目录具体自行百度。因为如果包括驱动会很大,另外,自己项目复制起来也会很大。2....
于是就想到用DMA来接收串口数据,这个STM32也是支持的。但是关键的一点,怎么知道数据接收完毕了呢?如果接收的数据长度固定,那就好办,直接设置DMA的接收数据个数就行了。但是如果长度不固定了,那应该怎么办了?
学习使用contex-m3的stm32f103c6的程序库,DMA驱动程序。
目前STM32家族中有些系列支持DMA的双缓冲模式,比如STM32F2/STM32F4/STM32F7等系列。尤其随着人们对STM32F4/F7系列应用不断拓宽和加深,在设计中运用到DMA双缓冲的场合也越来越多。STM32芯片中的DMA又可分为两大类,...
STM32F103通过DMA方式用DAC产生正弦波
本程序实现STM32 DMA中断模式下ADC多通道数据采集,并经过简单的均值滤波,亲测可用。 若有错误之处,希望读者指出,大家共同学习,一起进步!