CH32V307 定时器的单脉冲输出问题求教

各位专家您好,我在使用CH32V307的时候希望通过软件触发输出单脉冲信号,我的意思先初始化单脉冲,然后每隔一毫秒在PWM1,PWM2,PWM3,PWM4,输出一个脉冲信号,现在无法输出脉冲信号,烦请各位老师百忙之中指导,看看问题在哪哈。

我是用的TIMER1,然后需要IO口重定向到 PE14,PE13,PE11,PE9上面,

我的程序如下:

准备通过软件触发,网上说的是软件触发只需要再次使能Timer1即可。

   

//初始化TIMER1单脉冲信号输出
void stepper_one_pulse_init(uint16_t PolarityPins)
{
    const uint16_t arr=0xffff;
    const uint16_t ccp=0xffff;
    GPIO_InitTypeDef GPIO_InitStructure={0};
    TIM_OCInitTypeDef TIM_OCInitStructure={0};
    TIM_ICInitTypeDef TIM_ICInitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE );
    RCC_APB1PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_11|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOE, &GPIO_InitStructure );
    //重定向TIMER1
    AFIO->PCFR1|=(0x3<<6);
    
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    //TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    //设置时钟为8M,TIMER_COUNTER_FREQ=8000000
    TIM_TimeBaseInitStructure.TIM_Prescaler =
                (int) (((((float) SystemCoreClock) / TIMER_COUNTER_FREQ)) + 0.5f)
                        - 1;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
    TIM_ARRPreloadConfig(TIM1, DISABLE);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = ccp;
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x08) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x04) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x02) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x01) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);
    TIM_SelectOnePulseMode( TIM1,TIM_OPMode_Single);

}

//触发一个单脉冲
void stepper_one_pulse_start(uint16_t arr)
{
    TIM_Cmd(TIM1, DISABLE);
    TIM1->CNT=0;
    TIM1->ATRLR=(arr<<1)+(arr<<2);
    TIM1->CH1CVR=TIM1->ATRLR>>1;
    TIM1->CH2CVR=TIM1->ATRLR>>1;
    TIM1->CH3CVR=TIM1->ATRLR>>1;
    TIM1->CH4CVR=TIM1->ATRLR>>1;
    TIM_Cmd(TIM1, ENABLE);
}

OneTimeTest()
{
  //4路初始化默认低电平
  stepper_one_pulse_init(0x0000);
  while(1)
  {
     //延时1ms
     Delay(1);
     //4路PWM全部输出一个脉冲脉冲
     stepper_one_pulse_start(1000);
  }
}


你的AFIO时钟似乎没开


谢谢老师回复,我现在把初始化函数修改为如下:增加了AFIO的时钟使能,但是还是没有看到IO口的变化,由于我手头没有调试器,我也不知道是TIMER没有跑起来还是PWM没有成功,能否继续指导下哈。非常感谢。

void stepper_one_pulse_init(uint16_t PolarityPins)
{
    const uint16_t arr=0xffff;
    const uint16_t ccp=0xffff;
    GPIO_InitTypeDef GPIO_InitStructure={0};
    TIM_OCInitTypeDef TIM_OCInitStructure={0};
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE, ENABLE );
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );
    //使能remap时钟
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE );

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_11|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( GPIOE, &GPIO_InitStructure );
    AFIO->PCFR1|=(0x3<<6);
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    //设置TIMER时钟为8M
    TIM_TimeBaseInitStructure.TIM_Prescaler =
                (int) (((((float) SystemCoreClock) / TIMER_COUNTER_FREQ)) + 0.5f)
                        - 1;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure);
    TIM_ARRPreloadConfig(TIM1, DISABLE);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = ccp;
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x08) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x04) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x02) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCPolarity = (PolarityPins&0x01) ? TIM_OCPolarity_High:TIM_OCPolarity_Low;
    TIM_OC4Init(TIM1, &TIM_OCInitStructure);
    TIM_SelectOnePulseMode( TIM1,TIM_OPMode_Single);

}



我又修改了下,初始化程序增加了失能影子寄存器,还是没有效果,请老师务必在百忙之中指导下哈,万分感谢。

