搜索
bottom↓
回复: 6

请教stm32f103的DMA通道问题

[复制链接]

出200入0汤圆

发表于 2022-7-22 04:09:50 | 显示全部楼层 |阅读模式
100汤圆
本帖最后由 zjr0411 于 2022-7-22 04:11 编辑

在一个大神逆变器的程序里DMA的通道使用不怎么了解,请懂的帮我解答一下:大神的逆变器帖子在这:https://www.amobbs.com/thread-5545884-1-1.html


1、程序使用tim1的通道1和2输出带死区的pwm驱动H桥做逆变功能,

既然使用了tim1的通道1和2,那芯片手册上写的tim1的通道1和2分别对应了DMA1的2和3通道呀,结果程序里使用了DMA1的通道5,他的通道5是用了手册上写的哪个功能呢?手册如下图:

2、下面程序里#define TIM1_DMAR_Address    0x40012C4C里这个地址是怎么得出的呢?程序如下:
只上传了这个单独文件和函数,要整个工程的请到原帖下载。

#define TIM1_DMAR_Address    0x40012C4C
void Time1Config(void)
{
        
//        INT32U j=0,K=(u32)&dmabuff;
        
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
        DMA_InitTypeDef DMA_InitStructure;
  TIM_BDTRInitTypeDef TIM_BDTR_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB2PeriphClockCmd(  RCC_APB2Periph_TIM1|RCC_APB2Periph_AFIO,ENABLE);
  RCC_APB2PeriphClockCmd(  RCC_APB2Periph_GPIOB,ENABLE);
  
        //GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);


        
  TIM_DeInit(TIM1);
        TIM_TimeBaseStructure.TIM_Period = Fsys / Fpwm;                //重装载寄存器周期的值
  TIM_TimeBaseStructure.TIM_Prescaler = 0;                                                        //TIMx时钟频率除数的预分频值
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM中央对齐模式1计数模式
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                //时钟分割
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                //
  TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
  
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  TIM_OCInitStructure.TIM_Pulse = ((Fsys / Fpwm) * 50) / 100;
  TIM_OC1Init(TIM1,&TIM_OCInitStructure);
        
        
        
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  TIM_OCInitStructure.TIM_Pulse = ((Fsys / Fpwm) * 50) / 100;
  TIM_OC2Init(TIM1,&TIM_OCInitStructure);
        


TIM_BDTR_InitStructure.TIM_OSSRState = TIM_OSSRState_Disable;
TIM_BDTR_InitStructure.TIM_OSSIState = TIM_OSSIState_Disable;
TIM_BDTR_InitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTR_InitStructure.TIM_DeadTime = 0x15;
TIM_BDTR_InitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTR_InitStructure.TIM_BreakPolarity =TIM_BreakPolarity_High;

  TIM_BDTRConfig(TIM1,&TIM_BDTR_InitStructure);

  TIM_ARRPreloadConfig(TIM1, ENABLE);//ARR预装载缓冲器
  TIM_CtrlPWMOutputs(TIM1, ENABLE);        
        TIM_Cmd(TIM1,ENABLE);        

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);        
        
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12;                //SD
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
        
        GPIO_ResetBits(GPIOB,GPIO_Pin_12);//置低        
        
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

        TIM_DMAConfig(TIM1, TIM_DMABase_CCR2, TIM_DMABurstLength_1Byte );  
        TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);

        DMA_DeInit(DMA1_Channel5);        //初始化DMA1 第五通道
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(TIM1_DMAR_Address) ;
  DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)dmabuff;        
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                                                //外设作为目的地
  DMA_InitStructure.DMA_BufferSize = 250;
  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_InitStructure.DMA_Mode = DMA_Mode_Circular;                                                                                //工作模式 DMA_Mode_Normal;//
  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);


  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;                                                                         //DMA通道1中断允许
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
        DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);        //开传输完成中断
}
附件: 您需要 登录 才可以下载或查看,没有帐号?注册

最佳答案

查看完整内容

见这一行: 代码使能的DMA请求是TIM1_UP,所以对应的CH5。

出15入178汤圆

发表于 2022-7-22 04:09:51 | 显示全部楼层
见这一行:
  1. TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);
复制代码


代码使能的DMA请求是TIM1_UP,所以对应的CH5。

出200入0汤圆

 楼主| 发表于 2022-7-22 16:21:16 | 显示全部楼层
2nd 发表于 2022-7-22 10:48
见这一行:


(引用自2楼)

谢谢,那这个地址0x40012C4C是怎么算出来的呢?
#define TIM1_DMAR_Address    0x40012C4C
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(TIM1_DMAR_Address) ;

出20入186汤圆

发表于 2022-7-22 19:55:04 | 显示全部楼层
DMA的传送地址,可能是直接在MDK调试界面中,选中外设寄存器,下边有寄存器地址

出200入0汤圆

 楼主| 发表于 2022-7-22 23:11:40 | 显示全部楼层
yuyu87 发表于 2022-7-22 19:55
DMA的传送地址,可能是直接在MDK调试界面中,选中外设寄存器,下边有寄存器地址 ...
(引用自4楼)

TIM1->DMAR是不是这个呢,我按地址0x40012C4C找程序里面的寄存器计算得到的是这个。

出105入79汤圆

发表于 2022-7-22 23:25:46 | 显示全部楼层
注释不完整 ,代码可维护性低,一般配置代码要写清楚配置的思路和关键点

出200入0汤圆

 楼主| 发表于 2022-7-22 23:35:35 | 显示全部楼层
qwe2231695 发表于 2022-7-22 23:25
注释不完整 ,代码可维护性低,一般配置代码要写清楚配置的思路和关键点
(引用自6楼)

这是别人的程序,就是不懂才要来问。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 11:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表