OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6105|回复: 4

定时器1的通道3互补输出SPWM问题

[复制链接]

2

主题

10

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2018-7-10
在线时间
38 小时
发表于 2021-6-2 00:20:29 | 显示全部楼层 |阅读模式
50金钱

各位大佬好,我参考网友@nashui_sx的代码,设置定时器1 通道3输出SPWM波形,现已实现通道1输出了互补的波形,
现按照如下通道设置DMA通道6,TIM1_CH3通道3输出SPWM,但是如下代码只能输出互补的方波,没有可变PWM,定时器与DMA都对应手册设置,感觉DMA设置有问题,但又不知道问题在那,恳请各位解惑,谢谢!

备注:如下代码更改位DMA通道2,设置定时器为通道1,不用改为其他代码,即可在A8/B13输出互补的SPWM


u16 TIM1_Spwm_Buf[TIM1_Spwm_Buf_Size];  //发送数据缓冲区 ,控制占空比

void TIM1_Spwm_Creat_Buf(void)
{
    u32 i;
    float inc=2*PI/TIM1_Spwm_Buf_Size;        //计算增量

    for(i=0;i<TIM1_Spwm_Buf_Size;i++)
    {
        TIM1_Spwm_Buf=(u16)(TIM1_Spwm_Buf_Zhouqi/2*(1+sin(inc*i))+0.5);    //得到一个0-TIM1_Spwm_Buf_Zhouqi的正弦波控制spwm  +0.5是为了最大值能够达到TIM1_Spwm_Buf_Zhouqi 最小能到0
    }  
}
void TIM1_Spwm_Init(void)
{  
        GPIO_InitTypeDef         GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef                            TIM_OCInitStructure;                        //输出通道配置
        TIM_BDTRInitTypeDef                   TIM_BDTRInitStructure;                //死区和刹车配置
  DMA_InitTypeDef          DMA_InitStructure;
  NVIC_InitTypeDef         NVIC_InitStructure;
  TIM1_Spwm_Creat_Buf();
       

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //使能定时器3时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);        //使能定时器1时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
       
//        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
//        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_Init(GPIOA, &GPIO_InitStructure);
//  //初始化TIM1
//        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;  
//        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_10;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
  //初始化TIM1
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE);

        TIM_TimeBaseStructure.TIM_Period = TIM1_Spwm_Buf_Zhouqi-1;                        //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =35;                      //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision =0;                 //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);      

        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //输出极性:TIM输出比较极性高
        TIM_OC3Init(TIM1, &TIM_OCInitStructure);                     //初始化通道3
        TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);            //使能TIM1在通道3上的预装载寄存器
       
        /*TIM1高级定时器互补通道输出配置*/
        TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;         //PWM互补输出使能
        TIM_OCInitStructure.TIM_OCNPolarity  = TIM_OCNPolarity_High;           //互补PWM极性
        TIM_OCInitStructure.TIM_OCIdleState  = TIM_OCIdleState_Set;                   //输出空闲状态
        TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;          //PWM互补输出空闲状态
        TIM_OC3Init(TIM1, &TIM_OCInitStructure);                                //根据指定的参数初始化外设TIM1 OC3


        /*死区和刹车功能配置*/
        TIM_BDTRInitStructure.TIM_OSSRState       = TIM_OSSRState_Enable;
        TIM_BDTRInitStructure.TIM_OSSIState       = TIM_OSSIState_Enable;
        TIM_BDTRInitStructure.TIM_LOCKLevel       = TIM_LOCKLevel_1;
        TIM_BDTRInitStructure.TIM_DeadTime        = 0x1F;                //设置TIM1_BDTR的DTG[7:0]
        TIM_BDTRInitStructure.TIM_Break           = TIM_Break_Disable;
        TIM_BDTRInitStructure.TIM_BreakPolarity   = TIM_BreakPolarity_High;
        TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
        TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
       
        /*DMA功能配置*/
        DMA_DeInit(DMA1_Channel6);                                                 //将DMA的通道1寄存器重设为缺省值
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&TIM1->CCR1;               //DMA外设基地址   问题在这里
        DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)&TIM1_Spwm_Buf;              //DMA内存基地址
        DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;          //DMA_DIR_PeripheralSRC:从外设读  DMA_DIR_PeripheralDST:从内存读
        DMA_InitStructure.DMA_BufferSize         = TIM1_Spwm_Buf_Size;                              //DMA通道的DMA缓存的大小,实测不加1少一个,应该是最后一个还没输出就中断关闭定时器了,+1就好了
        DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;      //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;      //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;    //数据宽度为8位
        DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;                //工作在正常模式
        DMA_InitStructure.DMA_Priority           = DMA_Priority_Medium;            //DMA通道 x拥有中优先级
        DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;                //是否开启内存到内存传输(关闭表示只有事件产生才传输一次数据,开启表示一直传输)DMA_M2M_Disable:非存储器到存储器模式(关闭内存到内存模式)  DMA_M2M_Enable:启动存储器到存储器模式(开启内存到内存模式)
        DMA_Init(DMA1_Channel6, &DMA_InitStructure);                               //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器                 
        DMA_Cmd(DMA1_Channel6,ENABLE);                                           //DMA使能
        TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE);          //定时器TIM_DMA_CC1 TIM_DMA_Update使能       
//        TIM_DMACmd(TIM1, TIM_DMA_Update,ENABLE);

        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;   
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;      
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);               
        DMA_ClearFlag(DMA1_Channel6_IRQn);                                         //清除DMA所有标志

        DMA_ITConfig(DMA1_Channel6,DMA_IT_TC,ENABLE);                              //开传输完成中断
        TIM_SetCompare3(TIM1,TIM1_Spwm_Buf[0]);       //通道1
        TIM_CtrlPWMOutputs(TIM1, ENABLE);
        TIM_Cmd(TIM1, ENABLE);         //使能TIM1
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2018-7-10
在线时间
38 小时
 楼主| 发表于 2021-6-2 13:51:31 来自手机 | 显示全部楼层
回复

使用道具 举报

4

主题

456

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1072
金钱
1072
注册时间
2021-4-26
在线时间
352 小时
发表于 2021-6-2 18:49:26 | 显示全部楼层
帮顶  
回复

使用道具 举报

0

主题

17

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2018-9-9
在线时间
3 小时
发表于 2021-6-3 11:51:17 | 显示全部楼层

帮顶,正好也需要
回复

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2018-7-10
在线时间
38 小时
 楼主| 发表于 2021-6-3 11:55:29 来自手机 | 显示全部楼层
顶顶顶
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-23 02:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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