STM32 DMA及其DAM与DA实现正弦波生成

来源:互联网 发布:网络综艺的论文 编辑:程序博客网 时间:2024/06/18 06:16
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提供给我们的例子。
//////////////////////////////////////////
……
 
 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****/

这个是官方自带的例子,很好看懂~有不明白的给我留言。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 法院判刑后被告逃亡监护人怎么办 二审判决后不服的怎么办 对树木对生物花草过敏怎么办 高一英语成绩差怎么办 文章被同时录用该怎么办 来不及开ei检索证明怎么办 淘宝生产许可编号一定要填怎么办 官网下单被砍单怎么办美卡美私 大学网络课程挂了怎么办 如果二审超过6个月还不判怎么办? sci的proof时间超了怎么办 合肥电大考试没过怎么办 社保账号密码忘记了怎么办 住房公积金账号密码忘记了怎么办 燃气费单子丢了怎么办 商标初审公告期内被异议怎么办 手被山药痒了怎么办 9个月宝宝不吃奶粉怎么办 八个月宝宝拉粑粑费劲怎么办? 两个月小孩不吃奶粉怎么办 两个月的小孩不吃奶粉怎么办 两个多月宝宝不吃奶怎么办 三个多月宝宝不爱吃奶怎么办 4个月宝宝不吃奶怎么办 5个月宝宝不爱吃奶怎么办 九个月宝宝一直流鼻涕怎么办 九个月宝宝一直咳嗽怎么办 宝宝3岁不爱喝水怎么办 1岁宝宝不肯喝水怎么办 三个月宝宝体检说严重缺钙怎么办 1岁半宝宝不吃药怎么办 1岁宝宝抗拒吃药怎么办 六个月宝宝不爱吃辅食怎么办 宝宝九个月了不爱吃辅食怎么办 八个月宝宝不喜欢吃辅食怎么办 小孩米粉吃多了怎么办 宝宝四个月了奶水不足怎么办 4个月奶水不足怎么办 孩子不吃奶粉母乳又不够怎么办 宝宝吃母乳上火了怎么办 5个月宝宝厌奶期怎么办