求问如何能做出这样的PWM波形,试了好多方法。

2019-10-14 21:58发布

用PWM比较输出模式的话,虽然可以调相位差,但是,占空比却不能调。
如果用PWM输出模式的话,可以调占空比,但是相位差却不能调。
请问各位大神,这四路波形要怎么调出来啊。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
26条回答
K.O.Carnivist
1楼-- · 2019-10-15 03:42
本帖最后由 K.O.Carnivist 于 2016-10-6 11:50 编辑

楼主需要的波形是4个通道严格首位相接吗?

如果是的话,同时有癖不愿意用中断,可以试试这样:

用一个高级定时器做带有 Repetition Counter 的 One-Pulse,每次启动时发生6次更新。
周期是输出通道上一个脉冲的时间。
4个输出通道都配置成 Toggle,CCR 设成1。
开启任意一个通道的比较事件 DMA(任意通道,看哪个 DMA 通道空闲就好),循环写定时器的 CCER,需要哪个通道输出脉冲时把它使能。
把这个定时器做成 Slave - Trigger Mode,另外找一个定时器做 Master - Update,周期是四个脉冲的总周期。

优点是确实不用中断,通道之间波形严格相接。缺点是资源使用还是比较多的(2个定时器,1个DMA通道),而且输出波形哦定时器受限(需要高级定时器)。

需要改脉冲时间的话,改高级定时器的 ARR。
如果需要4个通道脉冲时间不一样,就再开任意一个通道的 DMA,循环写 ARR。

4-Step.png

[mw_shl_code=cpp,true]
   GPIO_InitTypeDef            GPIO_InitStructure;
    DMA_InitTypeDef             DMA_InitStructure;
    TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;
    TIM_OCInitTypeDef           TIM_OCInitStructure;
   
    uint16_t CCER_Buffer[6] = {0x0203,
                               0x0213,
                               0x0312,
                               0x1302,
                               0x1202,
                               0x0202};
   
    SystemCoreClockConfigure();                              // configure HSI as System Clock
    SystemCoreClockUpdate();

    SysTick_Config(SystemCoreClock / 1000);                  // SysTick 1 msec interrupts
   
    /* Clock Configuration --------------------------------------------------*/
    /* DMA1 clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
   
    /* TIM1 and GPIOA clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
   
    /* TIM2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    /* GPIO Configuration ---------------------------------------------------*/
    /* TIM1 channels as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    /* DMA Configuration ----------------------------------------------------*/
    /* DMA1 Channel2 Config */
    DMA_DeInit(DMA1_Channel2);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x40012C20;   /* TIM1_CCER */
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)CCER_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 6;
    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_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

    DMA_Init(DMA1_Channel2, &DMA_InitStructure);

    /* DMA1 Channel2 enable */
    DMA_Cmd(DMA1_Channel2, ENABLE);

    /* TIM1 Peripheral Configuration ----------------------------------------*/
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 2400;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 5;

    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    /* Channels Configuration in Toggle mode */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OCInitStructure.TIM_Pulse = 1;

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);

    /* Main Output Enable */
    TIM_CtrlPWMOutputs(TIM1, ENABLE);

    /* One Pulse Mode selection */
    TIM_SelectOnePulseMode(TIM1, TIM_OPMode_Single);
   
    /* Slave Mode selection: Trigger Mode */
    TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Trigger);
    TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1);
   
    /* TIM1 Channel1 DMA Request enable */
    TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE);

    /* TIM2 Peripheral Configuration ----------------------------------------*/
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Period = 48000;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    /* Master Mode selection */
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

    /* Select the Master Slave Mode */
    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

    /* TIM2 counter enable */
    TIM_Cmd(TIM2, ENABLE);
[/mw_shl_code]

正点原子
2楼-- · 2019-10-15 04:24
输出比较模式,可以调占空比的,不过要频繁中断,你的信号频率要求不高的话,可以用
vention
3楼-- · 2019-10-15 07:47
 精彩回答 2  元偷偷看……
vention
4楼-- · 2019-10-15 13:33
正点原子 发表于 2016-9-30 23:35
输出比较模式,可以调占空比的,不过要频繁中断,你的信号频率要求不高的话,可以用

频发中断……  可是我程序又有其他主要事情要处理,不是只单独输出这样的波形……不知道影响大不大
f1174562
5楼-- · 2019-10-15 18:28
用模拟的方法,不用PWM模式。设立一个定时器,定时触发中断,在中断程序中手动开关四次即可。
正点原子
6楼-- · 2019-10-15 19:53
vention 发表于 2016-10-1 09:18

完全可以用输出比较模式

一周热门 更多>