void?stepper_one_pulse_init(uint16_t?PolarityPins)
{
????const?uint16_t?arr=0xffff;
????const?uint16_t?ccp=0xffff;
????GPIO_InitTypeDef?GPIO_InitStructure={0};
????TIM_OCInitTypeDef?TIM_OCInitStructure={0};
????TIM_TimeBaseInitTypeDef?TIM_TimeBaseInitStructure={0};

????RCC_APB2PeriphClockCmd(?RCC_APB2Periph_GPIOE,?ENABLE?);
????RCC_APB2PeriphClockCmd(?RCC_APB2Periph_TIM1,?ENABLE?);
????RCC_APB2PeriphClockCmd(?RCC_APB2Periph_AFIO,?ENABLE?);

????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_14|GPIO_Pin_13|GPIO_Pin_11|GPIO_Pin_9;
????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;
????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;
????GPIO_Init(?GPIOE,?&GPIO_InitStructure?);
????AFIO->PCFR1|=(0x3<<6);
????GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);
????TIM_TimeBaseInitStructure.TIM_Period?=?arr;
????//TIM_TimeBaseInitStructure.TIM_Prescaler?=?psc;
????TIM_TimeBaseInitStructure.TIM_Prescaler?=
????????????????(int)?(((((float)?SystemCoreClock)?/?TIMER_COUNTER_FREQ))?+?0.5f)
????????????????????????-?1;
????TIM_TimeBaseInitStructure.TIM_ClockDivision?=?TIM_CKD_DIV1;
????TIM_TimeBaseInitStructure.TIM_CounterMode?=?TIM_CounterMode_Up;
????TIM_TimeBaseInit(?TIM1,?&TIM_TimeBaseInitStructure);

????TIM_OCInitStructure.TIM_OCMode?=?TIM_OCMode_PWM1;
????TIM_OCInitStructure.TIM_OutputState?=?TIM_OutputState_Enable;
????TIM_OCInitStructure.TIM_Pulse?=?ccp;
????TIM_OCInitStructure.TIM_OCPolarity?=?(PolarityPins&0x08)???TIM_OCPolarity_High:TIM_OCPolarity_Low;
????TIM_OC1Init(TIM1,?&TIM_OCInitStructure);
????TIM_OCInitStructure.TIM_OCPolarity?=?(PolarityPins&0x04)???TIM_OCPolarity_High:TIM_OCPolarity_Low;
????TIM_OC2Init(TIM1,?&TIM_OCInitStructure);
????TIM_OCInitStructure.TIM_OCPolarity?=?(PolarityPins&0x02)???TIM_OCPolarity_High:TIM_OCPolarity_Low;
????TIM_OC3Init(TIM1,?&TIM_OCInitStructure);
????TIM_OCInitStructure.TIM_OCPolarity?=?(PolarityPins&0x01)???TIM_OCPolarity_High:TIM_OCPolarity_Low;
????TIM_OC4Init(TIM1,?&TIM_OCInitStructure);

????TIM_ARRPreloadConfig(TIM1,?DISABLE);
????TIM_OC1PreloadConfig(TIM1,?DISABLE);
????TIM_OC2PreloadConfig(TIM1,?DISABLE);
????TIM_OC3PreloadConfig(TIM1,?DISABLE);
????TIM_OC4PreloadConfig(TIM1,?DISABLE);
????TIM_SelectOnePulseMode(?TIM1,TIM_OPMode_Single);

}



您好,根据你的描述,若需要每隔1ms输出一个脉冲信号,感觉你可以直接配置使用PWM输出,低电平的脉宽直接设置为1ms即可,若需要脉冲方式,可以参考一下附件例程看一下。后续若有问题,可邮箱(lzs@wch.cn)沟通。

icon_rar.gifCH32V307 脉冲输出.zip



感谢回复,我需要的是任意时候,我输出一个脉冲只能是一个,而且周期也是可以变化的,目前只有单脉冲能满足我的需求。这个1ms我是为了方便老师理解和测试设计的,我实际上脉冲不是固定周期的,也不是固定宽度的


喏,调用一次OnePulse(var);就产生一个脉冲,参数是脉冲宽度,单位是1ms

icon_rar.gifOnePulse.zip



改脉宽时间直接改ccr就行,arr最好设置成ccr+1


老师您好, 我们硬件已经做好了,对应的是PE8-PE15相关的引脚,只能使用TIM1,且必须是remap相关的IO引脚,能否再指导下这个TIM2跟我的TIM1有啥区别呢, 我的TIM1就是按照这个修改的啊

另外,如下这几句话是通过通道2触发单脉冲,通道2的引脚此时作为输入;

我这里由于不需要通道2触发,且需要将通道2作为输出引脚也产生脉冲,我没有加上这几句话。

TIM_ICStructInit( &TIM_ICInitStructure );

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x00;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;



只有登录才能回复,可以选择微信账号登录