STM32H7的DMA双缓冲控制IO输出脉冲

STM32H7的DMA双缓冲控制IO输出脉冲

  • keil的sct文件配置
  • MPU配置
  • 初始化DMA双缓冲
  • 初始化TIM12用处触发DMAMUX的请求发生器

keil的sct文件配置

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00200000  {    ; load region size_regionER_IROM1 0x08000000 0x00200000  {  ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO)}RW_IRAM1 0x20000000 0x00020000  {  ; RW data - 128KB DTCM.ANY (+RW +ZI)}RW_IRAM2 0x24000000 0x00080000  {  ; RW data - 512KB AXI SRAM*(.RAM_D1) }RW_IRAM3 0x30000000 0x00048000  {  ; RW data - 128KB SRAM1(0x30000000) + 128KB SRAM2(0x3002 0000) + 32KB SRAM3(0x30040000)*(.RAM_D2)}RW_IRAM4 0x38000000 0x00010000  {  ; RW data - 64KB SRAM4(0x38000000)*(.RAM_D3)}
}

MPU配置

/* 配置 SRAM4 的属性为 Write through, read allocate,no write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x38000000;
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);

初始化DMA双缓冲

在这里插入图片描述

/*初始化变量*/
#elif defined ( __CC_ARM )
ALIGN_32BYTES(__attribute__((section (".RAM_D3"))) uint32_t IO_Toggle[8]) ={ 0x00000002U, 0x00020000U, 0x00000002U, 0x00020000U, 0x00000002U, 0x00020000U, 0x00000002U, 0x00020000U, };
ALIGN_32BYTES(__attribute__((section (".RAM_D3"))) uint32_t IO_Toggle1[8]) ={ 0x00000002U, 0x00020000U, 0x00000002U, 0x00020000U, 0x00000002U, 0x00020000U, 0x00000002U, 0x00020000U, };
#endif
void bsp_InitTimDMA(void)
{GPIO_InitTypeDef  GPIO_InitStruct;DMA_HandleTypeDef DMA_Handle = {0};HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams = {0};/*##-1- 配置PB1用于PWM输出 ##################################################*/__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/*##-2- 使能DMA1时钟并配置 ##################################################*/__HAL_RCC_DMA1_CLK_ENABLE();DMA_Handle.Instance                 = DMA1_Stream1;            /* 使用的DMA1 Stream1 */DMA_Handle.Init.Request             = DMA_REQUEST_GENERATOR0;  /* 请求类型采用的DMAMUX请求发生器通道0 */  DMA_Handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;    /* 传输方向是从存储器到外设 */  DMA_Handle.Init.PeriphInc           = DMA_PINC_DISABLE;        /* 外设地址自增禁止 */ DMA_Handle.Init.MemInc              = DMA_MINC_ENABLE;         /* 存储器地址自增使能 */  DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;     /* 外设数据传输位宽选择字,即32bit */     DMA_Handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;     /* 存储器数据传输位宽选择字,即32bit */    DMA_Handle.Init.Mode                = DMA_CIRCULAR;            /* 循环模式 */   DMA_Handle.Init.Priority            = DMA_PRIORITY_LOW;        /* 优先级低 */  DMA_Handle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;    /* 禁止FIFO*/DMA_Handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL; /* 禁止FIFO此位不起作用,用于设置阀值 */DMA_Handle.Init.MemBurst            = DMA_MBURST_SINGLE;       /* 禁止FIFO此位不起作用,用于存储器突发 */DMA_Handle.Init.PeriphBurst         = DMA_PBURST_SINGLE;       /* 禁止FIFO此位不起作用,用于外设突发 *//* 初始化DMA */if(HAL_DMA_Init(&DMA_Handle) != HAL_OK){Error_Handler(__FILE__, __LINE__);     }/* 开启DMA1 Stream1的中断 */HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 2, 0);HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn); /*##-4- 配置DMAMUX ###########################################################*/dmamux_ReqGenParams.SignalID  = HAL_DMAMUX1_REQ_GEN_TIM12_TRGO;         /* 请求触发器选择LPTIM2_OUT */dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_RISING;              /* 上升沿触发  */dmamux_ReqGenParams.RequestNumber = 1;                                  /* 触发后,传输进行1次DMA传输 */HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle, &dmamux_ReqGenParams); /* 配置DMAMUX */HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handle);                      /* 使能DMAMUX请求发生器 */   /*##-4- 启动DMA双缓冲传输 ################################################*//*1、此函数会开启DMA的TC,TE和DME中断2、如果用户配置了回调函数DMA_Handle.XferHalfCpltCallback,那么函数HAL_DMA_Init会开启半传输完成中断。3、如果用户使用了DMAMUX的同步模式,此函数会开启同步溢出中断。4、如果用户使用了DMAMUX的请求发生器,此函数会开始请求发生器溢出中断。*/HAL_DMAEx_MultiBufferStart_IT(&DMA_Handle, (uint32_t)IO_Toggle, (uint32_t)&GPIOB->BSRRL,(uint32_t)IO_Toggle1, 8);/* 用不到的中断可以直接关闭 *///DMA1_Stream1->CR &= ~DMA_IT_DME; //DMA1_Stream1->CR &= ~DMA_IT_TE;//DMAMUX1_RequestGenerator0->RGCR &= ~DMAMUX_RGxCR_OIE;TIM12_Config(0);
}

初始化TIM12用处触发DMAMUX的请求发生器

/*
*********************************************************************************************************
*	函 数 名: TIM12_Config
*	功能说明: 配置TIM12,用于触发DMAMUX的请求发生器
*	形    参: _Mode 
*             0 表示配置为100KHz触发频率,配置为100KHz触发频率,如果DMAMUX配置为单边沿触发,那么输出PWM频
*               率是50KHz,双边沿是100KHz。
*			  1 表示配置为10KHz触发频率,如果DMAMUX配置为单边沿触发,那么输出PWM频率是5KHz,双边沿是10KHz。									  
*	返 回 值: 无
*********************************************************************************************************
*/
void TIM12_Config(uint8_t _Mode)
{TIM_HandleTypeDef  htim ={0};TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfig = {0};uint32_t Period[2] = {1999, 19999};uint32_t Pulse[2]  = {999, 9999};/* 使能时钟 */  __HAL_RCC_TIM12_CLK_ENABLE();/*-----------------------------------------------------------------------bsp.c 文件中 void SystemClock_Config(void) 函数对时钟的配置如下: System Clock source       = PLL (HSE)SYSCLK(Hz)                = 400000000 (CPU Clock)HCLK(Hz)                  = 200000000 (AXI and AHBs Clock)AHB Prescaler             = 2D1 APB3 Prescaler         = 2 (APB3 Clock  100MHz)D2 APB1 Prescaler         = 2 (APB1 Clock  100MHz)D2 APB2 Prescaler         = 2 (APB2 Clock  100MHz)D3 APB4 Prescaler         = 2 (APB4 Clock  100MHz)因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = APB1 x 2 = 200MHz;因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = APB2 x 2 = 200MHz;APB4上面的TIMxCLK没有分频,所以就是100MHz;APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14,LPTIM1APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17APB4 定时器有 LPTIM2,LPTIM3,LPTIM4,LPTIM5TIM12CLK = 200MHz/(Period + 1) / (Prescaler + 1)函数bsp_InitTimDMA1中DMAMUX1选择的是单边沿触发,每个时钟可以触发两次。----------------------------------------------------------------------- */  HAL_TIM_Base_DeInit(&htim);htim.Instance = TIM12;htim.Init.Period            = Period[_Mode];htim.Init.Prescaler         = 0;htim.Init.ClockDivision     = 0;htim.Init.CounterMode       = TIM_COUNTERMODE_UP;htim.Init.RepetitionCounter = 0;HAL_TIM_Base_Init(&htim);sConfig.OCMode     = TIM_OCMODE_PWM1;sConfig.OCPolarity = TIM_OCPOLARITY_LOW;/* 占空比50% */sConfig.Pulse = Pulse[_Mode];  if(HAL_TIM_OC_ConfigChannel(&htim, &sConfig, TIM_CHANNEL_1) != HAL_OK){Error_Handler(__FILE__, __LINE__);}/* 启动OC1 */if(HAL_TIM_OC_Start(&htim, TIM_CHANNEL_1) != HAL_OK){Error_Handler(__FILE__, __LINE__);}/* TIM12的TRGO用于触发DMAMUX的请求发生器 */sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/619841.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOV5检测界面搭建+bug解决

目录 一、环境搭建 二、界面运行bug解决 三、界面 先给出Github链接:https://github.com/Javacr/PyQt5-YOLOv5 大佬链接:大佬 一、环境搭建 下载完项目后,需要配置环境: conda create -n yolov5_pyqt5 python3.8 conda act…

milvus各组件的结构体分析

milvus各组件的结构体分析 各组件启动,需要构建各组件的结构体,一共8个。 runComponent(ctx, localMsg, wg, components.NewRootCoord, metrics.RegisterRootCoord) runComponent(ctx, localMsg, wg, components.NewProxy, metrics.RegisterProxy) run…

html--烟花3

html <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Canvas烟花粒子</title> <meta name"keywords" content"canvas烟花"/> <meta name"description" content"can…

亚马逊卖家如何选择合适的海外仓系统,如何利用海外仓系统进行退货换标?

在亚马逊的全球电商舞台上&#xff0c;如何选择一个合适的海外仓系统&#xff0c;高效管理海外仓库、优化退货换标流程&#xff0c;成为了卖家们亟待解决的问题。 今天&#xff0c;让我们就来聊聊怎么挑选海外仓系统&#xff0c;还有怎么利用它来处理退货换标的。 一、选择海外…

web3项目自动连接小狐狸以及小狐狸中的各种“地址”详解

刚做web3的时候&#xff0c;比较迷糊的就是人们口中说的各种地址&#xff0c;小狐狸钱包地址&#xff0c;私钥地址&#xff0c;跳转地址&#xff0c;接口地址&#xff0c;交易地址&#xff0c;等等XX地址&#xff0c;常常感觉跟做链的同事们说话不在一个频道。 这一小节&#x…

Java开发从入门到精通(十一):Java常用的API编程接口:ArrayList集合

Java大数据开发和安全开发 &#xff08;一&#xff09;Java的常用API:ArrayList集合1.1 什么是集合?1.2 有数组&#xff0c;为啥还学习集合?1.3 ArrayList集合该怎么学呢?1.3.1 创建ArrayList对象1.3.ArrayList的增删改查操作1.3.3 ArrayList集合的案例 &#xff08;一&…

波纹加载---

代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style…

【C语言】指针篇-初识指针(1/5)

&#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;C笔记专栏&#xff1a; C笔记 &#x1f308;喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 **内存和地址(知识铺垫(了解即可))**如何理解编址**指针变量*…

【unity】【C#】游戏音乐播放和发布

今天我们来认识一下有关 unity 音乐的一些知识 我们先创建 AudioClips 文件夹&#xff0c;这个文件夹通常就是 unity 中存放音乐的文件夹&#xff0c;然后拖进音乐文件进去 这里为大家提供了两个音乐&#xff0c;有需要可以自取 百度网盘&#xff1a;https://pan.baidu.com/s…

泛域名/通配符SSL证书有免费的吗?怎么申请?

我们需要明确的是&#xff0c;市场上确实存在免费的泛域名SSL证书&#xff0c;但这些免费证书通常由自动化的证书颁发机构&#xff08;CA&#xff09;提供&#xff0c;如JoySSL、Lets Encrypt。这些免费证书虽然能够满足基本的加密需求&#xff0c;但在服务支持、保险额度、信任…

Python7种运算符及运算符优先级

🥇作者简介:CSDN内容合伙人、新星计划第三季Python赛道Top1 🔥本文已收录于Python系列专栏: 零基础学Python 💬订阅专栏后可私信博主进入Python学习交流群,进群可领取Python视频教程以及Python相关电子书合集 私信未回可以加V:hacker0327 备注零基础学Python 订阅专…

Rust - 所有权

所有的程序都必须和计算机内存打交道&#xff0c;如何从内存中申请空间来存放程序的运行内容&#xff0c;如何在不需要的时候释放这些空间&#xff0c;成了重中之重&#xff0c;也是所有编程语言设计的难点之一。在计算机语言不断演变过程中&#xff0c;出现了三种流派&#xf…